aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/src/dx/DxFabric.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'NvCloth/src/dx/DxFabric.cpp')
-rw-r--r--NvCloth/src/dx/DxFabric.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/NvCloth/src/dx/DxFabric.cpp b/NvCloth/src/dx/DxFabric.cpp
new file mode 100644
index 0000000..4952e80
--- /dev/null
+++ b/NvCloth/src/dx/DxFabric.cpp
@@ -0,0 +1,208 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "DxFabric.h"
+#include "DxContextLock.h"
+#include "DxFactory.h"
+#include <algorithm>
+#include <PsUtilities.h>
+
+#if NV_CLOTH_ENABLE_DX11
+
+using namespace physx;
+using namespace nv;
+
+cloth::DxFabric::DxFabric(DxFactory& factory, uint32_t numParticles, Range<const uint32_t> phaseIndices,
+ Range<const uint32_t> sets, Range<const float> restvalues, Range<const float> stiffnessValues, Range<const uint32_t> indices,
+ Range<const uint32_t> anchors, Range<const float> tetherLengths,
+ Range<const uint32_t> triangles, uint32_t id)
+: DxContextLock(factory)
+, mFactory(factory)
+, mNumParticles(numParticles)
+, mPhases(phaseIndices.begin(), phaseIndices.end())
+, mSets(sets.begin(), sets.end())
+, mConstraints(mFactory.mConstraints)
+, mConstraintsHostCopy(mFactory.mConstraintsHostCopy)
+, mStiffnessValues(mFactory.mStiffnessValues)
+, mTethers(mFactory.mTethers)
+, mId(id)
+{
+ // should no longer be prefixed with 0
+ NV_CLOTH_ASSERT(sets.front() != 0);
+
+ NV_CLOTH_ASSERT(sets.back() == restvalues.size());
+ NV_CLOTH_ASSERT(restvalues.size() * 2 == indices.size());
+ NV_CLOTH_ASSERT(restvalues.size() == stiffnessValues.size() || stiffnessValues.size() == 0);
+ NV_CLOTH_ASSERT(mNumParticles > *shdfnd::maxElement(indices.begin(), indices.end()));
+
+ // manually convert uint32_t indices to uint16_t in temp memory
+ Vector<DxConstraint>::Type hostConstraints;
+ hostConstraints.resizeUninitialized(restvalues.size());
+ Vector<DxConstraint>::Type::Iterator cIt = hostConstraints.begin();
+ Vector<DxConstraint>::Type::Iterator cEnd = hostConstraints.end();
+
+ const uint32_t* iIt = indices.begin();
+ const float* rIt = restvalues.begin();
+ for (; cIt != cEnd; ++cIt)
+ {
+ cIt->mRestvalue = *rIt++;
+ cIt->mFirstIndex = uint16_t(*iIt++);
+ cIt->mSecondIndex = uint16_t(*iIt++);
+ }
+
+ // copy to device vector in one go
+#if 0
+ // Workaround for NvAPI SCG device updateSubresource size limit
+ mConstraintsHostCopy.assign(hostConstraints.begin(), hostConstraints.end());
+ mConstraints.resize(mConstraintsHostCopy.size());
+ mConstraints = mConstraintsHostCopy;
+#else
+ mConstraints.assign(hostConstraints.begin(), hostConstraints.end());
+#endif
+
+ mStiffnessValues.assign(stiffnessValues.begin(), stiffnessValues.end());
+
+ // gather data per phase
+ mFirstConstraintInPhase.reserve(phaseIndices.size());
+ mNumConstraintsInPhase.reserve(phaseIndices.size());
+ for (const uint32_t* pIt = phaseIndices.begin(); pIt != phaseIndices.end(); ++pIt)
+ {
+ uint32_t setIndex = *pIt;
+ uint32_t firstIndex = setIndex ? sets[setIndex - 1] : 0;
+ uint32_t lastIndex = sets[setIndex];
+ mFirstConstraintInPhase.pushBack(firstIndex);
+ mNumConstraintsInPhase.pushBack(lastIndex - firstIndex);
+ }
+
+ // tethers
+ NV_CLOTH_ASSERT(anchors.size() == tetherLengths.size());
+ mTetherLengthScale =
+ tetherLengths.empty() ? 1.0f : *shdfnd::maxElement(tetherLengths.begin(), tetherLengths.end()) / USHRT_MAX;
+ float inverseScale = 1 / (mTetherLengthScale + FLT_EPSILON);
+ Vector<DxTether>::Type tethers;
+ tethers.reserve(anchors.size());
+ for (; !anchors.empty(); anchors.popFront(), tetherLengths.popFront())
+ {
+ tethers.pushBack(DxTether(uint16_t(anchors.front()), uint16_t(tetherLengths.front() * inverseScale + 0.5f)));
+ }
+ mTethers.assign(tethers.begin(), tethers.end());
+
+ // triangles
+ Vector<uint16_t>::Type hostTriangles;
+ hostTriangles.resizeUninitialized(triangles.size());
+ Vector<uint16_t>::Type::Iterator tIt = hostTriangles.begin();
+
+ for (; !triangles.empty(); triangles.popFront())
+ *tIt++ = uint16_t(triangles.front());
+
+ mTriangles.assign(hostTriangles.begin(), hostTriangles.end());
+
+ DxContextLock::release();
+
+ // add to factory
+ mFactory.mFabrics.pushBack(this);
+}
+
+cloth::DxFabric::~DxFabric()
+{
+ DxContextLock::acquire();
+
+ Vector<DxFabric*>::Type::Iterator fIt = mFactory.mFabrics.find(this);
+
+ NV_CLOTH_ASSERT(fIt != mFactory.mFabrics.end());
+ mFactory.mFabrics.replaceWithLast(fIt);
+}
+
+cloth::Factory& cloth::DxFabric::getFactory() const
+{
+ return mFactory;
+}
+
+uint32_t cloth::DxFabric::getNumPhases() const
+{
+ return uint32_t(mPhases.size());
+}
+
+uint32_t cloth::DxFabric::getNumRestvalues() const
+{
+ return uint32_t(mConstraints.size());
+}
+
+uint32_t cloth::DxFabric::getNumStiffnessValues() const
+{
+ return uint32_t(mStiffnessValues.size());
+}
+
+uint32_t cloth::DxFabric::getNumSets() const
+{
+ return uint32_t(mSets.size());
+}
+
+uint32_t cloth::DxFabric::getNumIndices() const
+{
+ return uint32_t(mConstraints.size()) * 2;
+}
+
+uint32_t cloth::DxFabric::getNumParticles() const
+{
+ return mNumParticles;
+}
+
+uint32_t cloth::DxFabric::getNumTethers() const
+{
+ return uint32_t(mTethers.size());
+}
+
+uint32_t cloth::DxFabric::getNumTriangles() const
+{
+ return uint32_t(mTriangles.size()) / 3;
+}
+
+void cloth::DxFabric::scaleRestvalues(float scale)
+{
+ DxContextLock contextLock(mFactory);
+
+ Vector<DxConstraint>::Type constraints(uint32_t(mConstraints.size()));
+ mFactory.copyToHost(constraints.begin(), mConstraints.buffer(), mConstraints.mOffset * sizeof(DxConstraint),
+ constraints.size() * sizeof(DxConstraint));
+
+ Vector<DxConstraint>::Type::Iterator cIt, cEnd = constraints.end();
+ for (cIt = constraints.begin(); cIt != cEnd; ++cIt)
+ cIt->mRestvalue *= scale;
+
+ mConstraints = constraints;
+}
+
+void cloth::DxFabric::scaleTetherLengths(float scale)
+{
+ // cloth instances won't pick this up until DxClothData is dirty!
+ mTetherLengthScale *= scale;
+}
+
+#endif // NV_CLOTH_ENABLE_DX11