diff options
| author | mtamis <[email protected]> | 2017-02-15 16:06:25 +0100 |
|---|---|---|
| committer | mtamis <[email protected]> | 2017-02-15 16:06:25 +0100 |
| commit | 85305930aeeb1d513e23522bd91f29ba81aa6d14 (patch) | |
| tree | 45f1bb20a45a300d1fef107e436cac95602a0e57 /NvCloth/include | |
| download | nvcloth-85305930aeeb1d513e23522bd91f29ba81aa6d14.tar.xz nvcloth-85305930aeeb1d513e23522bd91f29ba81aa6d14.zip | |
NvCloth library v1.0.0
Diffstat (limited to 'NvCloth/include')
| -rw-r--r-- | NvCloth/include/NvCloth/Allocator.h | 184 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/Callbacks.h | 166 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/Cloth.h | 440 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/DxContextManagerCallback.h | 84 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/Fabric.h | 130 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/Factory.h | 194 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/PhaseConfig.h | 62 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/Range.h | 155 | ||||
| -rw-r--r-- | NvCloth/include/NvCloth/Solver.h | 99 |
9 files changed, 1514 insertions, 0 deletions
diff --git a/NvCloth/include/NvCloth/Allocator.h b/NvCloth/include/NvCloth/Allocator.h new file mode 100644 index 0000000..ade0698 --- /dev/null +++ b/NvCloth/include/NvCloth/Allocator.h @@ -0,0 +1,184 @@ +// 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. + + +/** \file Allocator.h + This file together with Callbacks.h define most memory management interfaces for internal use. +*/ + +/** \cond HIDDEN_SYMBOLS */ +#pragma once + +#include <PsArray.h> +#include <PsHashMap.h> +#include <PsAlignedMalloc.h> +#include "NvCloth/Callbacks.h" + +namespace nv +{ +namespace cloth +{ + +void* allocate(size_t); +void deallocate(void*); + +class NonTrackingAllocator +{ +public: + PX_FORCE_INLINE NonTrackingAllocator(const char* = 0) + { + } + PX_FORCE_INLINE void* allocate(size_t size, const char* file, int line) + { + return !size ? 0 : GetNvClothAllocator()->allocate(size, "NonTrackedAlloc", file, line); + } + PX_FORCE_INLINE void deallocate(void* ptr) + { + if (ptr) + GetNvClothAllocator()->deallocate(ptr); + } +}; + +/* templated typedefs for convenience */ + +template <typename T> +struct Vector +{ + typedef physx::shdfnd::Array<T, NonTrackingAllocator> Type; +}; + +template <typename T, size_t alignment> +struct AlignedVector +{ + typedef physx::shdfnd::Array<T, physx::shdfnd::AlignedAllocator<alignment, NonTrackingAllocator> > Type; +}; + +template <class Key, class Value, class HashFn = physx::shdfnd::Hash<Key> > +struct HashMap +{ + typedef physx::shdfnd::HashMap<Key, Value, HashFn, NonTrackingAllocator> Type; +}; + +struct NvClothOverload{}; +#define NV_CLOTH_NEW(T) new (__FILE__, __LINE__, nv::cloth::NvClothOverload()) T +#define NV_CLOTH_ALLOC(n, name) GetNvClothAllocator()->allocate(n, name, __FILE__, __LINE__) +#define NV_CLOTH_FREE(x) GetNvClothAllocator()->deallocate(x) +#define NV_CLOTH_DELETE(x) delete x + +} // namespace cloth +} // namespace nv + +//new/delete operators need to be declared in global scope +template <typename T> +PX_INLINE void* operator new(size_t size, const char* fileName, + typename physx::shdfnd::EnableIfPod<T, int>::Type line, nv::cloth::NvClothOverload overload) +{ + PX_UNUSED(overload); + return GetNvClothAllocator()->allocate(size, "<TypeName Unknown>", fileName, line); +} + +template <typename T> +PX_INLINE void* operator new [](size_t size, const char* fileName, + typename physx::shdfnd::EnableIfPod<T, int>::Type line, nv::cloth::NvClothOverload overload) +{ + PX_UNUSED(overload); + return GetNvClothAllocator()->allocate(size, "<TypeName Unknown>", fileName, line); +} + +// If construction after placement new throws, this placement delete is being called. +template <typename T> +PX_INLINE void operator delete(void* ptr, const char* fileName, + typename physx::shdfnd::EnableIfPod<T, int>::Type line, nv::cloth::NvClothOverload overload) +{ + PX_UNUSED(fileName); + PX_UNUSED(line); + PX_UNUSED(overload); + + return GetNvClothAllocator()->deallocate(ptr); +} + +// If construction after placement new throws, this placement delete is being called. +template <typename T> +PX_INLINE void operator delete [](void* ptr, const char* fileName, + typename physx::shdfnd::EnableIfPod<T, int>::Type line, nv::cloth::NvClothOverload overload) +{ + PX_UNUSED(fileName); + PX_UNUSED(line); + PX_UNUSED(overload); + + return GetNvClothAllocator()->deallocate(ptr); +} + +namespace nv +{ +namespace cloth +{ + +class UserAllocated +{ + public: + PX_INLINE void* operator new(size_t size, const char* fileName, int line, NvClothOverload overload) + { + PX_UNUSED(overload); + return GetNvClothAllocator()->allocate(size, "<TypeName Unknown>", fileName, line); + } + PX_INLINE void* operator new [](size_t size, const char* fileName, int line, NvClothOverload overload) + { + PX_UNUSED(overload); + return GetNvClothAllocator()->allocate(size, "<TypeName Unknown>", fileName, line); + } + + // placement delete + PX_INLINE void operator delete(void* ptr, const char* fileName, int line, NvClothOverload overload) + { + PX_UNUSED(fileName); + PX_UNUSED(line); + PX_UNUSED(overload); + GetNvClothAllocator()->deallocate(ptr); + } + PX_INLINE void operator delete [](void* ptr, const char* fileName, int line, NvClothOverload overload) + { + PX_UNUSED(fileName); + PX_UNUSED(line); + PX_UNUSED(overload); + GetNvClothAllocator()->deallocate(ptr); + } + PX_INLINE void operator delete(void* ptr) + { + return GetNvClothAllocator()->deallocate(ptr); + } + PX_INLINE void operator delete [](void* ptr) + { + return GetNvClothAllocator()->deallocate(ptr); + } +}; + +} // namespace cloth +} // namespace nv +/** \endcond */ diff --git a/NvCloth/include/NvCloth/Callbacks.h b/NvCloth/include/NvCloth/Callbacks.h new file mode 100644 index 0000000..13edaa2 --- /dev/null +++ b/NvCloth/include/NvCloth/Callbacks.h @@ -0,0 +1,166 @@ +// 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. + +/** \file Callbacks.h + \brief All functions to initialize and use user provided callbacks are declared in this header. + Initialize the callbacks with InitializeNvCloth(...) before using any other NvCloth API. + The other functions defined in this header are used to access the functionality provided by the callbacks, and are mostly for internal use. + */ + +#pragma once +#include <foundation/PxPreprocessor.h> +#include <foundation/PxProfiler.h> +#include <foundation/PxAssert.h> +#ifndef NV_CLOTH_IMPORT +#define NV_CLOTH_IMPORT PX_DLL_IMPORT +#endif + +#define NV_CLOTH_DLL_ID 0x2 + +#define NV_CLOTH_LINKAGE PX_C_EXPORT NV_CLOTH_IMPORT +#define NV_CLOTH_CALL_CONV PX_CALL_CONV +#define NV_CLOTH_API(ret_type) NV_CLOTH_LINKAGE ret_type NV_CLOTH_CALL_CONV + +namespace physx +{ + class PxAllocatorCallback; + class PxErrorCallback; + class PxProfilerCallback; + class PxAssertHandler; +} + +/** \brief NVidia namespace */ +namespace nv +{ +/** \brief nvcloth namespace */ +namespace cloth +{ +/** \brief Initialize the library by passing in callback functions. + This needs to be called before using any other part of the library. + @param allocatorCallback Callback interface for memory allocations. Needs to return 16 byte aligned memory. + @param errorCallback Callback interface for debug/warning/error messages. + @param assertHandler Callback interface for asserts. + @param profilerCallback Optional callback interface for performance information. + @param autoDllIDCheck Leave as default parameter. This is used to check header and dll version compatibility. + */ +NV_CLOTH_API(void) + InitializeNvCloth(physx::PxAllocatorCallback* allocatorCallback, physx::PxErrorCallback* errorCallback, + physx::PxAssertHandler* assertHandler, physx::PxProfilerCallback* profilerCallback, + int autoDllIDCheck = NV_CLOTH_DLL_ID); +} +} + +//Allocator +NV_CLOTH_API(physx::PxAllocatorCallback*) GetNvClothAllocator(); //Only use internally + +namespace nv +{ +namespace cloth +{ +//Logging +void LogErrorFn (const char* fileName, int lineNumber, const char* msg, ...); +void LogInvalidParameterFn (const char* fileName, int lineNumber, const char* msg, ...); +void LogWarningFn(const char* fileName, int lineNumber, const char* msg, ...); +void LogInfoFn (const char* fileName, int lineNumber, const char* msg, ...); +///arguments: NV_CLOTH_LOG_ERROR("format %s %s\n","additional","arguments"); +#define NV_CLOTH_LOG_ERROR(...) nv::cloth::LogErrorFn(__FILE__,__LINE__,__VA_ARGS__) +#define NV_CLOTH_LOG_INVALID_PARAMETER(...) nv::cloth::LogInvalidParameterFn(__FILE__,__LINE__,__VA_ARGS__) +#define NV_CLOTH_LOG_WARNING(...) nv::cloth::LogWarningFn(__FILE__,__LINE__,__VA_ARGS__) +#define NV_CLOTH_LOG_INFO(...) nv::cloth::LogInfoFn(__FILE__,__LINE__,__VA_ARGS__) + +//ASSERT +NV_CLOTH_API(physx::PxAssertHandler*) GetNvClothAssertHandler(); //This function needs to be exposed to properly inline asserts outside this dll +#if !PX_ENABLE_ASSERTS +#if PX_VC +#define NV_CLOTH_ASSERT(exp) __noop +#else +#define NV_CLOTH_ASSERT(exp) ((void)0) +#endif +#else +#define NV_CLOTH_ASSERT(exp) \ + { \ + static bool _ignore = false; \ + (static_cast<void>((!!(exp)) || (!_ignore && ((*nv::cloth::GetNvClothAssertHandler())(#exp, __FILE__, __LINE__, _ignore), false)))); \ + PX_CODE_ANALYSIS_ASSUME(exp); \ + } +#endif + +//Profiler +physx::PxProfilerCallback* GetNvClothProfiler(); //Only use internally +#if PX_DEBUG || PX_CHECKED || PX_PROFILE || 1 +class NvClothProfileScoped +{ + public: + PX_FORCE_INLINE NvClothProfileScoped(const char* eventName, bool detached, uint64_t contextId, + const char* fileName, int lineno, physx::PxProfilerCallback* callback) + : mCallback(callback) + { + PX_UNUSED(fileName); + PX_UNUSED(lineno); + mProfilerData = NULL; //nullptr doesn't work here on mac + if (mCallback) + { + mEventName = eventName; + mDetached = detached; + mContextId = contextId; + mProfilerData = mCallback->zoneStart(mEventName, mDetached, mContextId); + } + } + ~NvClothProfileScoped(void) + { + if (mCallback) + { + mCallback->zoneEnd(mProfilerData, mEventName, mDetached, mContextId); + } + } + physx::PxProfilerCallback* mCallback; + const char* mEventName; + bool mDetached; + uint64_t mContextId; + void* mProfilerData; +}; + +#define NV_CLOTH_PROFILE_ZONE(x, y) \ + nv::cloth::NvClothProfileScoped PX_CONCAT(_scoped, __LINE__)(x, false, y, __FILE__, __LINE__, nv::cloth::GetNvClothProfiler()) +#define NV_CLOTH_PROFILE_START_CROSSTHREAD(x, y) \ + (GetNvClothProfiler()!=nullptr? \ + GetNvClothProfiler()->zoneStart(x, true, y):nullptr) +#define NV_CLOTH_PROFILE_STOP_CROSSTHREAD(profilerData, x, y) \ + if (GetNvClothProfiler()) \ + GetNvClothProfiler()->zoneEnd(profilerData, x, true, y) +#else + +#define NV_CLOTH_PROFILE_ZONE(x, y) +#define NV_CLOTH_PROFILE_START_CROSSTHREAD(x, y) nullptr +#define NV_CLOTH_PROFILE_STOP_CROSSTHREAD(profilerData, x, y) + +#endif + +} +} diff --git a/NvCloth/include/NvCloth/Cloth.h b/NvCloth/include/NvCloth/Cloth.h new file mode 100644 index 0000000..9bf2bd0 --- /dev/null +++ b/NvCloth/include/NvCloth/Cloth.h @@ -0,0 +1,440 @@ +// 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. + +#pragma once + +#include "NvCloth/Range.h" +#include "NvCloth/PhaseConfig.h" +#include <foundation/PxVec3.h> +#include "NvCloth/Allocator.h" + +struct ID3D11Buffer; + +namespace nv +{ +namespace cloth +{ + +class Factory; +class Fabric; +class Cloth; + +#ifdef _MSC_VER +#pragma warning(disable : 4371) // layout of class may have changed from a previous version of the compiler due to + // better packing of member +#endif + +template <typename T> +struct MappedRange : public Range<T> +{ + MappedRange(T* first, T* last, const Cloth& cloth, void (Cloth::*lock)() const, void (Cloth::*unlock)() const) + : Range<T>(first, last), mCloth(cloth), mLock(lock), mUnlock(unlock) + { + } + + MappedRange(const MappedRange& other) + : Range<T>(other), mCloth(other.mCloth), mLock(other.mLock), mUnlock(other.mUnlock) + { + (mCloth.*mLock)(); + } + + ~MappedRange() + { + (mCloth.*mUnlock)(); + } + + private: + MappedRange& operator = (const MappedRange&); + + const Cloth& mCloth; + void (Cloth::*mLock)() const; + void (Cloth::*mUnlock)() const; +}; + +struct GpuParticles +{ + physx::PxVec4* mCurrent; + physx::PxVec4* mPrevious; + ID3D11Buffer* mBuffer; +}; + +// abstract cloth instance +class Cloth : public UserAllocated +{ + protected: + Cloth() {} + Cloth(const Cloth&); + Cloth& operator = (const Cloth&); + + public: + virtual ~Cloth() {} + + /** \brief Creates a duplicate of this Cloth instance. + Same as: + \code + getFactory().clone(*this); + \endcode + */ + virtual Cloth* clone(Factory& factory) const = 0; + + /** \brief Returns the fabric used to create this Cloth.*/ + virtual Fabric& getFabric() const = 0; + /** \brief Returns the Factory used to create this Cloth.*/ + virtual Factory& getFactory() const = 0; + + /* particle properties */ + /// Returns the number of particles simulated by this fabric. + virtual uint32_t getNumParticles() const = 0; + /** \brief Used internally to synchronize CPU and GPU particle memory.*/ + virtual void lockParticles() const = 0; //Might be better if it was called map/unmapParticles + /** \brief Used internally to synchronize CPU and GPU particle memory.*/ + virtual void unlockParticles() const = 0; + + /** \brief Returns the simulation particles of the current frame. + Each PxVec4 element contains the particle position in the XYZ components and the inverse mass in the W component. + The returned memory may be overwritten (to change attachment point locations for animation for example). + Setting the inverse mass to 0 locks the particle in place. + */ + virtual MappedRange<physx::PxVec4> getCurrentParticles() = 0; + + /** \brief Returns the simulation particles of the current frame, read only. + Similar to the non-const version of this function. + This version is preferred as it doesn't wake up the cloth to account for the possibility that particles were changed. + */ + virtual MappedRange<const physx::PxVec4> getCurrentParticles() const = 0; + + /** \brief Returns the simulation particles of the previous frame. + Similar to getCurrentParticles(). + */ + virtual MappedRange<physx::PxVec4> getPreviousParticles() = 0; + + /** \brief Returns the simulation particles of the previous frame. + Similar to getCurrentParticles() const. + */ + virtual MappedRange<const physx::PxVec4> getPreviousParticles() const = 0; + + /** \brief Returns platform dependent pointers to the current GPU particle memory.*/ + virtual GpuParticles getGpuParticles() = 0; + + + /** \brief Set the translation of the local space simulation after next call to simulate(). + This applies a force to make the cloth behave as if it was moved through space. + This does not move the particles as they are in local space. + Use the graphics transformation matrices to render the cloth in the proper location. + The applied force is proportional to the value set with Cloth::setLinearInertia(). + */ + virtual void setTranslation(const physx::PxVec3& trans) = 0; + + /** \brief Set the rotation of the local space simulation after next call to simulate(). + Similar to Cloth::setTranslation(). + The applied force is proportional to the value set with Cloth::setAngularInertia() and Cloth::setCentrifugalInertia(). + */ + virtual void setRotation(const physx::PxQuat& rot) = 0; + + /** \brief Returns the current translation value that was set using setTranslation().*/ + virtual const physx::PxVec3& getTranslation() const = 0; + /** \brief Returns the current rotation value that was set using setRotation().*/ + virtual const physx::PxQuat& getRotation() const = 0; + + /** \brief Set inertia derived from setTranslation() and setRotation() to zero (once).*/ + virtual void clearInertia() = 0; + + /** \brief Adjust the position of the cloth without affecting the dynamics (to call after a world origin shift, for example). */ + virtual void teleport(const physx::PxVec3& delta) = 0; + + /* solver parameters */ + + /** \brief Returns the delta time used for previous iteration.*/ + virtual float getPreviousIterationDt() const = 0; + + /** \brief Sets gravity in global coordinates.*/ + virtual void setGravity(const physx::PxVec3&) = 0; + /// Returns gravity set with setGravity(). + virtual physx::PxVec3 getGravity() const = 0; + + /** \brief Sets damping of local particle velocity (1/stiffnessFrequency). + 0 (default): velocity is unaffected, 1: velocity is zeroed + */ + virtual void setDamping(const physx::PxVec3&) = 0; + /// Returns value set with setDamping(). + virtual physx::PxVec3 getDamping() const = 0; + + // portion of local frame velocity applied to particles + // 0 (default): particles are unaffected + // same as damping: damp global particle velocity + virtual void setLinearDrag(const physx::PxVec3&) = 0; + virtual physx::PxVec3 getLinearDrag() const = 0; + virtual void setAngularDrag(const physx::PxVec3&) = 0; + virtual physx::PxVec3 getAngularDrag() const = 0; + + /** \brief Set the portion of local frame linear acceleration applied to particles. + 0: particles are unaffected, 1 (default): physically correct. + */ + virtual void setLinearInertia(const physx::PxVec3&) = 0; + /// Returns value set with getLinearInertia(). + virtual physx::PxVec3 getLinearInertia() const = 0; + /** \brief Similar to setLinearInertia(), but for angular inertia.*/ + virtual void setAngularInertia(const physx::PxVec3&) = 0; + /// Returns value set with setAngularInertia(). + virtual physx::PxVec3 getAngularInertia() const = 0; + /** \brief Similar to setLinearInertia(), but for centrifugal inertia.*/ + virtual void setCentrifugalInertia(const physx::PxVec3&) = 0; + ///Returns value set with setCentrifugalInertia(). + virtual physx::PxVec3 getCentrifugalInertia() const = 0; + + /** \brief Set target solver iterations per second. + At least 1 iteration per frame will be solved regardless of the value set. + */ + virtual void setSolverFrequency(float) = 0; + /// Returns gravity set with getSolverFrequency().*/ + virtual float getSolverFrequency() const = 0; + + // damp, drag, stiffness exponent per second + virtual void setStiffnessFrequency(float) = 0; + virtual float getStiffnessFrequency() const = 0; + + // filter width for averaging dt^2 factor of gravity and + // external acceleration, in numbers of iterations (default=30). + virtual void setAcceleationFilterWidth(uint32_t) = 0; + virtual uint32_t getAccelerationFilterWidth() const = 0; + + // setup edge constraint solver iteration + virtual void setPhaseConfig(Range<const PhaseConfig> configs) = 0; + + /* collision parameters */ + + /** \brief Set spheres for collision detection. + Elements of spheres contain PxVec4(x,y,z,r) where [x,y,z] is the center and r the radius of the sphere. + The values currently in range[first, last[ will be replaced with the content of spheres. + \code + cloth->setSpheres(Range<const PxVec4>(), 0, cloth->getNumSpheres()); //Removes all spheres + \endcode + */ + virtual void setSpheres(Range<const physx::PxVec4> spheres, uint32_t first, uint32_t last) = 0; + /// Returns the number of spheres currently set. + virtual uint32_t getNumSpheres() const = 0; + + + /** \brief Set indices for capsule collision detection. + The indices define the spheres that form the end points between the capsule. + Every two elements in capsules define one capsule. + The values currently in range[first, last[ will be replaced with the content of capsules. + Note that first and last are indices to whole capsules consisting of 2 indices each. So if + you want to update the first two capsules (without changing the total number of capsules) + you would use the following code: + \code + uint32_t capsules[4] = { 0,1, 1,2 }; //Define indices for 2 capsules + //updates the indices of the first 2 capsules in cloth + cloth->setCapsules(Range<const uint32_t>(capsules, capsules + 4), 0, 2); + \endcode + */ + virtual void setCapsules(Range<const uint32_t> capsules, uint32_t first, uint32_t last) = 0; + /// Returns the number of capsules (which is half the number of capsule indices). + virtual uint32_t getNumCapsules() const = 0; + + /** \brief Sets plane values to be used with convex collision detection. + The planes are specified in the form ax + by + cz + d = 0, where elements in planes contain PxVec4(x,y,z,d). + [x,y,z] is required to be normalized. + The values currently in range [first, last[ will be replaced with the content of planes. + Use setConvexes to enable planes for collision detection. + */ + virtual void setPlanes(Range<const physx::PxVec4> planes, uint32_t first, uint32_t last) = 0; + /// Returns the number of planes currently set. + virtual uint32_t getNumPlanes() const = 0; + + /** \brief Enable planes for collision. + convexMasks must contain masks of the form (1<<planeIndex1)|(1<<planeIndex2)|...|(1<<planeIndexN). + All planes masked in a single element of convexMasks form a single convex polyhedron. + The values currently in range [first, last[ will be replaced with the content of convexMasks. + */ + virtual void setConvexes(Range<const uint32_t> convexMasks, uint32_t first, uint32_t last) = 0; + /// Returns the number of convexMasks currently set. + virtual uint32_t getNumConvexes() const = 0; + + /** \brief Set triangles for collision. + Each triangle in the list is defined by of 3 vertices. + The values currently in range [first, last[ will be replaced with the content of convexMasks. + */ + virtual void setTriangles(Range<const physx::PxVec3> triangles, uint32_t first, uint32_t last) = 0; + virtual void setTriangles(Range<const physx::PxVec3> triangles, Range<const physx::PxVec3>, uint32_t first) = 0; + /// Returns the number of triangles currently set. + virtual uint32_t getNumTriangles() const = 0; + + /// Returns true if we use ccd + virtual bool isContinuousCollisionEnabled() const = 0; + /// Set if we use ccd or not (disabled by default) + virtual void enableContinuousCollision(bool) = 0; + + // controls how quickly mass is increased during collisions + virtual float getCollisionMassScale() const = 0; + virtual void setCollisionMassScale(float) = 0; + + /** \brief Set the cloth collision shape friction coefficient.*/ + virtual void setFriction(float) = 0; + ///Returns value set with setFriction(). + virtual float getFriction() const = 0; + + // set virtual particles for collision handling. + // each indices element consists of 3 particle + // indices and an index into the lerp weights array. + virtual void setVirtualParticles(Range<const uint32_t[4]> indices, Range<const physx::PxVec3> weights) = 0; + virtual uint32_t getNumVirtualParticles() const = 0; + virtual uint32_t getNumVirtualParticleWeights() const = 0; + + /* tether constraint parameters */ + + /** \brief Set Tether constraint scale. + 1.0 is the original scale of the Fabric. + 0.0 disables tether constraints in the Solver. + */ + virtual void setTetherConstraintScale(float scale) = 0; + ///Returns value set with setTetherConstraintScale(). + virtual float getTetherConstraintScale() const = 0; + /** \brief Set Tether constraint stiffness.. + 1.0 is the default. + <1.0 makes the constraints behave springy. + */ + virtual void setTetherConstraintStiffness(float stiffness) = 0; + ///Returns value set with setTetherConstraintStiffness(). + virtual float getTetherConstraintStiffness() const = 0; + + /* motion constraint parameters */ + + /** \brief Returns reference to motion constraints (position, radius) + The entire range must be written after calling this function. + */ + virtual Range<physx::PxVec4> getMotionConstraints() = 0; + /** \brief Removes all motion constraints. + */ + virtual void clearMotionConstraints() = 0; + virtual uint32_t getNumMotionConstraints() const = 0; + virtual void setMotionConstraintScaleBias(float scale, float bias) = 0; + virtual float getMotionConstraintScale() const = 0; + virtual float getMotionConstraintBias() const = 0; + virtual void setMotionConstraintStiffness(float stiffness) = 0; + virtual float getMotionConstraintStiffness() const = 0; + + /* separation constraint parameters */ + + // return reference to separation constraints (position, radius) + // The entire range must be written after calling this function. + virtual Range<physx::PxVec4> getSeparationConstraints() = 0; + virtual void clearSeparationConstraints() = 0; + virtual uint32_t getNumSeparationConstraints() const = 0; + + /* clear interpolation */ + + // assign current to previous positions for + // collision spheres, motion, and separation constraints + virtual void clearInterpolation() = 0; + + /* particle acceleration parameters */ + + // return reference to particle accelerations (in local coordinates) + // The entire range must be written after calling this function. + virtual Range<physx::PxVec4> getParticleAccelerations() = 0; + virtual void clearParticleAccelerations() = 0; + virtual uint32_t getNumParticleAccelerations() const = 0; + + /* wind */ + + /** /brief Set wind in global coordinates. Acts on the fabric's triangles. */ + virtual void setWindVelocity(physx::PxVec3) = 0; + ///Returns value set with setWindVelocity(). + virtual physx::PxVec3 getWindVelocity() const = 0; + /** /brief Sets the air drag coefficient. */ + virtual void setDragCoefficient(float) = 0; + ///Returns value set with setDragCoefficient(). + virtual float getDragCoefficient() const = 0; + /** /brief Sets the air lift coefficient. */ + virtual void setLiftCoefficient(float) = 0; + ///Returns value set with setLiftCoefficient(). + virtual float getLiftCoefficient() const = 0; + + /* self collision */ + + /** /brief Set the distance particles need to be separated from each other withing the cloth. */ + virtual void setSelfCollisionDistance(float distance) = 0; + ///Returns value set with setSelfCollisionDistance(). + virtual float getSelfCollisionDistance() const = 0; + /** /brief Set the constraint stiffness for the self collision constraints. */ + virtual void setSelfCollisionStiffness(float stiffness) = 0; + ///Returns value set with setSelfCollisionStiffness(). + virtual float getSelfCollisionStiffness() const = 0; + + virtual void setSelfCollisionIndices(Range<const uint32_t>) = 0; + virtual uint32_t getNumSelfCollisionIndices() const = 0; + + /* rest positions */ + + // set rest particle positions used during self-collision + virtual void setRestPositions(Range<const physx::PxVec4>) = 0; + virtual uint32_t getNumRestPositions() const = 0; + + /* bounding box */ + + /** \brief Returns current particle position bounds center in local space */ + virtual const physx::PxVec3& getBoundingBoxCenter() const = 0; + /** \brief Returns current particle position bounds size in local space */ + virtual const physx::PxVec3& getBoundingBoxScale() const = 0; + + /* sleeping (disabled by default) */ + + // max particle velocity (per axis) to pass sleep test + virtual void setSleepThreshold(float) = 0; + virtual float getSleepThreshold() const = 0; + // test sleep condition every nth millisecond + virtual void setSleepTestInterval(uint32_t) = 0; + virtual uint32_t getSleepTestInterval() const = 0; + // put cloth to sleep when n consecutive sleep tests pass + virtual void setSleepAfterCount(uint32_t) = 0; + virtual uint32_t getSleepAfterCount() const = 0; + virtual uint32_t getSleepPassCount() const = 0; + virtual bool isAsleep() const = 0; + virtual void putToSleep() = 0; + virtual void wakeUp() = 0; + + /** \brief Set user data. Not used internally. */ + virtual void setUserData(void*) = 0; + // Returns value set by setUserData(). + virtual void* getUserData() const = 0; +}; + +// wrappers to prevent non-const overload from marking particles dirty +inline MappedRange<const physx::PxVec4> readCurrentParticles(const Cloth& cloth) +{ + return cloth.getCurrentParticles(); +} +inline MappedRange<const physx::PxVec4> readPreviousParticles(const Cloth& cloth) +{ + return cloth.getPreviousParticles(); +} + +} // namespace cloth +} // namespace nv diff --git a/NvCloth/include/NvCloth/DxContextManagerCallback.h b/NvCloth/include/NvCloth/DxContextManagerCallback.h new file mode 100644 index 0000000..05c6aaa --- /dev/null +++ b/NvCloth/include/NvCloth/DxContextManagerCallback.h @@ -0,0 +1,84 @@ +// 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. + +#pragma once + +struct ID3D11Device; +struct ID3D11DeviceContext; + +namespace nv +{ +namespace cloth +{ + +/** Callback interface to manage the DirectX context/device used for compute + * + */ +class DxContextManagerCallback +{ +public: + virtual ~DxContextManagerCallback() {} + /** + * \brief Acquire the D3D context for the current thread + * + * Acquisitions are allowed to be recursive within a single thread. + * You can acquire the context multiple times so long as you release + * it the same count. + */ + virtual void acquireContext() = 0; + + /** + * \brief Release the D3D context from the current thread + */ + virtual void releaseContext() = 0; + + /** + * \brief Return the D3D device to use for compute work + */ + virtual ID3D11Device* getDevice() const = 0; + + /** + * \brief Return the D3D context to use for compute work + */ + virtual ID3D11DeviceContext* getContext() const = 0; + + /** + * \brief Return if exposed buffers (only cloth particles at the moment) + * are created with D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX. + * + * The user is responsible to query and acquire the mutex of all + * corresponding buffers. + * todo: We should acquire the mutex locally if we continue to + * allow resource sharing across devices. + */ + virtual bool synchronizeResources() const = 0; +}; + +} +}
\ No newline at end of file diff --git a/NvCloth/include/NvCloth/Fabric.h b/NvCloth/include/NvCloth/Fabric.h new file mode 100644 index 0000000..02b1140 --- /dev/null +++ b/NvCloth/include/NvCloth/Fabric.h @@ -0,0 +1,130 @@ +// 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. + +#pragma once + +#include "NvCloth/Callbacks.h" +#include "NvCloth/Allocator.h" +#include <PsAtomic.h> + +namespace nv +{ +namespace cloth +{ + +class Factory; + +// abstract cloth constraints and triangle indices +class Fabric : public UserAllocated +{ +protected: + Fabric(const Fabric&); + Fabric& operator = (const Fabric&); + +protected: + Fabric() : mRefCount(1) + { + } + + virtual ~Fabric() + { + NV_CLOTH_ASSERT(0 == mRefCount); + } + +public: + /** \brief Returns the Factory used to create this Fabric.*/ + virtual Factory& getFactory() const = 0; + + /** \brief Returns the number of constraint solve phases stored. + Phases are groups of constraints that make up the general structure of the fabric. + Cloth instances can have different configuration settings per phase (see Cloth::setPhaseConfig()). + Phases are usually split by type (horizontal, vertical, bending, shearing), depending on the cooker used. + */ + virtual uint32_t getNumPhases() const = 0; + + /** \brief Returns the number of rest lengths stored. + Each constraint uses the rest value to determine if the two connected particles need to be pulled together or pushed apart. + */ + virtual uint32_t getNumRestvalues() const = 0; + + /** \brief Returns the number of constraint stiffness values stored. + It is optional for a Fabric to have per constraint stiffness values provided. + This function will return 0 if no values are stored. + Stiffness per constraint values stored here can be used if more fine grain control is required (as opposed to the values stored in the cloth's phase configuration). + The Cloth 's phase configuration stiffness values will be ignored if stiffness per constraint values are used. + */ + virtual uint32_t getNumStiffnessValues() const = 0; + + + /** \brief Returns the number of sets stored. + Sets connect a phase to a range of indices. + */ + virtual uint32_t getNumSets() const = 0; + + /** \brief Returns the number of indices stored. + Each constraint has a pair of indices that indicate which particles it connects. + */ + virtual uint32_t getNumIndices() const = 0; + /// Returns the number of particles. + virtual uint32_t getNumParticles() const = 0; + /// Returns the number of Tethers stored. + virtual uint32_t getNumTethers() const = 0; + /// Returns the number of triangles that make up the cloth mesh. + virtual uint32_t getNumTriangles() const = 0; + + /** Scales all constraint rest lengths.*/ + virtual void scaleRestvalues(float) = 0; + /** Scales all tether lengths.*/ + virtual void scaleTetherLengths(float) = 0; + + void incRefCount() + { + physx::shdfnd::atomicIncrement(&mRefCount); + NV_CLOTH_ASSERT(mRefCount > 0); + } + + /// Returns true if the object is destroyed + bool decRefCount() + { + NV_CLOTH_ASSERT(mRefCount > 0); + int result = physx::shdfnd::atomicDecrement(&mRefCount); + if (result == 0) + { + delete this; + return true; + } + return false; + } + + protected: + int32_t mRefCount; +}; + +} // namespace cloth +} // namespace nv diff --git a/NvCloth/include/NvCloth/Factory.h b/NvCloth/include/NvCloth/Factory.h new file mode 100644 index 0000000..bb06451 --- /dev/null +++ b/NvCloth/include/NvCloth/Factory.h @@ -0,0 +1,194 @@ +// 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. + +#pragma once + +#include "NvCloth/Range.h" +#include <foundation/PxVec4.h> +#include <foundation/PxVec3.h> +#include "NvCloth/Allocator.h" + +typedef struct CUctx_st* CUcontext; + +namespace nv +{ +namespace cloth +{ +class DxContextManagerCallback; +class Factory; +} +} +NV_CLOTH_API(nv::cloth::Factory*) NvClothCreateFactoryCPU(); +NV_CLOTH_API(nv::cloth::Factory*) NvClothCreateFactoryCUDA(CUcontext); +NV_CLOTH_API(nv::cloth::Factory*) NvClothCreateFactoryDX11(nv::cloth::DxContextManagerCallback*); +NV_CLOTH_API(void) NvClothDestroyFactory(nv::cloth::Factory*); + +///Returns true if this dll was compiled with cuda support +NV_CLOTH_API(bool) NvClothCompiledWithCudaSupport(); +///Returns true if this dll was compiled with DX support +NV_CLOTH_API(bool) NvClothCompiledWithDxSupport(); + +namespace nv +{ +namespace cloth +{ + +class Fabric; +class Cloth; +class Solver; + +enum struct Platform +{ + CPU, + CUDA, + DX11 +}; + +/// abstract factory to create context-specific simulation components +/// such as cloth, solver, collision, etc. +class Factory : public UserAllocated +{ + protected: + Factory() {} + Factory(const Factory&); + Factory& operator = (const Factory&); + virtual ~Factory() {} + + friend NV_CLOTH_IMPORT void NV_CLOTH_CALL_CONV ::NvClothDestroyFactory(nv::cloth::Factory*); + + public: + virtual Platform getPlatform() const = 0; + + /** + \brief Create fabric data used to setup cloth object. + Look at the cooking extension for helper functions to create fabrics from meshes. + The returned fabric will have a refcount of 1. + @param numParticles number of particles, must be larger than any particle index + @param phaseIndices map from phase to set index + @param sets inclusive prefix sum of restvalue count per set + @param restvalues array of constraint rest values + @param indices array of particle index pair per constraint + */ + virtual Fabric* createFabric(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) = 0; + + /** + \brief Create cloth object. + @param particles initial particle positions. + @param fabric edge distance constraint structure + */ + virtual Cloth* createCloth(Range<const physx::PxVec4> particles, Fabric& fabric) = 0; + + /** + \brief Create cloth solver object. + */ + virtual Solver* createSolver() = 0; + + /** + \brief Create a copy of a cloth instance + @param cloth the instance to be cloned, need not match the factory type + */ + virtual Cloth* clone(const Cloth& cloth) = 0; + + /** + \brief Extract original data from a fabric object. + Use the getNum* methods on Cloth to get the memory requirements before calling this function. + @param fabric to extract from, must match factory type + @param phaseIndices pre-allocated memory range to write phase => set indices + @param sets pre-allocated memory range to write sets + @param restvalues pre-allocated memory range to write restvalues + @param indices pre-allocated memory range to write indices + */ + virtual void extractFabricData(const Fabric& fabric, Range<uint32_t> phaseIndices, Range<uint32_t> sets, + Range<float> restvalues, Range<float> stiffnessValues, Range<uint32_t> indices, Range<uint32_t> anchors, + Range<float> tetherLengths, Range<uint32_t> triangles) const = 0; + + /** + \brief Extract current collision spheres and capsules from a cloth object. + Use the getNum* methods on Cloth to get the memory requirements before calling this function. + @param cloth the instance to extract from, must match factory type + @param spheres pre-allocated memory range to write spheres + @param capsules pre-allocated memory range to write capsules + @param planes pre-allocated memory range to write planes + @param convexes pre-allocated memory range to write convexes + @param triangles pre-allocated memory range to write triangles + */ + virtual void extractCollisionData(const Cloth& cloth, Range<physx::PxVec4> spheres, Range<uint32_t> capsules, + Range<physx::PxVec4> planes, Range<uint32_t> convexes, Range<physx::PxVec3> triangles) const = 0; + + /** + Extract current motion constraints from a cloth object + Use the getNum* methods on Cloth to get the memory requirements before calling this function. + @param cloth the instance to extract from, must match factory type + @param destConstraints pre-allocated memory range to write constraints + */ + virtual void extractMotionConstraints(const Cloth& cloth, Range<physx::PxVec4> destConstraints) const = 0; + + /** + Extract current separation constraints from a cloth object + @param cloth the instance to extract from, must match factory type + @param destConstraints pre-allocated memory range to write constraints + */ + virtual void extractSeparationConstraints(const Cloth& cloth, Range<physx::PxVec4> destConstraints) const = 0; + + /** + Extract current particle accelerations from a cloth object + @param cloth the instance to extract from, must match factory type + @param destAccelerations pre-allocated memory range to write accelerations + */ + virtual void extractParticleAccelerations(const Cloth& cloth, Range<physx::PxVec4> destAccelerations) const = 0; + + /** + Extract virtual particles from a cloth object + @param cloth the instance to extract from, must match factory type + @param destIndices pre-allocated memory range to write indices + @param destWeights pre-allocated memory range to write weights + */ + virtual void extractVirtualParticles(const Cloth& cloth, Range<uint32_t[4]> destIndices, + Range<physx::PxVec3> destWeights) const = 0; + + /** + Extract self collision indices from cloth object. + @param cloth the instance to extract from, must match factory type + @param destIndices pre-allocated memory range to write indices + */ + virtual void extractSelfCollisionIndices(const Cloth& cloth, Range<uint32_t> destIndices) const = 0; + + /** + Extract particle rest positions from cloth object. + @param cloth the instance to extract from, must match factory type + @param destRestPositions pre-allocated memory range to write rest positions + */ + virtual void extractRestPositions(const Cloth& cloth, Range<physx::PxVec4> destRestPositions) const = 0; +}; + +} // namespace cloth +} // namespace nv diff --git a/NvCloth/include/NvCloth/PhaseConfig.h b/NvCloth/include/NvCloth/PhaseConfig.h new file mode 100644 index 0000000..328dc32 --- /dev/null +++ b/NvCloth/include/NvCloth/PhaseConfig.h @@ -0,0 +1,62 @@ +// 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. + +#pragma once + +#include <foundation/Px.h> + +namespace nv +{ +namespace cloth +{ + +struct PhaseConfig +{ + PhaseConfig(uint16_t index = uint16_t(-1)) + : mStiffness(1.0f) + , mStiffnessMultiplier(1.0f) + , mCompressionLimit(1.0f) + , mStretchLimit(1.0f) + , mPhaseIndex(index) + , mPadding(0xffff) + { + } + + //These 4 floats need to be in order as they are loaded in to simd vectors in the solver + float mStiffness; // target convergence rate per iteration (1/solverFrequency) + float mStiffnessMultiplier; + float mCompressionLimit; + float mStretchLimit; + + uint16_t mPhaseIndex; + uint16_t mPadding; +}; + +} // namespace cloth +} // namespace nv diff --git a/NvCloth/include/NvCloth/Range.h b/NvCloth/include/NvCloth/Range.h new file mode 100644 index 0000000..c5c4059 --- /dev/null +++ b/NvCloth/include/NvCloth/Range.h @@ -0,0 +1,155 @@ +// 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. + +#pragma once + +#include "NvCloth/Callbacks.h" + +namespace nv +{ +namespace cloth +{ + +template <class T> +struct Range +{ + /** \brief Construct an empty range. + */ + Range(); + + /** \brief Construct a range (array like container) using existing memory. + Range doesn't take ownership of this memory. + Interface works similar to std::vector. + @param begin start of the memory + @param end end of the memory range, point to one element past the last valid element. + */ + Range(T* begin, T* end); + + template <typename S> + Range(const Range<S>& other); + + uint32_t size() const; + bool empty() const; + + void popFront(); + void popBack(); + + T* begin() const; + T* end() const; + + T& front() const; + T& back() const; + + T& operator[](uint32_t i) const; + + private: + T* mBegin; + T* mEnd; // past last element (like std::vector::end()) +}; + +template <typename T> +Range<T>::Range() +: mBegin(0), mEnd(0) +{ +} + +template <typename T> +Range<T>::Range(T* begin, T* end) +: mBegin(begin), mEnd(end) +{ +} + +template <typename T> +template <typename S> +Range<T>::Range(const Range<S>& other) +: mBegin(other.begin()), mEnd(other.end()) +{ +} + +template <typename T> +uint32_t Range<T>::size() const +{ + return uint32_t(mEnd - mBegin); +} + +template <typename T> +bool Range<T>::empty() const +{ + return mBegin >= mEnd; +} + +template <typename T> +void Range<T>::popFront() +{ + NV_CLOTH_ASSERT(mBegin < mEnd); + ++mBegin; +} + +template <typename T> +void Range<T>::popBack() +{ + NV_CLOTH_ASSERT(mBegin < mEnd); + --mEnd; +} + +template <typename T> +T* Range<T>::begin() const +{ + return mBegin; +} + +template <typename T> +T* Range<T>::end() const +{ + return mEnd; +} + +template <typename T> +T& Range<T>::front() const +{ + NV_CLOTH_ASSERT(mBegin < mEnd); + return *mBegin; +} + +template <typename T> +T& Range<T>::back() const +{ + NV_CLOTH_ASSERT(mBegin < mEnd); + return mEnd[-1]; +} + +template <typename T> +T& Range<T>::operator[](uint32_t i) const +{ + NV_CLOTH_ASSERT(mBegin + i < mEnd); + return mBegin[i]; +} + +} // namespace cloth +} // namespace nv diff --git a/NvCloth/include/NvCloth/Solver.h b/NvCloth/include/NvCloth/Solver.h new file mode 100644 index 0000000..9d1e373 --- /dev/null +++ b/NvCloth/include/NvCloth/Solver.h @@ -0,0 +1,99 @@ +// 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. + +#pragma once + +#include "NvCloth/Allocator.h" + +namespace nv +{ +namespace cloth +{ + +class Cloth; + +// called during inter-collision, user0 and user1 are the user data from each cloth +typedef bool (*InterCollisionFilter)(void* user0, void* user1); + +/// base class for solvers +class Solver : public UserAllocated +{ + protected: + Solver() {} + Solver(const Solver&); + Solver& operator = (const Solver&); + + public: + virtual ~Solver() {} + + /// Adds cloth object, returns true if successful. + virtual void addCloth(Cloth*) = 0; + + /// Removes cloth object. + virtual void removeCloth(Cloth*) = 0; + + // functions executing the simulation work. + /** \brief Begins a simulation frame. + Returns false if there is nothing to simulate. + Use simulateChunk() after calling this function to do the computation. + @param dt The delta time for this frame. + */ + virtual bool beginSimulation(float dt) = 0; + + /** \brief Do the computationally heavy part of the simulation. + Call this function getSimulationChunkCount() times to do the entire simulation. + This function can be called from multiple threads in parallel. + All Chunks need to be simulated before ending the frame. + */ + virtual void simulateChunk(int idx) = 0; + + /** \brief Finishes up the simulation. + This function can be expensive if inter-collision is enabled. + */ + virtual void endSimulation() = 0; + + /** \brief Returns the number of chunks that need to be simulated this frame. + */ + virtual int getSimulationChunkCount() const = 0; + + // inter-collision parameters + virtual void setInterCollisionDistance(float distance) = 0; + virtual float getInterCollisionDistance() const = 0; + virtual void setInterCollisionStiffness(float stiffness) = 0; + virtual float getInterCollisionStiffness() const = 0; + virtual void setInterCollisionNbIterations(uint32_t nbIterations) = 0; + virtual uint32_t getInterCollisionNbIterations() const = 0; + virtual void setInterCollisionFilter(InterCollisionFilter filter) = 0; + + /// Returns true if an unrecoverable error has occurred. + virtual bool hasError() const = 0; +}; + +} // namespace cloth +} // namespace nv |