diff options
Diffstat (limited to 'NvCloth/src')
| -rw-r--r-- | NvCloth/src/ClothBase.h | 1 | ||||
| -rw-r--r-- | NvCloth/src/ClothImpl.h | 26 | ||||
| -rw-r--r-- | NvCloth/src/IterationState.h | 4 | ||||
| -rw-r--r-- | NvCloth/src/SwClothData.cpp | 1 | ||||
| -rw-r--r-- | NvCloth/src/SwClothData.h | 1 | ||||
| -rw-r--r-- | NvCloth/src/SwSolverKernel.cpp | 25 | ||||
| -rw-r--r-- | NvCloth/src/cuda/CuClothData.cpp | 1 | ||||
| -rw-r--r-- | NvCloth/src/cuda/CuClothData.h | 1 | ||||
| -rw-r--r-- | NvCloth/src/cuda/CuSolverKernel.cu | 14 | ||||
| -rw-r--r-- | NvCloth/src/dx/DxClothData.cpp | 1 | ||||
| -rw-r--r-- | NvCloth/src/dx/DxClothData.h | 3 | ||||
| -rw-r--r-- | NvCloth/src/dx/DxSolverKernel.hlsl | 15 | ||||
| -rw-r--r-- | NvCloth/src/neon/SwCollisionHelpers.h | 4 | ||||
| -rw-r--r-- | NvCloth/src/scalar/SwCollisionHelpers.h | 4 |
14 files changed, 71 insertions, 30 deletions
diff --git a/NvCloth/src/ClothBase.h b/NvCloth/src/ClothBase.h index 8d75a72..ec1ee40 100644 --- a/NvCloth/src/ClothBase.h +++ b/NvCloth/src/ClothBase.h @@ -74,6 +74,7 @@ void initialize(Cloth& cloth, const physx::PxVec4* pIt, const physx::PxVec4* pEn cloth.mWind = physx::PxVec3(0.0f); cloth.mDragLogCoefficient = 0.0f; cloth.mLiftLogCoefficient = 0.0f; + cloth.mFluidDensity = 1.0f; cloth.mEnableContinuousCollision = false; cloth.mCollisionMassScale = 0.0f; cloth.mFriction = 0.0f; diff --git a/NvCloth/src/ClothImpl.h b/NvCloth/src/ClothImpl.h index 0c2b362..1e8d9a1 100644 --- a/NvCloth/src/ClothImpl.h +++ b/NvCloth/src/ClothImpl.h @@ -157,6 +157,8 @@ class ClothImpl : public Cloth virtual float getDragCoefficient() const; virtual void setLiftCoefficient(float); virtual float getLiftCoefficient() const; + virtual void setFluidDensity(float); + virtual float getFluidDensity() const; virtual void setSelfCollisionDistance(float); virtual float getSelfCollisionDistance() const; @@ -216,6 +218,7 @@ public: //Fields shared between all cloth classes physx::PxVec3 mWind; float mDragLogCoefficient; float mLiftLogCoefficient; + float mFluidDensity; // sleeping uint32_t mSleepTestInterval; // how often to test for movement @@ -313,7 +316,8 @@ inline physx::PxVec3 ClothImpl<T>::getGravity() const inline float safeLog2(float x) { - return x ? physx::shdfnd::log2(x) : -FLT_MAX_EXP; + NV_CLOTH_ASSERT(("safeLog2",x >= 0.0f)); + return x > 0 ? physx::shdfnd::log2(x) : -FLT_MAX_EXP; } inline physx::PxVec3 safeLog2(const physx::PxVec3& v) @@ -1214,11 +1218,30 @@ inline float ClothImpl<T>::getLiftCoefficient() const } template <typename T> +inline void ClothImpl<T>::setFluidDensity(float fluidDensity) +{ + NV_CLOTH_ASSERT(fluidDensity < 0.f); + if (fluidDensity == mFluidDensity) + return; + + mFluidDensity = fluidDensity; + getChildCloth()->notifyChanged(); + wakeUp(); +} + +template <typename T> +inline float ClothImpl<T>::getFluidDensity() const +{ + return mFluidDensity; +} + +template <typename T> inline uint32_t ClothImpl<T>::getNumSelfCollisionIndices() const { return uint32_t(getChildCloth()->mSelfCollisionIndices.size()); } + // Fixed 4505:local function has been removed template <typename T> inline void ClothImpl<T>::setRestPositions(Range<const physx::PxVec4> restPositions) @@ -1255,6 +1278,7 @@ inline float ClothImpl<T>::getSelfCollisionDistance() const template <typename T> inline void ClothImpl<T>::setSelfCollisionStiffness(float stiffness) { + NV_CLOTH_ASSERT(stiffness <= 1.0f); float value = safeLog2(1 - stiffness); if (value == getChildCloth()->mSelfCollisionLogStiffness) return; diff --git a/NvCloth/src/IterationState.h b/NvCloth/src/IterationState.h index f199663..224e87e 100644 --- a/NvCloth/src/IterationState.h +++ b/NvCloth/src/IterationState.h @@ -137,7 +137,7 @@ struct IterationState Simd4f mCurBias; // in local space Simd4f mPrevBias; // in local space - Simd4f mWind; // delta position per iteration + Simd4f mWind; // delta position per iteration (wind velocity * mIterDt) Simd4f mPrevMatrix[3]; Simd4f mCurMatrix[3]; @@ -290,7 +290,7 @@ cloth::IterationState<Simd4f> cloth::IterationStateFactory::create(MyCloth const result.mCurBias = transform(result.mRotationMatrix, curLinearInertia + bias) & maskXYZ; result.mPrevBias = transform(result.mRotationMatrix, linearInertia - curLinearInertia) & maskXYZ; - Simd4f wind = load(array(cloth.mWind)) * iterDt; + Simd4f wind = load(array(cloth.mWind)) * iterDt; // multiply with delta time here already so we don't have to do it inside the solver result.mWind = transform(result.mRotationMatrix, translation - wind) & maskXYZ; result.mIsTurning = mPrevAngularVelocity.magnitudeSquared() + cloth.mAngularVelocity.magnitudeSquared() > 0.0f; diff --git a/NvCloth/src/SwClothData.cpp b/NvCloth/src/SwClothData.cpp index eddd821..f102bde 100644 --- a/NvCloth/src/SwClothData.cpp +++ b/NvCloth/src/SwClothData.cpp @@ -80,6 +80,7 @@ cloth::SwClothData::SwClothData(SwCloth& cloth, const SwFabric& fabric) mNumTriangles = uint32_t(fabric.mTriangles.size()) / 3; mDragCoefficient = 1.0f - expf(stiffnessExponent * cloth.mDragLogCoefficient); mLiftCoefficient = 1.0f - expf(stiffnessExponent * cloth.mLiftLogCoefficient); + mFluidDensity = cloth.mFluidDensity * 0.5f; //divide by 2 to so we don't have to compensate for double area from cross product in the solver mStartMotionConstraints = cloth.mMotionConstraints.mStart.size() ? array(cloth.mMotionConstraints.mStart.front()) : 0; mTargetMotionConstraints = diff --git a/NvCloth/src/SwClothData.h b/NvCloth/src/SwClothData.h index d2387b5..78a6f99 100644 --- a/NvCloth/src/SwClothData.h +++ b/NvCloth/src/SwClothData.h @@ -92,6 +92,7 @@ struct SwClothData uint32_t mNumTriangles; float mDragCoefficient; float mLiftCoefficient; + float mFluidDensity; // motion constraint data const float* mStartMotionConstraints; diff --git a/NvCloth/src/SwSolverKernel.cpp b/NvCloth/src/SwSolverKernel.cpp index 52dfdaa..dec46d7 100644 --- a/NvCloth/src/SwSolverKernel.cpp +++ b/NvCloth/src/SwSolverKernel.cpp @@ -384,9 +384,13 @@ T4f calculateMaxDelta(const T4f* prevIt, const T4f* curIt, const T4f* curEnd) template <bool IsTurning, typename T4f> void applyWind(T4f* __restrict curIt, const T4f* __restrict prevIt, const uint16_t* __restrict tIt, - const uint16_t* __restrict tEnd, T4f dragCoefficient, T4f liftCoefficient, T4f wind, + const uint16_t* __restrict tEnd, float itrDtf, float dragCoefficientf, float liftCoefficientf, float fluidDensityf, T4f wind, const T4f (&rotation)[3]) { + const T4f dragCoefficient = simd4f(dragCoefficientf); + const T4f liftCoefficient = simd4f(liftCoefficientf); + const T4f fluidDensity = simd4f(fluidDensityf); + const T4f itrDt = simd4f(itrDtf); const T4f oneThird = simd4f(1.0f / 3.0f); for (; tIt < tEnd; tIt += 3) @@ -410,7 +414,7 @@ void applyWind(T4f* __restrict curIt, const T4f* __restrict prevIt, const uint16 T4f previous = oneThird * (p0 + p1 + p2); //offset of the triangle center, including wind - T4f delta = current - previous + wind; + T4f delta = current - previous + wind; //wind is also already multiplied by dt in the iteration state so everything it in the same units if (IsTurning) { @@ -423,23 +427,25 @@ void applyWind(T4f* __restrict curIt, const T4f* __restrict prevIt, const uint16 T4f normal = cross3(c2 - c0, c1 - c0); T4f doubleArea = sqrt(dot3(normal, normal)); + normal = normal / doubleArea; T4f invSqrScale = dot3(delta, delta); T4f isZero = invSqrScale < gSimd4fEpsilon; T4f scale = rsqrt(invSqrScale); + T4f deltaLength = sqrt(invSqrScale); //scale 'normalizes' delta, doubleArea normalized normal - T4f cosTheta = dot3(normal, delta) * scale / doubleArea; + T4f cosTheta = dot3(normal, delta) * scale; T4f sinTheta = sqrt(max(gSimd4fZero, gSimd4fOne - cosTheta * cosTheta)); // orthogonal to delta, in delta-normal plane, same length as delta T4f liftDir = cross3(cross3(delta, normal), delta * scale); // sin(theta) * cos(theta) = 0.5 * sin(2 * theta) - T4f lift = liftCoefficient * cosTheta * sinTheta * liftDir; - T4f drag = dragCoefficient * abs(cosTheta) * doubleArea * delta; //dragCoefficient should compensate for double area + T4f lift = liftCoefficient * cosTheta * sinTheta * liftDir * deltaLength / itrDt; + T4f drag = dragCoefficient * abs(cosTheta) * delta * deltaLength / itrDt; - T4f impulse = (lift + drag) & ~isZero; + T4f impulse = (drag + lift) * fluidDensity * doubleArea & ~isZero; //fluidDensity compensates for double area curIt[i0] = c0 - impulse * splat<3>(c0); curIt[i1] = c1 - impulse * splat<3>(c1); @@ -668,17 +674,14 @@ void cloth::SwSolverKernel<T4f>::applyWind() const uint16_t* tIt = mClothData.mTriangles; const uint16_t* tEnd = tIt + 3 * mClothData.mNumTriangles; - T4f dragCoefficient = simd4f(mClothData.mDragCoefficient); - T4f liftCoefficient = simd4f(mClothData.mLiftCoefficient); - if (mState.mIsTurning) { - ::applyWind<true>(curIt, prevIt, tIt, tEnd, dragCoefficient, liftCoefficient, mState.mWind, + ::applyWind<true>(curIt, prevIt, tIt, tEnd, mState.mIterDt, mClothData.mDragCoefficient, mClothData.mLiftCoefficient, mClothData.mFluidDensity, mState.mWind, mState.mRotationMatrix); } else { - ::applyWind<false>(curIt, prevIt, tIt, tEnd, dragCoefficient, liftCoefficient, mState.mWind, + ::applyWind<false>(curIt, prevIt, tIt, tEnd, mState.mIterDt, mClothData.mDragCoefficient, mClothData.mLiftCoefficient, mClothData.mFluidDensity, mState.mWind, mState.mRotationMatrix); } } diff --git a/NvCloth/src/cuda/CuClothData.cpp b/NvCloth/src/cuda/CuClothData.cpp index decfd2c..927997c 100644 --- a/NvCloth/src/cuda/CuClothData.cpp +++ b/NvCloth/src/cuda/CuClothData.cpp @@ -124,6 +124,7 @@ cloth::CuFrameData::CuFrameData(CuCloth& cloth, uint32_t numSharedPositions, con stiffness = gSimd4fOne - exp2(logStiffness * stiffnessExponent); mDragCoefficient = array(stiffness)[0]; mLiftCoefficient = array(stiffness)[1]; + mFluidDensity = cloth.mFluidDensity * 0.5f; //divide by 2 to so we don't have to compensate for double area from cross product in the solver for (int i = 0; i < 9; ++i) mRotation[i] = array(state.mRotationMatrix[i / 3])[i % 3]; diff --git a/NvCloth/src/cuda/CuClothData.h b/NvCloth/src/cuda/CuClothData.h index 0e4cda0..dd836fd 100644 --- a/NvCloth/src/cuda/CuClothData.h +++ b/NvCloth/src/cuda/CuClothData.h @@ -135,6 +135,7 @@ struct CuFrameData // wind data float mDragCoefficient; float mLiftCoefficient; + float mFluidDensity; float mRotation[9]; // motion constraint data diff --git a/NvCloth/src/cuda/CuSolverKernel.cu b/NvCloth/src/cuda/CuSolverKernel.cu index 3517193..edb66dc 100644 --- a/NvCloth/src/cuda/CuSolverKernel.cu +++ b/NvCloth/src/cuda/CuSolverKernel.cu @@ -867,6 +867,8 @@ __device__ void applyWind(CurrentT& current, PreviousT& previous) { const float dragCoefficient = gFrameData.mDragCoefficient; const float liftCoefficient = gFrameData.mLiftCoefficient; + const float fluidDensity = gFrameData.mFluidDensity; + const float itrDt = gFrameData.mIterDt; if (dragCoefficient == 0.0f && liftCoefficient == 0.0f) return; @@ -912,20 +914,22 @@ __device__ void applyWind(CurrentT& current, PreviousT& previous) float3 normal = cross3(c2 - c0, c1 - c0); - float doubleArea = sqrtf(dot3(normal, normal)); + const float doubleArea = sqrtf(dot3(normal, normal)); + normal = (1.0f / doubleArea) * normal; float invSqrScale = dot3(delta, delta); float scale = rsqrtf(invSqrScale); + float deltaLength = sqrtf(invSqrScale); - float cosTheta = dot3(normal, delta) * scale / doubleArea; + float cosTheta = dot3(normal, delta) * scale; float sinTheta = sqrtf(max(0.0f, 1.0f - cosTheta * cosTheta)); float3 liftDir = cross3(cross3(delta, normal), scale * delta); - float3 lift = liftCoefficient * cosTheta * sinTheta * liftDir; - float3 drag = dragCoefficient * abs(cosTheta) * doubleArea * delta; + float3 lift = liftCoefficient * cosTheta * sinTheta * ((deltaLength / itrDt) * liftDir); + float3 drag = dragCoefficient * abs(cosTheta) * ((deltaLength / itrDt) * delta); - float3 impulse = invSqrScale < FLT_EPSILON ? make_float3(0.0f, 0.0f, 0.0f) : lift + drag; + float3 impulse = invSqrScale < FLT_EPSILON ? make_float3(0.0f, 0.0f, 0.0f) : fluidDensity * doubleArea * (lift + drag); applyImpulse(current(i0), impulse); applyImpulse(current(i1), impulse); diff --git a/NvCloth/src/dx/DxClothData.cpp b/NvCloth/src/dx/DxClothData.cpp index 075dc81..57049bf 100644 --- a/NvCloth/src/dx/DxClothData.cpp +++ b/NvCloth/src/dx/DxClothData.cpp @@ -112,6 +112,7 @@ cloth::DxFrameData::DxFrameData(DxCloth& cloth, uint32_t numSharedPositions, con Simd4f stiffness = gSimd4fOne - exp2(logStiffness * stiffnessExponent); mDragCoefficient = array(stiffness)[0]; mLiftCoefficient = array(stiffness)[1]; + mFluidDensity = cloth.mFluidDensity * 0.5f; //divide by 2 to so we don't have to compensate for double area from cross product in the solver for(int i = 0; i < 9; ++i) mRotation[i] = array(state.mRotationMatrix[i / 3])[i % 3]; } diff --git a/NvCloth/src/dx/DxClothData.h b/NvCloth/src/dx/DxClothData.h index af02bc6..f91d37d 100644 --- a/NvCloth/src/dx/DxClothData.h +++ b/NvCloth/src/dx/DxClothData.h @@ -46,7 +46,7 @@ typedef unsigned int uint32_t; typedef int int32_t; #endif -static const uint32_t MaxParticlesInSharedMem = 1972; +static const uint32_t MaxParticlesInSharedMem = 1971; struct DxPhaseConfig @@ -167,6 +167,7 @@ struct DxFrameData // wind data float mDragCoefficient; float mLiftCoefficient; + float mFluidDensity; float mRotation[9]; // motion constraint data diff --git a/NvCloth/src/dx/DxSolverKernel.hlsl b/NvCloth/src/dx/DxSolverKernel.hlsl index 2ca42b3..4d91f4b 100644 --- a/NvCloth/src/dx/DxSolverKernel.hlsl +++ b/NvCloth/src/dx/DxSolverKernel.hlsl @@ -202,7 +202,8 @@ void applyWind(IParticles curParticles, IParticles prevParticles, uint32_t threa { const float dragCoefficient = gFrameData.mDragCoefficient; const float liftCoefficient = gFrameData.mLiftCoefficient; - + const float fluidDensity = gFrameData.mFluidDensity; + const float itrDt = gFrameData.mIterDt; if(dragCoefficient == 0.0f && liftCoefficient == 0.0f) return; @@ -258,20 +259,22 @@ void applyWind(IParticles curParticles, IParticles prevParticles, uint32_t threa float3 normal = cross(c2.xyz - c0.xyz, c1.xyz - c0.xyz); - float doubleArea = sqrt(dot(normal, normal)); + const float doubleArea = sqrt(dot(normal, normal)); + normal = normal / doubleArea; float invSqrScale = dot(delta, delta); float scale = rsqrt(invSqrScale); + float deltaLength = sqrt(invSqrScale); - float cosTheta = dot(normal, delta) * scale / doubleArea; + float cosTheta = dot(normal, delta) * scale; float sinTheta = sqrt(max(0.0f, 1.0f - cosTheta * cosTheta)); float3 liftDir = cross(cross(delta, normal), scale * delta); - float3 lift = liftCoefficient * cosTheta * sinTheta * liftDir; - float3 drag = dragCoefficient * abs(cosTheta) * doubleArea * delta; + float3 lift = liftCoefficient * cosTheta * sinTheta * liftDir * deltaLength / itrDt; + float3 drag = dragCoefficient * abs(cosTheta) * delta * deltaLength / itrDt; - float3 impulse = invSqrScale < 1.192092896e-07F ? float3(0.0f, 0.0f, 0.0f) : lift + drag; + float3 impulse = invSqrScale < 1.192092896e-07F ? float3(0.0f, 0.0f, 0.0f) : (lift + drag) * fluidDensity * doubleArea; curParticles.atomicAdd(i0, -impulse * c0.w); curParticles.atomicAdd(i1, -impulse * c1.w); diff --git a/NvCloth/src/neon/SwCollisionHelpers.h b/NvCloth/src/neon/SwCollisionHelpers.h index 0b9410b..acd8a2a 100644 --- a/NvCloth/src/neon/SwCollisionHelpers.h +++ b/NvCloth/src/neon/SwCollisionHelpers.h @@ -33,7 +33,7 @@ #include <arm_neon.h> #endif -namespace physx +namespace nv { namespace cloth { @@ -84,4 +84,4 @@ Simd4i Gather<Simd4i>::operator()(const Simd4i* ptr) const } } // namespace cloth -} // namespace physx +} // namespace nv diff --git a/NvCloth/src/scalar/SwCollisionHelpers.h b/NvCloth/src/scalar/SwCollisionHelpers.h index 0d7321f..af21812 100644 --- a/NvCloth/src/scalar/SwCollisionHelpers.h +++ b/NvCloth/src/scalar/SwCollisionHelpers.h @@ -29,7 +29,7 @@ #pragma once -namespace physx +namespace nv { namespace cloth { @@ -89,4 +89,4 @@ Scalar4i Gather<Scalar4i>::operator()(const Scalar4i* ptr) const } } // namespace cloth -} // namespace physx +} // namespace nv |