Add NvCloth dependency
This commit is contained in:
168
Source/ThirdParty/NvCloth/Allocator.h
vendored
Normal file
168
Source/ThirdParty/NvCloth/Allocator.h
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
// 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-2020 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 "NvCloth/ps/PsArray.h"
|
||||
#include "NvCloth/ps/PsHashMap.h"
|
||||
#include "NvCloth/Callbacks.h"
|
||||
#include "NvCloth/ps/PsAlignedMalloc.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
namespace cloth
|
||||
{
|
||||
|
||||
void* allocate(size_t);
|
||||
void deallocate(void*);
|
||||
|
||||
|
||||
/* templated typedefs for convenience */
|
||||
|
||||
template <typename T>
|
||||
struct Vector
|
||||
{
|
||||
typedef ps::Array<T, ps::NonTrackingAllocator> Type;
|
||||
};
|
||||
|
||||
template <typename T, size_t alignment>
|
||||
struct AlignedVector
|
||||
{
|
||||
typedef ps::Array<T, ps::AlignedAllocator<alignment, ps::NonTrackingAllocator> > Type;
|
||||
};
|
||||
|
||||
template <class Key, class Value, class HashFn = ps::Hash<Key> >
|
||||
struct HashMap
|
||||
{
|
||||
typedef ps::HashMap<Key, Value, HashFn, ps::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 nv::cloth::ps::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 nv::cloth::ps::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 nv::cloth::ps::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 nv::cloth::ps::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 */
|
||||
192
Source/ThirdParty/NvCloth/Callbacks.h
vendored
Normal file
192
Source/ThirdParty/NvCloth/Callbacks.h
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// 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-2020 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/PxAllocatorCallback.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
|
||||
|
||||
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
class PxAllocatorCallback;
|
||||
class PxErrorCallback;
|
||||
class PxProfilerCallback;
|
||||
class PxAssertHandler;
|
||||
|
||||
/** \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,
|
||||
nv::cloth::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
|
||||
{
|
||||
|
||||
/* Base class to handle assert failures */
|
||||
class PxAssertHandler
|
||||
{
|
||||
public:
|
||||
virtual ~PxAssertHandler()
|
||||
{
|
||||
}
|
||||
virtual void operator()(const char* exp, const char* file, int line, bool& ignore) = 0;
|
||||
};
|
||||
|
||||
|
||||
//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(nv::cloth::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
|
||||
#define NV_CLOTH_ASSERT_WITH_MESSAGE(message, exp) __noop
|
||||
#else
|
||||
#define NV_CLOTH_ASSERT(exp) ((void)0)
|
||||
#define NV_CLOTH_ASSERT_WITH_MESSAGE(message, exp) ((void)0)
|
||||
#endif
|
||||
#else
|
||||
#if PX_VC
|
||||
#define PX_CODE_ANALYSIS_ASSUME(exp) \
|
||||
__analysis_assume(!!(exp)) // This macro will be used to get rid of analysis warning messages if a NV_CLOTH_ASSERT is used
|
||||
// to "guard" illegal mem access, for example.
|
||||
#else
|
||||
#define PX_CODE_ANALYSIS_ASSUME(exp)
|
||||
#endif
|
||||
#define NV_CLOTH_ASSERT(exp) \
|
||||
{ \
|
||||
static bool _ignore = false; \
|
||||
((void)((!!(exp)) || (!_ignore && ((*nv::cloth::GetNvClothAssertHandler())(#exp, __FILE__, __LINE__, _ignore), false)))); \
|
||||
PX_CODE_ANALYSIS_ASSUME(exp); \
|
||||
}
|
||||
#define NV_CLOTH_ASSERT_WITH_MESSAGE(message, exp) \
|
||||
{ \
|
||||
static bool _ignore = false; \
|
||||
((void)((!!(exp)) || (!_ignore && ((*nv::cloth::GetNvClothAssertHandler())(message, __FILE__, __LINE__, _ignore), false)))); \
|
||||
PX_CODE_ANALYSIS_ASSUME(exp); \
|
||||
}
|
||||
#endif
|
||||
|
||||
//Profiler
|
||||
physx::PxProfilerCallback* GetNvClothProfiler(); //Only use internally
|
||||
#if PX_DEBUG || PX_CHECKED || PX_PROFILE
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
477
Source/ThirdParty/NvCloth/Cloth.h
vendored
Normal file
477
Source/ThirdParty/NvCloth/Cloth.h
vendored
Normal file
@@ -0,0 +1,477 @@
|
||||
// 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-2020 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;
|
||||
|
||||
/** \brief Adjust the position and rotation of the cloth without affecting the dynamics (to call after a world origin shift, for example).
|
||||
The velocity will be set to zero this frame, unless setTranslation/setRotation is called with a different value after this function is called.
|
||||
The correct order to use this is:
|
||||
\code
|
||||
cloth->teleportToLocation(pos, rot);
|
||||
pos += velocity * dt;
|
||||
rot += 0.5 * angularVelocity * rot * dt;
|
||||
cloth->setTranslation(pos);
|
||||
cloth->setRotation(rot);
|
||||
\endcode
|
||||
*/
|
||||
virtual void teleportToLocation(const physx::PxVec3& translation, const physx::PxQuat& rotation) = 0;
|
||||
|
||||
/** \brief Don't recalculate the velocity based on the values provided by setTranslation and setRotation for one frame (so it acts as if the velocity was the same as last frame).
|
||||
This is useful when the cloth is moving while teleported, but the integration of the cloth position for that frame is already included in the teleport.
|
||||
Example:
|
||||
\code
|
||||
pos += velocity * dt;
|
||||
rot += 0.5 * angularVelocity * rot * dt;
|
||||
cloth->teleportToLocation(pos, rot);
|
||||
cloth->ignoreVelocityDiscontinuity();
|
||||
\endcode
|
||||
*/
|
||||
virtual void ignoreVelocityDiscontinuity() = 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;
|
||||
virtual void setSpheres(Range<const physx::PxVec4> startSpheres, Range<const physx::PxVec4> targetSpheres) = 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;
|
||||
virtual void setPlanes(Range<const physx::PxVec4> startPlanes, Range<const physx::PxVec4> targetPlanes) = 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 triangles.
|
||||
*/
|
||||
virtual void setTriangles(Range<const physx::PxVec3> triangles, uint32_t first, uint32_t last) = 0;
|
||||
virtual void setTriangles(Range<const physx::PxVec3> startTriangles, Range<const physx::PxVec3> targetTriangles, 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;
|
||||
/** /brief Sets the fluid density used for air drag/lift calculations. */
|
||||
virtual void setFluidDensity(float) = 0;
|
||||
///Returns value set with setFluidDensity().
|
||||
virtual float getFluidDensity() 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;
|
||||
|
||||
/** \brief Set self collision indices.
|
||||
Each index in the range indicates that the particle at that index should be used for self collision.
|
||||
If set to an empty range (default) all particles will be used.
|
||||
*/
|
||||
virtual void setSelfCollisionIndices(Range<const uint32_t>) = 0;
|
||||
///Returns the number of self collision indices set.
|
||||
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
|
||||
84
Source/ThirdParty/NvCloth/DxContextManagerCallback.h
vendored
Normal file
84
Source/ThirdParty/NvCloth/DxContextManagerCallback.h
vendored
Normal file
@@ -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-2020 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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
130
Source/ThirdParty/NvCloth/Fabric.h
vendored
Normal file
130
Source/ThirdParty/NvCloth/Fabric.h
vendored
Normal file
@@ -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-2020 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 "NvCloth/ps/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()
|
||||
{
|
||||
ps::atomicIncrement(&mRefCount);
|
||||
NV_CLOTH_ASSERT(mRefCount > 0);
|
||||
}
|
||||
|
||||
/// Returns true if the object is destroyed
|
||||
bool decRefCount()
|
||||
{
|
||||
NV_CLOTH_ASSERT(mRefCount > 0);
|
||||
int result = ps::atomicDecrement(&mRefCount);
|
||||
if (result == 0)
|
||||
{
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t mRefCount;
|
||||
};
|
||||
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
194
Source/ThirdParty/NvCloth/Factory.h
vendored
Normal file
194
Source/ThirdParty/NvCloth/Factory.h
vendored
Normal file
@@ -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-2020 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
|
||||
69
Source/ThirdParty/NvCloth/License.txt
vendored
Normal file
69
Source/ThirdParty/NvCloth/License.txt
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
Nvidia Source Code License (1-Way Commercial)
|
||||
|
||||
1. Definitions
|
||||
|
||||
"Licensor" means any person or entity that distributes its Work. "Software"
|
||||
means the original work of authorship made available under this License. "Work"
|
||||
means the Software and any additions to or derivative works of the Software that
|
||||
are made available under this License. The terms "reproduce," "reproduction,"
|
||||
"derivative works," and "distribution" have the meaning as provided under U.S.
|
||||
copyright law; provided, however, that for the purposes of this License,
|
||||
derivative works shall not include works that remain separable from, or merely
|
||||
link (or bind by name) to the interfaces of, the Work. Works, including the
|
||||
Software, are "made available" under this License by including in or with the
|
||||
Work either (a) a copyright notice referencing the applicability of this License
|
||||
to the Work, or (b) a copy of this License.
|
||||
|
||||
2. License Grants
|
||||
|
||||
2.1 Copyright Grant. Subject to the terms and conditions of this License, each
|
||||
Licensor grants to you a perpetual, worldwide, non-exclusive, royalty-free,
|
||||
copyright license to reproduce, prepare derivative works of, publicly display,
|
||||
publicly perform, sublicense and distribute its Work and any resulting
|
||||
derivative works in any form.
|
||||
|
||||
3. Limitations
|
||||
|
||||
3.1 Redistribution. You may reproduce or distribute the Work only if (a) you do
|
||||
so under this License, (b) you include a complete copy of this License with your
|
||||
distribution, and (c) you retain without modification any copyright, patent,
|
||||
trademark, or attribution notices that are present in the Work.
|
||||
|
||||
3.2 Derivative Works. You may specify that additional or different terms apply
|
||||
to the use, reproduction, and distribution of your derivative works of the Work
|
||||
("Your Terms") only if you identify the specific derivative works that are
|
||||
subject to Your Terms. Notwithstanding Your Terms, this License (including the
|
||||
redistribution requirements in Section 3.1) will continue to apply to the Work
|
||||
itself.
|
||||
|
||||
3.3 Patent Claims. If you bring or threaten to bring a patent claim against any
|
||||
Licensor (including any claim, cross-claim or counterclaim in a lawsuit) to
|
||||
enforce any patents that you allege are infringed by any Work, then your rights
|
||||
under this License from such Licensor (including the grant in Section 2.1) will
|
||||
terminate immediately.
|
||||
|
||||
3.4 Trademarks. This License does not grant any rights to use any Licensor's or
|
||||
its affiliates' names, logos, or trademarks, except as necessary to reproduce
|
||||
the notices described in this License.
|
||||
|
||||
3.5 Termination. If you violate any term of this License, then your rights under
|
||||
this License (including the grant in Section 2.1) will terminate
|
||||
immediately.
|
||||
|
||||
4. Disclaimer of Warranty.
|
||||
|
||||
THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT.
|
||||
YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER THIS LICENSE.
|
||||
|
||||
5. Limitation of Liability.
|
||||
|
||||
EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL THEORY,
|
||||
WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE SHALL ANY
|
||||
LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL,
|
||||
INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATED TO THIS LICENSE,
|
||||
THE USE OR INABILITY TO USE THE WORK (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS OR DATA, COMPUTER FAILURE OR
|
||||
MALFUNCTION, OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR
|
||||
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
48
Source/ThirdParty/NvCloth/NvCloth.Build.cs
vendored
Normal file
48
Source/ThirdParty/NvCloth/NvCloth.Build.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.IO;
|
||||
using Flax.Build;
|
||||
using Flax.Build.NativeCpp;
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com/NVIDIAGameWorks/NvCloth
|
||||
/// </summary>
|
||||
public class NvCloth : DepsModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
|
||||
LicenseType = LicenseTypes.Custom;
|
||||
LicenseFilePath = "License.txt";
|
||||
|
||||
// Merge third-party modules into engine binary
|
||||
BinaryModuleName = "FlaxEngine";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Setup(BuildOptions options)
|
||||
{
|
||||
base.Setup(options);
|
||||
|
||||
options.PublicDefinitions.Add("WITH_CLOTH");
|
||||
options.PublicDefinitions.Add("NV_CLOTH_IMPORT=");
|
||||
|
||||
var libName = "NvCloth_x64";
|
||||
switch (options.Platform.Target)
|
||||
{
|
||||
case TargetPlatform.PS4:
|
||||
case TargetPlatform.PS5:
|
||||
case TargetPlatform.Android:
|
||||
libName = "NvCloth";
|
||||
break;
|
||||
case TargetPlatform.Switch:
|
||||
libName = "NvCloth";
|
||||
options.PublicIncludePaths.Add(Path.Combine(Globals.EngineRoot, "Source/Platforms/Switch/Binaries/Data/PhysX/physx/include"));
|
||||
options.PublicIncludePaths.Add(Path.Combine(Globals.EngineRoot, "Source/Platforms/Switch/Binaries/Data/PhysX/physx/include/foundation"));
|
||||
break;
|
||||
}
|
||||
AddLib(options, options.DepsFolder, libName);
|
||||
}
|
||||
}
|
||||
225
Source/ThirdParty/NvCloth/NvClothExt/ClothFabricCooker.h
vendored
Normal file
225
Source/ThirdParty/NvCloth/NvClothExt/ClothFabricCooker.h
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef NV_CLOTH_EXTENSIONS_CLOTH_FABRIC_COOKER_H
|
||||
#define NV_CLOTH_EXTENSIONS_CLOTH_FABRIC_COOKER_H
|
||||
|
||||
/** \addtogroup extensions
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "ClothMeshDesc.h"
|
||||
#include "NvCloth/Fabric.h"
|
||||
#include "NvCloth/Factory.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
namespace cloth
|
||||
{
|
||||
|
||||
struct CookedData
|
||||
{
|
||||
uint32_t mNumParticles;
|
||||
Range<const uint32_t> mPhaseIndices;
|
||||
Range<const int32_t> mPhaseTypes;
|
||||
Range<const uint32_t> mSets;
|
||||
Range<const float> mRestvalues;
|
||||
Range<const float> mStiffnessValues;
|
||||
Range<const uint32_t> mIndices;
|
||||
Range<const uint32_t> mAnchors;
|
||||
Range<const float> mTetherLengths;
|
||||
Range<const uint32_t> mTriangles;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Describe type of phase in cloth fabric.
|
||||
\see Fabric for an explanation of concepts on phase and set.
|
||||
*/
|
||||
struct ClothFabricPhaseType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
eINVALID, //!< invalid type
|
||||
eVERTICAL, //!< resists stretching or compression, usually along the gravity
|
||||
eHORIZONTAL, //!< resists stretching or compression, perpendicular to the gravity
|
||||
eBENDING, //!< resists out-of-plane bending in angle-based formulation
|
||||
eSHEARING, //!< resists in-plane shearing along (typically) diagonal edges,
|
||||
eCOUNT // internal use only
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
\brief References a set of constraints that can be solved in parallel.
|
||||
\see Fabric for an explanation of the concepts on phase and set.
|
||||
*/
|
||||
struct ClothFabricPhase
|
||||
{
|
||||
ClothFabricPhase(ClothFabricPhaseType::Enum type =
|
||||
ClothFabricPhaseType::eINVALID, physx::PxU32 index = 0);
|
||||
|
||||
/**
|
||||
\brief Type of constraints to solve.
|
||||
*/
|
||||
ClothFabricPhaseType::Enum phaseType;
|
||||
|
||||
/**
|
||||
\brief Index of the set that contains the particle indices.
|
||||
*/
|
||||
physx::PxU32 setIndex;
|
||||
};
|
||||
|
||||
PX_INLINE ClothFabricPhase::ClothFabricPhase(
|
||||
ClothFabricPhaseType::Enum type, physx::PxU32 index)
|
||||
: phaseType(type)
|
||||
, setIndex(index)
|
||||
{}
|
||||
|
||||
/**
|
||||
\brief References all the data required to create a fabric.
|
||||
\see ClothFabricCooker.getDescriptor()
|
||||
*/
|
||||
class ClothFabricDesc
|
||||
{
|
||||
public:
|
||||
/** \brief The number of particles needed when creating a PxCloth instance from the fabric. */
|
||||
physx::PxU32 nbParticles;
|
||||
|
||||
/** \brief The number of solver phases. */
|
||||
physx::PxU32 nbPhases;
|
||||
/** \brief Array defining which constraints to solve each phase. See #Fabric.getPhases(). */
|
||||
const ClothFabricPhase* phases;
|
||||
|
||||
/** \brief The number of sets in the fabric. */
|
||||
physx::PxU32 nbSets;
|
||||
/** \brief Array with an index per set which points one entry beyond the last constraint of the set. See #Fabric.getSets(). */
|
||||
const physx::PxU32* sets;
|
||||
|
||||
/** \brief Array of particle indices which specifies the pair of constrained vertices. See #Fabric.getParticleIndices(). */
|
||||
const physx::PxU32* indices;
|
||||
/** \brief Array of rest values for each constraint. See #Fabric.getRestvalues(). */
|
||||
const physx::PxReal* restvalues;
|
||||
|
||||
/** \brief Size of tetherAnchors and tetherLengths arrays, needs to be multiple of nbParticles. */
|
||||
physx::PxU32 nbTethers;
|
||||
/** \brief Array of particle indices specifying the tether anchors. See #Fabric.getTetherAnchors(). */
|
||||
const physx::PxU32* tetherAnchors;
|
||||
/** \brief Array of rest distance between tethered particle pairs. See #Fabric.getTetherLengths(). */
|
||||
const physx::PxReal* tetherLengths;
|
||||
|
||||
physx::PxU32 nbTriangles;
|
||||
const physx::PxU32* triangles;
|
||||
|
||||
/**
|
||||
\brief constructor sets to default.
|
||||
*/
|
||||
PX_INLINE ClothFabricDesc();
|
||||
|
||||
/**
|
||||
\brief (re)sets the structure to the default.
|
||||
*/
|
||||
PX_INLINE void setToDefault();
|
||||
|
||||
/**
|
||||
\brief Returns true if the descriptor is valid.
|
||||
\return True if the current settings are valid
|
||||
*/
|
||||
PX_INLINE bool isValid() const;
|
||||
};
|
||||
|
||||
PX_INLINE ClothFabricDesc::ClothFabricDesc()
|
||||
{
|
||||
setToDefault();
|
||||
}
|
||||
|
||||
PX_INLINE void ClothFabricDesc::setToDefault()
|
||||
{
|
||||
memset(this, 0, sizeof(ClothFabricDesc));
|
||||
}
|
||||
|
||||
PX_INLINE bool ClothFabricDesc::isValid() const
|
||||
{
|
||||
return nbParticles && nbPhases && phases && restvalues && nbSets
|
||||
&& sets && indices && (!nbTethers || (tetherAnchors && tetherLengths))
|
||||
&& (!nbTriangles || triangles);
|
||||
}
|
||||
|
||||
///Use NvClothCreateFabricCooker() to create an implemented instance
|
||||
class NV_CLOTH_IMPORT ClothFabricCooker : public UserAllocated
|
||||
{
|
||||
public:
|
||||
virtual ~ClothFabricCooker(){}
|
||||
|
||||
/**
|
||||
\brief Cooks a triangle mesh to a ClothFabricDesc.
|
||||
\param desc The cloth mesh descriptor on which the generation of the cooked mesh depends.
|
||||
\param gravity A normalized vector which specifies the direction of gravity.
|
||||
This information allows the cooker to generate a fabric with higher quality simulation behavior.
|
||||
The gravity vector should point in the direction gravity will be pulling towards in the most common situation/at rest.
|
||||
e.g. For flags it might be beneficial to set the gravity horizontal if they are cooked in landscape orientation, as a flag will hang in portrait orientation at rest.
|
||||
\param useGeodesicTether A flag to indicate whether to compute geodesic distance for tether constraints.
|
||||
\note The geodesic option for tether only works for manifold input. For non-manifold input, a simple Euclidean distance will be used.
|
||||
For more detailed cooker status for such cases, try running ClothGeodesicTetherCooker directly.
|
||||
*/
|
||||
virtual bool cook(const ClothMeshDesc& desc, physx::PxVec3 gravity, bool useGeodesicTether = true) = 0;
|
||||
|
||||
/** \brief Returns fabric cooked data for creating fabrics. */
|
||||
virtual CookedData getCookedData() const = 0;
|
||||
|
||||
/** \brief Returns the fabric descriptor to create the fabric. */
|
||||
virtual ClothFabricDesc getDescriptor() const = 0;
|
||||
|
||||
/** \brief Saves the fabric data to a platform and version dependent stream. */
|
||||
virtual void save(physx::PxOutputStream& stream, bool platformMismatch) const = 0;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
|
||||
NV_CLOTH_API(nv::cloth::ClothFabricCooker*) NvClothCreateFabricCooker();
|
||||
|
||||
/**
|
||||
\brief Cooks a triangle mesh to a Fabric.
|
||||
|
||||
\param factory The factory for which the cloth is cooked.
|
||||
\param desc The cloth mesh descriptor on which the generation of the cooked mesh depends.
|
||||
\param gravity A normalized vector which specifies the direction of gravity.
|
||||
This information allows the cooker to generate a fabric with higher quality simulation behavior.
|
||||
\param phaseTypes Optional array where phase type information can be writen to.
|
||||
\param useGeodesicTether A flag to indicate whether to compute geodesic distance for tether constraints.
|
||||
\return The created cloth fabric, or NULL if creation failed.
|
||||
*/
|
||||
NV_CLOTH_API(nv::cloth::Fabric*) NvClothCookFabricFromMesh(nv::cloth::Factory* factory,
|
||||
const nv::cloth::ClothMeshDesc& desc, const float gravity[3],
|
||||
nv::cloth::Vector<int32_t>::Type* phaseTypes = nullptr, bool useGeodesicTether = true);
|
||||
|
||||
#endif // NV_CLOTH_EXTENSIONS_CLOTH_FABRIC_COOKER_H
|
||||
211
Source/ThirdParty/NvCloth/NvClothExt/ClothMeshDesc.h
vendored
Normal file
211
Source/ThirdParty/NvCloth/NvClothExt/ClothMeshDesc.h
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef NV_CLOTH_EXTENSIONS_CLOTHMESHDESC
|
||||
#define NV_CLOTH_EXTENSIONS_CLOTHMESHDESC
|
||||
/** \addtogroup extensions
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
namespace cloth
|
||||
{
|
||||
|
||||
struct StridedData
|
||||
{
|
||||
/**
|
||||
\brief The offset in bytes between consecutive samples in the data.
|
||||
|
||||
<b>Default:</b> 0
|
||||
*/
|
||||
physx::PxU32 stride;
|
||||
const void* data;
|
||||
|
||||
StridedData() : stride( 0 ), data( NULL ) {}
|
||||
|
||||
template<typename TDataType>
|
||||
PX_INLINE const TDataType& at( physx::PxU32 idx ) const
|
||||
{
|
||||
physx::PxU32 theStride( stride );
|
||||
if ( theStride == 0 )
|
||||
theStride = sizeof( TDataType );
|
||||
physx::PxU32 offset( theStride * idx );
|
||||
return *(reinterpret_cast<const TDataType*>( reinterpret_cast< const physx::PxU8* >( data ) + offset ));
|
||||
}
|
||||
};
|
||||
|
||||
struct BoundedData : public StridedData
|
||||
{
|
||||
physx::PxU32 count;
|
||||
BoundedData() : count( 0 ) {}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Enum with flag values to be used in ClothMeshDesc.
|
||||
*/
|
||||
struct MeshFlag
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
e16_BIT_INDICES = (1<<1) //!< Denotes the use of 16-bit vertex indices
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Descriptor class for a cloth mesh.
|
||||
*/
|
||||
class ClothMeshDesc
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
\brief Pointer to first vertex point.
|
||||
*/
|
||||
BoundedData points;
|
||||
|
||||
/**
|
||||
\brief Pointer to first stiffness value in stiffnes per vertex array. empty if unused.
|
||||
*/
|
||||
BoundedData pointsStiffness;
|
||||
|
||||
/**
|
||||
\brief Determines whether particle is simulated or static.
|
||||
A positive value denotes that the particle is being simulated, zero denotes a static particle.
|
||||
This data is used to generate tether and zero stretch constraints.
|
||||
If invMasses.data is null, all particles are assumed to be simulated
|
||||
and no tether and zero stretch constraints are being generated.
|
||||
*/
|
||||
BoundedData invMasses;
|
||||
|
||||
/**
|
||||
\brief Pointer to the first triangle.
|
||||
|
||||
These are triplets of 0 based indices:
|
||||
vert0 vert1 vert2
|
||||
vert0 vert1 vert2
|
||||
vert0 vert1 vert2
|
||||
...
|
||||
|
||||
where vert* is either a 32 or 16 bit unsigned integer. There are a total of 3*count indices.
|
||||
The stride determines the byte offset to the next index triple.
|
||||
|
||||
This is declared as a void pointer because it is actually either an physx::PxU16 or a physx::PxU32 pointer.
|
||||
*/
|
||||
BoundedData triangles;
|
||||
|
||||
/**
|
||||
\brief Pointer to the first quad.
|
||||
|
||||
These are quadruples of 0 based indices:
|
||||
vert0 vert1 vert2 vert3
|
||||
vert0 vert1 vert2 vert3
|
||||
vert0 vert1 vert2 vert3
|
||||
...
|
||||
|
||||
where vert* is either a 32 or 16 bit unsigned integer. There are a total of 4*count indices.
|
||||
The stride determines the byte offset to the next index quadruple.
|
||||
|
||||
This is declared as a void pointer because it is actually either an physx::PxU16 or a physx::PxU32 pointer.
|
||||
*/
|
||||
BoundedData quads;
|
||||
|
||||
/**
|
||||
\brief Flags bits, combined from values of the enum ::MeshFlag
|
||||
*/
|
||||
unsigned int flags;
|
||||
|
||||
/**
|
||||
\brief constructor sets to default.
|
||||
*/
|
||||
PX_INLINE ClothMeshDesc();
|
||||
/**
|
||||
\brief (re)sets the structure to the default.
|
||||
*/
|
||||
PX_INLINE void setToDefault();
|
||||
/**
|
||||
\brief Returns true if the descriptor is valid.
|
||||
\return True if the current settings are valid
|
||||
*/
|
||||
PX_INLINE bool isValid() const;
|
||||
};
|
||||
|
||||
PX_INLINE ClothMeshDesc::ClothMeshDesc()
|
||||
{
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
PX_INLINE void ClothMeshDesc::setToDefault()
|
||||
{
|
||||
*this = ClothMeshDesc();
|
||||
}
|
||||
|
||||
PX_INLINE bool ClothMeshDesc::isValid() const
|
||||
{
|
||||
if (points.count < 3) // at least 1 triangle
|
||||
return false;
|
||||
if ((pointsStiffness.count != points.count) && pointsStiffness.count != 0)
|
||||
return false; // either all or none of the points can have stiffness information
|
||||
if (points.count > 0xffff && flags & MeshFlag::e16_BIT_INDICES)
|
||||
return false;
|
||||
if (!points.data)
|
||||
return false;
|
||||
if (points.stride < sizeof(physx::PxVec3)) // should be at least one point
|
||||
return false;
|
||||
|
||||
if (invMasses.data && invMasses.stride < sizeof(float))
|
||||
return false;
|
||||
if (invMasses.data && invMasses.count != points.count)
|
||||
return false;
|
||||
|
||||
if (!triangles.count && !quads.count) // no support for non-indexed mesh
|
||||
return false;
|
||||
if (triangles.count && !triangles.data)
|
||||
return false;
|
||||
if (quads.count && !quads.data)
|
||||
return false;
|
||||
|
||||
physx::PxU32 indexSize = (flags & MeshFlag::e16_BIT_INDICES) ? sizeof(physx::PxU16) : sizeof(physx::PxU32);
|
||||
if (triangles.count && triangles.stride < indexSize*3)
|
||||
return false;
|
||||
if (quads.count && quads.stride < indexSize*4)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
78
Source/ThirdParty/NvCloth/NvClothExt/ClothMeshQuadifier.h
vendored
Normal file
78
Source/ThirdParty/NvCloth/NvClothExt/ClothMeshQuadifier.h
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef NV_CLOTH_EXTENSIONS_CLOTH_EDGE_QUADIFIER_H
|
||||
#define NV_CLOTH_EXTENSIONS_CLOTH_EDGE_QUADIFIER_H
|
||||
|
||||
/** \addtogroup extensions
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "ClothMeshDesc.h"
|
||||
#include "NvCloth/Callbacks.h"
|
||||
#include "NvCloth/Allocator.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
namespace cloth
|
||||
{
|
||||
|
||||
class ClothMeshQuadifier : public UserAllocated
|
||||
{
|
||||
public:
|
||||
virtual ~ClothMeshQuadifier(){}
|
||||
|
||||
/**
|
||||
\brief Convert triangles of ClothMeshDesc to quads.
|
||||
\details In NvCloth, quad dominant mesh representations are preferable to pre-triangulated versions.
|
||||
In cases where the mesh has been already triangulated, this class provides a meachanism to
|
||||
convert (quadify) some triangles back to quad representations.
|
||||
\see ClothFabricCooker
|
||||
\param desc The cloth mesh descriptor prepared for cooking
|
||||
*/
|
||||
virtual bool quadify(const ClothMeshDesc& desc) = 0;
|
||||
|
||||
/**
|
||||
\brief Returns a mesh descriptor with some triangle pairs converted to quads.
|
||||
\note The returned descriptor is valid only within the lifespan of ClothMeshQuadifier class.
|
||||
*/
|
||||
|
||||
virtual ClothMeshDesc getDescriptor() const = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
NV_CLOTH_API(nv::cloth::ClothMeshQuadifier*) NvClothCreateMeshQuadifier();
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif // NV_CLOTH_EXTENSIONS_CLOTH_EDGE_QUADIFIER_H
|
||||
94
Source/ThirdParty/NvCloth/NvClothExt/ClothTetherCooker.h
vendored
Normal file
94
Source/ThirdParty/NvCloth/NvClothExt/ClothTetherCooker.h
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef NV_CLOTH_EXTENSIONS_CLOTH_TETHER_COOKER_H
|
||||
#define NV_CLOTH_EXTENSIONS_CLOTH_TETHER_COOKER_H
|
||||
|
||||
/** \addtogroup extensions
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "ClothMeshDesc.h"
|
||||
#include "NvCloth/Allocator.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
namespace cloth
|
||||
{
|
||||
|
||||
class ClothTetherCooker : public UserAllocated
|
||||
{
|
||||
public:
|
||||
virtual ~ClothTetherCooker(){}
|
||||
|
||||
/**
|
||||
\brief Compute tether data from ClothMeshDesc with simple distance measure.
|
||||
\details The tether constraint in NvCloth requires rest distance and anchor index to be precomputed during cooking time.
|
||||
This cooker computes a simple Euclidean distance to closest anchor point.
|
||||
The Euclidean distance measure works reasonably for flat cloth and flags and computation time is very fast.
|
||||
With this cooker, there is only one tether anchor point per particle.
|
||||
\see ClothTetherGeodesicCooker for more accurate distance estimation.
|
||||
\param desc The cloth mesh descriptor prepared for cooking
|
||||
*/
|
||||
virtual bool cook(const ClothMeshDesc &desc) = 0;
|
||||
|
||||
/**
|
||||
\brief Returns cooker status
|
||||
\details This function returns cooker status after cooker computation is done.
|
||||
A non-zero return value indicates a failure.
|
||||
*/
|
||||
virtual uint32_t getCookerStatus() const = 0; //From APEX
|
||||
|
||||
/**
|
||||
\brief Returns number of tether anchors per particle
|
||||
\note Returned number indicates the maximum anchors.
|
||||
If some particles are assigned fewer anchors, the anchor indices will be physx::PxU32(-1)
|
||||
\note If there is no attached point in the input mesh descriptor, this will return 0 and no tether data will be generated.
|
||||
*/
|
||||
virtual physx::PxU32 getNbTethersPerParticle() const = 0;
|
||||
|
||||
/**
|
||||
\brief Returns computed tether data.
|
||||
\details This function returns anchor indices for each particle as well as desired distance between the tether anchor and the particle.
|
||||
The user buffers should be at least as large as number of particles.
|
||||
*/
|
||||
virtual void getTetherData(physx::PxU32* userTetherAnchors, physx::PxReal* userTetherLengths) const = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
NV_CLOTH_API(nv::cloth::ClothTetherCooker*) NvClothCreateSimpleTetherCooker();
|
||||
NV_CLOTH_API(nv::cloth::ClothTetherCooker*) NvClothCreateGeodesicTetherCooker();
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif // NV_CLOTH_EXTENSIONS_CLOTH_TETHER_COOKER_H
|
||||
62
Source/ThirdParty/NvCloth/PhaseConfig.h
vendored
Normal file
62
Source/ThirdParty/NvCloth/PhaseConfig.h
vendored
Normal file
@@ -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-2020 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
|
||||
155
Source/ThirdParty/NvCloth/Range.h
vendored
Normal file
155
Source/ThirdParty/NvCloth/Range.h
vendored
Normal file
@@ -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-2020 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
|
||||
111
Source/ThirdParty/NvCloth/Solver.h
vendored
Normal file
111
Source/ThirdParty/NvCloth/Solver.h
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// 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-2020 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"
|
||||
#include "NvCloth/Range.h"
|
||||
#include "NvCloth/ps/PsArray.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.
|
||||
virtual void addCloth(Cloth* cloth) = 0;
|
||||
|
||||
/// Adds an array of cloth objects.
|
||||
virtual void addCloths(Range<Cloth*> cloths) = 0;
|
||||
|
||||
/// Removes cloth object.
|
||||
virtual void removeCloth(Cloth* cloth) = 0;
|
||||
|
||||
/// Returns the numer of cloths added to the solver.
|
||||
virtual int getNumCloths() const = 0;
|
||||
|
||||
/// Returns the pointer to the first cloth added to the solver
|
||||
virtual Cloth * const * getClothList() const = 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
|
||||
/// Note that using intercollision with more than 32 cloths added to the solver will cause undefined behavior
|
||||
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
|
||||
75
Source/ThirdParty/NvCloth/ps/Ps.h
vendored
Normal file
75
Source/ThirdParty/NvCloth/ps/Ps.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PS_H
|
||||
#define PSFOUNDATION_PS_H
|
||||
|
||||
/*! \file top level include file for shared foundation */
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
/**
|
||||
Platform specific defines
|
||||
*/
|
||||
#if PX_WINDOWS_FAMILY || PX_XBOXONE
|
||||
#pragma intrinsic(memcmp)
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#pragma intrinsic(abs)
|
||||
#pragma intrinsic(labs)
|
||||
#endif
|
||||
|
||||
// An expression that should expand to nothing in non PX_CHECKED builds.
|
||||
// We currently use this only for tagging the purpose of containers for memory use tracking.
|
||||
#if PX_CHECKED
|
||||
#define PX_DEBUG_EXP(x) (x)
|
||||
#else
|
||||
#define PX_DEBUG_EXP(x)
|
||||
#endif
|
||||
|
||||
#define PX_SIGN_BITMASK 0x80000000
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
// Int-as-bool type - has some uses for efficiency and with SIMD
|
||||
typedef int IntBool;
|
||||
static const IntBool IntFalse = 0;
|
||||
static const IntBool IntTrue = 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PS_H
|
||||
93
Source/ThirdParty/NvCloth/ps/PsAlignedMalloc.h
vendored
Normal file
93
Source/ThirdParty/NvCloth/ps/PsAlignedMalloc.h
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSALIGNEDMALLOC_H
|
||||
#define PSFOUNDATION_PSALIGNEDMALLOC_H
|
||||
|
||||
#include "PsUserAllocated.h"
|
||||
|
||||
/*!
|
||||
Allocate aligned memory.
|
||||
Alignment must be a power of 2!
|
||||
-- should be templated by a base allocator
|
||||
*/
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
/**
|
||||
Allocator, which is used to access the global PxAllocatorCallback instance
|
||||
(used for dynamic data types template instantiation), which can align memory
|
||||
*/
|
||||
|
||||
// SCS: AlignedMalloc with 3 params not found, seems not used on PC either
|
||||
// disabled for now to avoid GCC error
|
||||
|
||||
template <uint32_t N, typename BaseAllocator = NonTrackingAllocator>
|
||||
class AlignedAllocator : public BaseAllocator
|
||||
{
|
||||
public:
|
||||
AlignedAllocator(const BaseAllocator& base = BaseAllocator()) : BaseAllocator(base)
|
||||
{
|
||||
}
|
||||
|
||||
void* allocate(size_t size, const char* file, int line)
|
||||
{
|
||||
size_t pad = N - 1 + sizeof(size_t); // store offset for delete.
|
||||
uint8_t* base = reinterpret_cast<uint8_t*>(BaseAllocator::allocate(size + pad, file, line));
|
||||
if(!base)
|
||||
return NULL;
|
||||
|
||||
uint8_t* ptr = reinterpret_cast<uint8_t*>(size_t(base + pad) & ~(size_t(N) - 1)); // aligned pointer, ensuring N
|
||||
// is a size_t
|
||||
// wide mask
|
||||
reinterpret_cast<size_t*>(ptr)[-1] = size_t(ptr - base); // store offset
|
||||
|
||||
return ptr;
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
if(ptr == NULL)
|
||||
return;
|
||||
|
||||
uint8_t* base = reinterpret_cast<uint8_t*>(ptr) - reinterpret_cast<size_t*>(ptr)[-1];
|
||||
BaseAllocator::deallocate(base);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSALIGNEDMALLOC_H
|
||||
351
Source/ThirdParty/NvCloth/ps/PsAllocator.h
vendored
Normal file
351
Source/ThirdParty/NvCloth/ps/PsAllocator.h
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSALLOCATOR_H
|
||||
#define PSFOUNDATION_PSALLOCATOR_H
|
||||
|
||||
#include "foundation/PxAllocatorCallback.h"
|
||||
//#include "foundation/PxFoundation.h"
|
||||
#include "Ps.h"
|
||||
#include "../Callbacks.h"
|
||||
|
||||
#if(PX_WINDOWS_FAMILY || PX_XBOXONE)
|
||||
#include <exception>
|
||||
#if PX_VC >= 16
|
||||
#include <typeinfo>
|
||||
#else
|
||||
#include <typeinfo.h>
|
||||
#endif
|
||||
#endif
|
||||
#if(PX_APPLE_FAMILY)
|
||||
#include <typeinfo>
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
|
||||
// Allocation macros going through user allocator
|
||||
#define PX_ALLOC(n, name) nv::cloth::NonTrackingAllocator().allocate(n, __FILE__, __LINE__)
|
||||
#define PX_ALLOC_TEMP(n, name) PX_ALLOC(n, name)
|
||||
#define PX_FREE(x) nv::cloth::NonTrackingAllocator().deallocate(x)
|
||||
#define PX_FREE_AND_RESET(x) \
|
||||
{ \
|
||||
PX_FREE(x); \
|
||||
x = 0; \
|
||||
}
|
||||
|
||||
// The following macros support plain-old-types and classes derived from UserAllocated.
|
||||
#define PX_NEW(T) new (nv::cloth::ReflectionAllocator<T>(), __FILE__, __LINE__) T
|
||||
#define PX_NEW_TEMP(T) PX_NEW(T)
|
||||
#define PX_DELETE(x) delete x
|
||||
#define PX_DELETE_AND_RESET(x) \
|
||||
{ \
|
||||
PX_DELETE(x); \
|
||||
x = 0; \
|
||||
}
|
||||
#define PX_DELETE_POD(x) \
|
||||
{ \
|
||||
PX_FREE(x); \
|
||||
x = 0; \
|
||||
}
|
||||
#define PX_DELETE_ARRAY(x) \
|
||||
{ \
|
||||
PX_DELETE([] x); \
|
||||
x = 0; \
|
||||
}
|
||||
|
||||
// aligned allocation
|
||||
#define PX_ALIGNED16_ALLOC(n) nv::cloth::AlignedAllocator<16>().allocate(n, __FILE__, __LINE__)
|
||||
#define PX_ALIGNED16_FREE(x) nv::cloth::AlignedAllocator<16>().deallocate(x)
|
||||
|
||||
//! placement new macro to make it easy to spot bad use of 'new'
|
||||
#define PX_PLACEMENT_NEW(p, T) new (p) T
|
||||
|
||||
#if PX_DEBUG || PX_CHECKED
|
||||
#define PX_USE_NAMED_ALLOCATOR 1
|
||||
#else
|
||||
#define PX_USE_NAMED_ALLOCATOR 0
|
||||
#endif
|
||||
|
||||
// Don't use inline for alloca !!!
|
||||
#if PX_WINDOWS_FAMILY
|
||||
#include <malloc.h>
|
||||
#define PxAlloca(x) _alloca(x)
|
||||
#elif PX_LINUX || PX_ANDROID
|
||||
#include <malloc.h>
|
||||
#define PxAlloca(x) alloca(x)
|
||||
#elif PX_APPLE_FAMILY
|
||||
#include <alloca.h>
|
||||
#define PxAlloca(x) alloca(x)
|
||||
#elif PX_PS4 || PX_PS5
|
||||
#include <memory.h>
|
||||
#define PxAlloca(x) alloca(x)
|
||||
#elif PX_XBOXONE
|
||||
#include <malloc.h>
|
||||
#define PxAlloca(x) alloca(x)
|
||||
#elif PX_SWITCH
|
||||
#include <malloc.h>
|
||||
#define PxAlloca(x) alloca(x)
|
||||
#endif
|
||||
|
||||
#define PxAllocaAligned(x, alignment) ((size_t(PxAlloca(x + alignment)) + (alignment - 1)) & ~size_t(alignment - 1))
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
//NV_CLOTH_IMPORT PxAllocatorCallback& getAllocator();
|
||||
|
||||
/**
|
||||
Allocator used to access the global PxAllocatorCallback instance without providing additional information.
|
||||
*/
|
||||
|
||||
class NV_CLOTH_IMPORT Allocator
|
||||
{
|
||||
public:
|
||||
Allocator(const char* = 0)
|
||||
{
|
||||
}
|
||||
void* allocate(size_t size, const char* file, int line);
|
||||
void deallocate(void* ptr);
|
||||
};
|
||||
|
||||
/*
|
||||
* Bootstrap allocator using malloc/free.
|
||||
* Don't use unless your objects get allocated before foundation is initialized.
|
||||
*/
|
||||
class RawAllocator
|
||||
{
|
||||
public:
|
||||
RawAllocator(const char* = 0)
|
||||
{
|
||||
}
|
||||
void* allocate(size_t size, const char*, int)
|
||||
{
|
||||
// malloc returns valid pointer for size==0, no need to check
|
||||
return ::malloc(size);
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
// free(0) is guaranteed to have no side effect, no need to check
|
||||
::free(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocator that simply calls straight back to the application without tracking.
|
||||
* This is used by the heap (Foundation::mNamedAllocMap) that tracks allocations
|
||||
* because it needs to be able to grow as a result of an allocation.
|
||||
* Making the hash table re-entrant to deal with this may not make sense.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
\brief Virtual allocator callback used to provide run-time defined allocators to foundation types like Array or Bitmap.
|
||||
This is used by VirtualAllocator
|
||||
*/
|
||||
class VirtualAllocatorCallback
|
||||
{
|
||||
public:
|
||||
VirtualAllocatorCallback()
|
||||
{
|
||||
}
|
||||
virtual ~VirtualAllocatorCallback()
|
||||
{
|
||||
}
|
||||
virtual void* allocate(const size_t size, const char* file, const int line) = 0;
|
||||
virtual void deallocate(void* ptr) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
\brief Virtual allocator to be used by foundation types to provide run-time defined allocators.
|
||||
Due to the fact that Array extends its allocator, rather than contains a reference/pointer to it, the VirtualAllocator
|
||||
must
|
||||
be a concrete type containing a pointer to a virtual callback. The callback may not be available at instantiation time,
|
||||
therefore
|
||||
methods are provided to set the callback later.
|
||||
*/
|
||||
class VirtualAllocator
|
||||
{
|
||||
public:
|
||||
VirtualAllocator(VirtualAllocatorCallback* callback = NULL) : mCallback(callback)
|
||||
{
|
||||
}
|
||||
|
||||
void* allocate(const size_t size, const char* file, const int line)
|
||||
{
|
||||
NV_CLOTH_ASSERT(mCallback);
|
||||
if(size)
|
||||
return mCallback->allocate(size, file, line);
|
||||
return NULL;
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
NV_CLOTH_ASSERT(mCallback);
|
||||
if(ptr)
|
||||
mCallback->deallocate(ptr);
|
||||
}
|
||||
|
||||
void setCallback(VirtualAllocatorCallback* callback)
|
||||
{
|
||||
mCallback = callback;
|
||||
}
|
||||
VirtualAllocatorCallback* getCallback()
|
||||
{
|
||||
return mCallback;
|
||||
}
|
||||
|
||||
private:
|
||||
VirtualAllocatorCallback* mCallback;
|
||||
VirtualAllocator& operator=(const VirtualAllocator&);
|
||||
};
|
||||
|
||||
/**
|
||||
Allocator used to access the global PxAllocatorCallback instance using a static name derived from T.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
class ReflectionAllocator
|
||||
{
|
||||
static const char* getName()
|
||||
{
|
||||
if(true)
|
||||
return "<allocation names disabled>";
|
||||
#if PX_GCC_FAMILY
|
||||
return __PRETTY_FUNCTION__;
|
||||
#else
|
||||
// name() calls malloc(), raw_name() wouldn't
|
||||
return typeid(T).name();
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
ReflectionAllocator(const physx::PxEMPTY)
|
||||
{
|
||||
}
|
||||
ReflectionAllocator(const char* = 0)
|
||||
{
|
||||
}
|
||||
inline ReflectionAllocator(const ReflectionAllocator&)
|
||||
{
|
||||
}
|
||||
void* allocate(size_t size, const char* filename, int line)
|
||||
{
|
||||
return size ? GetNvClothAllocator()->allocate(size, getName(), filename, line) : 0;
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
if(ptr)
|
||||
GetNvClothAllocator()->deallocate(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct AllocatorTraits
|
||||
{
|
||||
typedef ReflectionAllocator<T> Type;
|
||||
};
|
||||
|
||||
// if you get a build error here, you are trying to PX_NEW a class
|
||||
// that is neither plain-old-type nor derived from UserAllocated
|
||||
template <typename T, typename X>
|
||||
union EnableIfPod
|
||||
{
|
||||
int i;
|
||||
T t;
|
||||
typedef X Type;
|
||||
};
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
// Global placement new for ReflectionAllocator templated by
|
||||
// plain-old-type. Allows using PX_NEW for pointers and built-in-types.
|
||||
//
|
||||
// ATTENTION: You need to use PX_DELETE_POD or PX_FREE to deallocate
|
||||
// memory, not PX_DELETE. PX_DELETE_POD redirects to PX_FREE.
|
||||
//
|
||||
// Rationale: PX_DELETE uses global operator delete(void*), which we dont' want to overload.
|
||||
// Any other definition of PX_DELETE couldn't support array syntax 'PX_DELETE([]a);'.
|
||||
// PX_DELETE_POD was preferred over PX_DELETE_ARRAY because it is used
|
||||
// less often and applies to both single instances and arrays.
|
||||
template <typename T>
|
||||
PX_INLINE void* operator new(size_t size, nv::cloth::ps::ReflectionAllocator<T> alloc, const char* fileName,
|
||||
typename nv::cloth::ps::EnableIfPod<T, int>::Type line)
|
||||
{
|
||||
return alloc.allocate(size, fileName, line);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PX_INLINE void* operator new [](size_t size, nv::cloth::ps::ReflectionAllocator<T> alloc, const char* fileName,
|
||||
typename nv::cloth::ps::EnableIfPod<T, int>::Type line)
|
||||
{ return alloc.allocate(size, fileName, line); }
|
||||
|
||||
// If construction after placement new throws, this placement delete is being called.
|
||||
template <typename T>
|
||||
PX_INLINE void operator delete(void* ptr, nv::cloth::ps::ReflectionAllocator<T> alloc, const char* fileName,
|
||||
typename nv::cloth::ps::EnableIfPod<T, int>::Type line)
|
||||
{
|
||||
PX_UNUSED(fileName);
|
||||
PX_UNUSED(line);
|
||||
|
||||
alloc.deallocate(ptr);
|
||||
}
|
||||
|
||||
// If construction after placement new throws, this placement delete is being called.
|
||||
template <typename T>
|
||||
PX_INLINE void operator delete [](void* ptr, nv::cloth::ps::ReflectionAllocator<T> alloc, const char* fileName,
|
||||
typename nv::cloth::ps::EnableIfPod<T, int>::Type line)
|
||||
{
|
||||
PX_UNUSED(fileName);
|
||||
PX_UNUSED(line);
|
||||
|
||||
alloc.deallocate(ptr);
|
||||
}
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSALLOCATOR_H
|
||||
726
Source/ThirdParty/NvCloth/ps/PsArray.h
vendored
Normal file
726
Source/ThirdParty/NvCloth/ps/PsArray.h
vendored
Normal file
@@ -0,0 +1,726 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSARRAY_H
|
||||
#define PSFOUNDATION_PSARRAY_H
|
||||
|
||||
#include "../Callbacks.h"
|
||||
#include "foundation/PxIntrinsics.h"
|
||||
#include "PsBasicTemplates.h"
|
||||
#include "NvCloth/ps/PsAllocator.h"
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
template <class Serializer>
|
||||
void exportArray(Serializer& stream, const void* data, uint32_t size, uint32_t sizeOfElement, uint32_t capacity);
|
||||
char* importArray(char* address, void** data, uint32_t size, uint32_t sizeOfElement, uint32_t capacity);
|
||||
|
||||
/*!
|
||||
An array is a sequential container.
|
||||
|
||||
Implementation note
|
||||
* entries between 0 and size are valid objects
|
||||
* we use inheritance to build this because the array is included inline in a lot
|
||||
of objects and we want the allocator to take no space if it's not stateful, which
|
||||
aggregation doesn't allow. Also, we want the metadata at the front for the inline
|
||||
case where the allocator contains some inline storage space
|
||||
*/
|
||||
template <class T, class Alloc = typename AllocatorTraits<T>::Type>
|
||||
class Array : protected Alloc
|
||||
{
|
||||
public:
|
||||
typedef T* Iterator;
|
||||
typedef const T* ConstIterator;
|
||||
|
||||
explicit Array(const physx::PxEMPTY v) : Alloc(v)
|
||||
{
|
||||
if(mData)
|
||||
mCapacity |= PX_SIGN_BITMASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
Default array constructor. Initialize an empty array
|
||||
*/
|
||||
PX_INLINE explicit Array(const Alloc& alloc = Alloc()) : Alloc(alloc), mData(0), mSize(0), mCapacity(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Initialize array with given capacity
|
||||
*/
|
||||
PX_INLINE explicit Array(uint32_t size, const T& a = T(), const Alloc& alloc = Alloc())
|
||||
: Alloc(alloc), mData(0), mSize(0), mCapacity(0)
|
||||
{
|
||||
resize(size, a);
|
||||
}
|
||||
|
||||
/*!
|
||||
Copy-constructor. Copy all entries from other array
|
||||
*/
|
||||
template <class A>
|
||||
PX_INLINE explicit Array(const Array<T, A>& other, const Alloc& alloc = Alloc())
|
||||
: Alloc(alloc)
|
||||
{
|
||||
copy(other);
|
||||
}
|
||||
|
||||
// This is necessary else the basic default copy constructor is used in the case of both arrays being of the same
|
||||
// template instance
|
||||
// The C++ standard clearly states that a template constructor is never a copy constructor [2]. In other words,
|
||||
// the presence of a template constructor does not suppress the implicit declaration of the copy constructor.
|
||||
// Also never make a copy constructor explicit, or copy-initialization* will no longer work. This is because
|
||||
// 'binding an rvalue to a const reference requires an accessible copy constructor' (http://gcc.gnu.org/bugs/)
|
||||
// *http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-assignment-initializ
|
||||
PX_INLINE Array(const Array& other, const Alloc& alloc = Alloc()) : Alloc(alloc)
|
||||
{
|
||||
copy(other);
|
||||
}
|
||||
|
||||
/*!
|
||||
Initialize array with given length
|
||||
*/
|
||||
PX_INLINE explicit Array(const T* first, const T* last, const Alloc& alloc = Alloc())
|
||||
: Alloc(alloc), mSize(last < first ? 0 : uint32_t(last - first)), mCapacity(mSize)
|
||||
{
|
||||
mData = allocate(mSize);
|
||||
copy(mData, mData + mSize, first);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructor
|
||||
*/
|
||||
PX_INLINE ~Array()
|
||||
{
|
||||
destroy(mData, mData + mSize);
|
||||
|
||||
if(capacity() && !isInUserMemory())
|
||||
deallocate(mData);
|
||||
}
|
||||
|
||||
/*!
|
||||
Assignment operator. Copy content (deep-copy)
|
||||
*/
|
||||
template <class A>
|
||||
PX_INLINE Array& operator=(const Array<T, A>& rhs)
|
||||
{
|
||||
if(&rhs == this)
|
||||
return *this;
|
||||
|
||||
clear();
|
||||
reserve(rhs.mSize);
|
||||
copy(mData, mData + rhs.mSize, rhs.mData);
|
||||
|
||||
mSize = rhs.mSize;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PX_INLINE Array& operator=(const Array& t) // Needs to be declared, see comment at copy-constructor
|
||||
{
|
||||
return operator=<Alloc>(t);
|
||||
}
|
||||
|
||||
/*!
|
||||
Array indexing operator.
|
||||
\param i
|
||||
The index of the element that will be returned.
|
||||
\return
|
||||
The element i in the array.
|
||||
*/
|
||||
PX_FORCE_INLINE const T& operator[](uint32_t i) const
|
||||
{
|
||||
NV_CLOTH_ASSERT(i < mSize);
|
||||
return mData[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
Array indexing operator.
|
||||
\param i
|
||||
The index of the element that will be returned.
|
||||
\return
|
||||
The element i in the array.
|
||||
*/
|
||||
PX_FORCE_INLINE T& operator[](uint32_t i)
|
||||
{
|
||||
NV_CLOTH_ASSERT(i < mSize);
|
||||
return mData[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a pointer to the initial element of the array.
|
||||
\return
|
||||
a pointer to the initial element of the array.
|
||||
*/
|
||||
PX_FORCE_INLINE ConstIterator begin() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE Iterator begin()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns an iterator beyond the last element of the array. Do not dereference.
|
||||
\return
|
||||
a pointer to the element beyond the last element of the array.
|
||||
*/
|
||||
|
||||
PX_FORCE_INLINE ConstIterator end() const
|
||||
{
|
||||
return mData + mSize;
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE Iterator end()
|
||||
{
|
||||
return mData + mSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a reference to the first element of the array. Undefined if the array is empty.
|
||||
\return a reference to the first element of the array
|
||||
*/
|
||||
|
||||
PX_FORCE_INLINE const T& front() const
|
||||
{
|
||||
NV_CLOTH_ASSERT(mSize);
|
||||
return mData[0];
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE T& front()
|
||||
{
|
||||
NV_CLOTH_ASSERT(mSize);
|
||||
return mData[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a reference to the last element of the array. Undefined if the array is empty
|
||||
\return a reference to the last element of the array
|
||||
*/
|
||||
|
||||
PX_FORCE_INLINE const T& back() const
|
||||
{
|
||||
NV_CLOTH_ASSERT(mSize);
|
||||
return mData[mSize - 1];
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE T& back()
|
||||
{
|
||||
NV_CLOTH_ASSERT(mSize);
|
||||
return mData[mSize - 1];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the number of entries in the array. This can, and probably will,
|
||||
differ from the array capacity.
|
||||
\return
|
||||
The number of of entries in the array.
|
||||
*/
|
||||
PX_FORCE_INLINE uint32_t size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
Clears the array.
|
||||
*/
|
||||
PX_INLINE void clear()
|
||||
{
|
||||
destroy(mData, mData + mSize);
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the array is empty (i.e. whether its size is 0).
|
||||
\return
|
||||
true if the array is empty
|
||||
*/
|
||||
PX_FORCE_INLINE bool empty() const
|
||||
{
|
||||
return mSize == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Finds the first occurrence of an element in the array.
|
||||
\param a
|
||||
The element to find.
|
||||
*/
|
||||
|
||||
PX_INLINE Iterator find(const T& a)
|
||||
{
|
||||
uint32_t index;
|
||||
for(index = 0; index < mSize && mData[index] != a; index++)
|
||||
;
|
||||
return mData + index;
|
||||
}
|
||||
|
||||
PX_INLINE ConstIterator find(const T& a) const
|
||||
{
|
||||
uint32_t index;
|
||||
for(index = 0; index < mSize && mData[index] != a; index++)
|
||||
;
|
||||
return mData + index;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Adds one element to the end of the array. Operation is O(1).
|
||||
\param a
|
||||
The element that will be added to this array.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PX_FORCE_INLINE T& pushBack(const T& a)
|
||||
{
|
||||
if(capacity() <= mSize)
|
||||
return growAndPushBack(a);
|
||||
|
||||
PX_PLACEMENT_NEW(reinterpret_cast<void*>(mData + mSize), T)(a);
|
||||
|
||||
return mData[mSize++];
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Returns the element at the end of the array. Only legal if the array is non-empty.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE T popBack()
|
||||
{
|
||||
NV_CLOTH_ASSERT(mSize);
|
||||
T t = mData[mSize - 1];
|
||||
|
||||
mData[--mSize].~T();
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Construct one element at the end of the array. Operation is O(1).
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE T& insert()
|
||||
{
|
||||
if(capacity() <= mSize)
|
||||
grow(capacityIncrement());
|
||||
|
||||
T* ptr = mData + mSize++;
|
||||
new (ptr) T; // not 'T()' because PODs should not get default-initialized.
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Subtracts the element on position i from the array and replace it with
|
||||
the last element.
|
||||
Operation is O(1)
|
||||
\param i
|
||||
The position of the element that will be subtracted from this array.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void replaceWithLast(uint32_t i)
|
||||
{
|
||||
NV_CLOTH_ASSERT(i < mSize);
|
||||
mData[i] = mData[--mSize];
|
||||
|
||||
mData[mSize].~T();
|
||||
}
|
||||
|
||||
PX_INLINE void replaceWithLast(Iterator i)
|
||||
{
|
||||
replaceWithLast(static_cast<uint32_t>(i - mData));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Replaces the first occurrence of the element a with the last element
|
||||
Operation is O(n)
|
||||
\param a
|
||||
The position of the element that will be subtracted from this array.
|
||||
\return true if the element has been removed.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PX_INLINE bool findAndReplaceWithLast(const T& a)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
while(index < mSize && mData[index] != a)
|
||||
++index;
|
||||
if(index == mSize)
|
||||
return false;
|
||||
replaceWithLast(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Subtracts the element on position i from the array. Shift the entire
|
||||
array one step.
|
||||
Operation is O(n)
|
||||
\param i
|
||||
The position of the element that will be subtracted from this array.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void remove(uint32_t i)
|
||||
{
|
||||
NV_CLOTH_ASSERT(i < mSize);
|
||||
|
||||
T* it = mData + i;
|
||||
it->~T();
|
||||
while (++i < mSize)
|
||||
{
|
||||
new (it) T(mData[i]);
|
||||
++it;
|
||||
it->~T();
|
||||
}
|
||||
--mSize;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Removes a range from the array. Shifts the array so order is maintained.
|
||||
Operation is O(n)
|
||||
\param begin
|
||||
The starting position of the element that will be subtracted from this array.
|
||||
\param count
|
||||
The number of elments that will be subtracted from this array.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void removeRange(uint32_t begin, uint32_t count)
|
||||
{
|
||||
NV_CLOTH_ASSERT(begin < mSize);
|
||||
NV_CLOTH_ASSERT((begin + count) <= mSize);
|
||||
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
mData[begin + i].~T(); // call the destructor on the ones being removed first.
|
||||
|
||||
T* dest = &mData[begin]; // location we are copying the tail end objects to
|
||||
T* src = &mData[begin + count]; // start of tail objects
|
||||
uint32_t move_count = mSize - (begin + count); // compute remainder that needs to be copied down
|
||||
|
||||
for(uint32_t i = 0; i < move_count; i++)
|
||||
{
|
||||
new (dest) T(*src); // copy the old one to the new location
|
||||
src->~T(); // call the destructor on the old location
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
mSize -= count;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Resize array
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_NOINLINE void resize(const uint32_t size, const T& a = T());
|
||||
|
||||
PX_NOINLINE void resizeUninitialized(const uint32_t size);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Resize array such that only as much memory is allocated to hold the
|
||||
existing elements
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void shrink()
|
||||
{
|
||||
recreate(mSize);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Deletes all array elements and frees memory.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void reset()
|
||||
{
|
||||
resize(0);
|
||||
shrink();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Ensure that the array has at least size capacity.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void reserve(const uint32_t capacity)
|
||||
{
|
||||
if(capacity > this->capacity())
|
||||
grow(capacity);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Query the capacity(allocated mem) for the array.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_FORCE_INLINE uint32_t capacity() const
|
||||
{
|
||||
return mCapacity & ~PX_SIGN_BITMASK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Unsafe function to force the size of the array
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_FORCE_INLINE void forceSize_Unsafe(uint32_t size)
|
||||
{
|
||||
NV_CLOTH_ASSERT(size <= mCapacity);
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Swap contents of an array without allocating temporary storage
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void swap(Array<T, Alloc>& other)
|
||||
{
|
||||
ps::swap(mData, other.mData);
|
||||
ps::swap(mSize, other.mSize);
|
||||
ps::swap(mCapacity, other.mCapacity);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
Assign a range of values to this vector (resizes to length of range)
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
PX_INLINE void assign(const T* first, const T* last)
|
||||
{
|
||||
resizeUninitialized(uint32_t(last - first));
|
||||
copy(begin(), end(), first);
|
||||
}
|
||||
|
||||
// We need one bit to mark arrays that have been deserialized from a user-provided memory block.
|
||||
// For alignment & memory saving purpose we store that bit in the rarely used capacity member.
|
||||
PX_FORCE_INLINE uint32_t isInUserMemory() const
|
||||
{
|
||||
return mCapacity & PX_SIGN_BITMASK;
|
||||
}
|
||||
|
||||
/// return reference to allocator
|
||||
PX_INLINE Alloc& getAllocator()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
// constructor for where we don't own the memory
|
||||
Array(T* memory, uint32_t size, uint32_t capacity, const Alloc& alloc = Alloc())
|
||||
: Alloc(alloc), mData(memory), mSize(size), mCapacity(capacity | PX_SIGN_BITMASK)
|
||||
{
|
||||
}
|
||||
|
||||
template <class A>
|
||||
PX_NOINLINE void copy(const Array<T, A>& other);
|
||||
|
||||
PX_INLINE T* allocate(uint32_t size)
|
||||
{
|
||||
if(size > 0)
|
||||
{
|
||||
T* p = reinterpret_cast<T*>(Alloc::allocate(sizeof(T) * size, __FILE__, __LINE__));
|
||||
/**
|
||||
Mark a specified amount of memory with 0xcd pattern. This is used to check that the meta data
|
||||
definition for serialized classes is complete in checked builds.
|
||||
*/
|
||||
#if PX_CHECKED
|
||||
if(p)
|
||||
{
|
||||
for(uint32_t i = 0; i < (sizeof(T) * size); ++i)
|
||||
reinterpret_cast<uint8_t*>(p)[i] = 0xcd;
|
||||
}
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PX_INLINE void deallocate(void* mem)
|
||||
{
|
||||
Alloc::deallocate(mem);
|
||||
}
|
||||
|
||||
static PX_INLINE void create(T* first, T* last, const T& a)
|
||||
{
|
||||
for(; first < last; ++first)
|
||||
::new (first) T(a);
|
||||
}
|
||||
|
||||
static PX_INLINE void copy(T* first, T* last, const T* src)
|
||||
{
|
||||
if(last <= first)
|
||||
return;
|
||||
|
||||
for(; first < last; ++first, ++src)
|
||||
::new (first) T(*src);
|
||||
}
|
||||
|
||||
static PX_INLINE void destroy(T* first, T* last)
|
||||
{
|
||||
for(; first < last; ++first)
|
||||
first->~T();
|
||||
}
|
||||
|
||||
/*!
|
||||
Called when pushBack() needs to grow the array.
|
||||
\param a The element that will be added to this array.
|
||||
*/
|
||||
PX_NOINLINE T& growAndPushBack(const T& a);
|
||||
|
||||
/*!
|
||||
Resizes the available memory for the array.
|
||||
|
||||
\param capacity
|
||||
The number of entries that the set should be able to hold.
|
||||
*/
|
||||
PX_INLINE void grow(uint32_t capacity)
|
||||
{
|
||||
NV_CLOTH_ASSERT(this->capacity() < capacity);
|
||||
recreate(capacity);
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a new memory block, copies all entries to the new block and destroys old entries.
|
||||
|
||||
\param capacity
|
||||
The number of entries that the set should be able to hold.
|
||||
*/
|
||||
PX_NOINLINE void recreate(uint32_t capacity);
|
||||
|
||||
// The idea here is to prevent accidental bugs with pushBack or insert. Unfortunately
|
||||
// it interacts badly with InlineArrays with smaller inline allocations.
|
||||
// TODO(dsequeira): policy template arg, this is exactly what they're for.
|
||||
PX_INLINE uint32_t capacityIncrement() const
|
||||
{
|
||||
const uint32_t capacity = this->capacity();
|
||||
return capacity == 0 ? 1 : capacity * 2;
|
||||
}
|
||||
|
||||
T* mData;
|
||||
uint32_t mSize;
|
||||
uint32_t mCapacity;
|
||||
};
|
||||
|
||||
template <class T, class Alloc>
|
||||
PX_NOINLINE void Array<T, Alloc>::resize(const uint32_t size, const T& a)
|
||||
{
|
||||
reserve(size);
|
||||
create(mData + mSize, mData + size, a);
|
||||
destroy(mData + size, mData + mSize);
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
template <class T, class Alloc>
|
||||
template <class A>
|
||||
PX_NOINLINE void Array<T, Alloc>::copy(const Array<T, A>& other)
|
||||
{
|
||||
if(!other.empty())
|
||||
{
|
||||
mData = allocate(mSize = mCapacity = other.size());
|
||||
copy(mData, mData + mSize, other.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
mData = NULL;
|
||||
mSize = 0;
|
||||
mCapacity = 0;
|
||||
}
|
||||
|
||||
// mData = allocate(other.mSize);
|
||||
// mSize = other.mSize;
|
||||
// mCapacity = other.mSize;
|
||||
// copy(mData, mData + mSize, other.mData);
|
||||
}
|
||||
|
||||
template <class T, class Alloc>
|
||||
PX_NOINLINE void Array<T, Alloc>::resizeUninitialized(const uint32_t size)
|
||||
{
|
||||
reserve(size);
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
template <class T, class Alloc>
|
||||
PX_NOINLINE T& Array<T, Alloc>::growAndPushBack(const T& a)
|
||||
{
|
||||
uint32_t capacity = capacityIncrement();
|
||||
|
||||
T* newData = allocate(capacity);
|
||||
NV_CLOTH_ASSERT((!capacity) || (newData && (newData != mData)));
|
||||
copy(newData, newData + mSize, mData);
|
||||
|
||||
// inserting element before destroying old array
|
||||
// avoids referencing destroyed object when duplicating array element.
|
||||
PX_PLACEMENT_NEW(reinterpret_cast<void*>(newData + mSize), T)(a);
|
||||
|
||||
destroy(mData, mData + mSize);
|
||||
if(!isInUserMemory())
|
||||
deallocate(mData);
|
||||
|
||||
mData = newData;
|
||||
mCapacity = capacity;
|
||||
|
||||
return mData[mSize++];
|
||||
}
|
||||
|
||||
template <class T, class Alloc>
|
||||
PX_NOINLINE void Array<T, Alloc>::recreate(uint32_t capacity)
|
||||
{
|
||||
T* newData = allocate(capacity);
|
||||
NV_CLOTH_ASSERT((!capacity) || (newData && (newData != mData)));
|
||||
|
||||
copy(newData, newData + mSize, mData);
|
||||
destroy(mData, mData + mSize);
|
||||
if(!isInUserMemory())
|
||||
deallocate(mData);
|
||||
|
||||
mData = newData;
|
||||
mCapacity = capacity;
|
||||
}
|
||||
|
||||
template <class T, class Alloc>
|
||||
PX_INLINE void swap(Array<T, Alloc>& x, Array<T, Alloc>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSARRAY_H
|
||||
69
Source/ThirdParty/NvCloth/ps/PsAtomic.h
vendored
Normal file
69
Source/ThirdParty/NvCloth/ps/PsAtomic.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSATOMIC_H
|
||||
#define PSFOUNDATION_PSATOMIC_H
|
||||
|
||||
#include "NvCloth/ps/Ps.h"
|
||||
#include "NvCloth/Callbacks.h"
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
/* set *dest equal to val. Return the old value of *dest */
|
||||
NV_CLOTH_IMPORT int32_t atomicExchange(volatile int32_t* dest, int32_t val);
|
||||
|
||||
/* if *dest == comp, replace with exch. Return original value of *dest */
|
||||
NV_CLOTH_IMPORT int32_t atomicCompareExchange(volatile int32_t* dest, int32_t exch, int32_t comp);
|
||||
|
||||
/* if *dest == comp, replace with exch. Return original value of *dest */
|
||||
NV_CLOTH_IMPORT void* atomicCompareExchangePointer(volatile void** dest, void* exch, void* comp);
|
||||
|
||||
/* increment the specified location. Return the incremented value */
|
||||
NV_CLOTH_IMPORT int32_t atomicIncrement(volatile int32_t* val);
|
||||
|
||||
/* decrement the specified location. Return the decremented value */
|
||||
NV_CLOTH_IMPORT int32_t atomicDecrement(volatile int32_t* val);
|
||||
|
||||
/* add delta to *val. Return the new value */
|
||||
NV_CLOTH_IMPORT int32_t atomicAdd(volatile int32_t* val, int32_t delta);
|
||||
|
||||
/* compute the maximum of dest and val. Return the new value */
|
||||
NV_CLOTH_IMPORT int32_t atomicMax(volatile int32_t* val, int32_t val2);
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSATOMIC_H
|
||||
151
Source/ThirdParty/NvCloth/ps/PsBasicTemplates.h
vendored
Normal file
151
Source/ThirdParty/NvCloth/ps/PsBasicTemplates.h
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSBASICTEMPLATES_H
|
||||
#define PSFOUNDATION_PSBASICTEMPLATES_H
|
||||
|
||||
#include "Ps.h"
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
template <typename A>
|
||||
struct Equal
|
||||
{
|
||||
bool operator()(const A& a, const A& b) const
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
struct Less
|
||||
{
|
||||
bool operator()(const A& a, const A& b) const
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A>
|
||||
struct Greater
|
||||
{
|
||||
bool operator()(const A& a, const A& b) const
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
};
|
||||
|
||||
template <class F, class S>
|
||||
class Pair
|
||||
{
|
||||
public:
|
||||
F first;
|
||||
S second;
|
||||
Pair() : first(F()), second(S())
|
||||
{
|
||||
}
|
||||
Pair(const F& f, const S& s) : first(f), second(s)
|
||||
{
|
||||
}
|
||||
Pair(const Pair& p) : first(p.first), second(p.second)
|
||||
{
|
||||
}
|
||||
// CN - fix for /.../PsBasicTemplates.h(61) : warning C4512: 'nv::cloth::Pair<F,S>' : assignment operator could
|
||||
// not be generated
|
||||
Pair& operator=(const Pair& p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const Pair& p) const
|
||||
{
|
||||
return first == p.first && second == p.second;
|
||||
}
|
||||
bool operator<(const Pair& p) const
|
||||
{
|
||||
if(first < p.first)
|
||||
return true;
|
||||
else
|
||||
return !(p.first < first) && (second < p.second);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int A>
|
||||
struct LogTwo
|
||||
{
|
||||
static const unsigned int value = LogTwo<(A >> 1)>::value + 1;
|
||||
};
|
||||
template <>
|
||||
struct LogTwo<1>
|
||||
{
|
||||
static const unsigned int value = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct UnConst
|
||||
{
|
||||
typedef T Type;
|
||||
};
|
||||
template <typename T>
|
||||
struct UnConst<const T>
|
||||
{
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T pointerOffset(void* p, ptrdiff_t offset)
|
||||
{
|
||||
return reinterpret_cast<T>(reinterpret_cast<char*>(p) + offset);
|
||||
}
|
||||
template <typename T>
|
||||
T pointerOffset(const void* p, ptrdiff_t offset)
|
||||
{
|
||||
return reinterpret_cast<T>(reinterpret_cast<const char*>(p) + offset);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PX_CUDA_CALLABLE PX_INLINE void swap(T& x, T& y)
|
||||
{
|
||||
const T tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSBASICTEMPLATES_H
|
||||
114
Source/ThirdParty/NvCloth/ps/PsBitUtils.h
vendored
Normal file
114
Source/ThirdParty/NvCloth/ps/PsBitUtils.h
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSBITUTILS_H
|
||||
#define PSFOUNDATION_PSBITUTILS_H
|
||||
|
||||
#include "foundation/PxIntrinsics.h"
|
||||
#include "../Callbacks.h"
|
||||
#include "PsIntrinsics.h"
|
||||
#include "Ps.h"
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
PX_INLINE uint32_t bitCount(uint32_t v)
|
||||
{
|
||||
// from http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
||||
uint32_t const w = v - ((v >> 1) & 0x55555555);
|
||||
uint32_t const x = (w & 0x33333333) + ((w >> 2) & 0x33333333);
|
||||
return (((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
}
|
||||
|
||||
PX_INLINE bool isPowerOfTwo(uint32_t x)
|
||||
{
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
// "Next Largest Power of 2
|
||||
// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
|
||||
// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
|
||||
// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
|
||||
// largest power of 2. For a 32-bit value:"
|
||||
PX_INLINE uint32_t nextPowerOfTwo(uint32_t x)
|
||||
{
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the index of the highest set bit. Not valid for zero arg.
|
||||
*/
|
||||
|
||||
PX_INLINE uint32_t lowestSetBit(uint32_t x)
|
||||
{
|
||||
NV_CLOTH_ASSERT(x);
|
||||
return PxLowestSetBitUnsafe(x);
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the index of the highest set bit. Not valid for zero arg.
|
||||
*/
|
||||
|
||||
PX_INLINE uint32_t highestSetBit(uint32_t x)
|
||||
{
|
||||
NV_CLOTH_ASSERT(x);
|
||||
return PxHighestSetBitUnsafe(x);
|
||||
}
|
||||
|
||||
// Helper function to approximate log2 of an integer value
|
||||
// assumes that the input is actually power of two.
|
||||
// todo: replace 2 usages with 'highestSetBit'
|
||||
PX_INLINE uint32_t ilog2(uint32_t num)
|
||||
{
|
||||
for(uint32_t i = 0; i < 32; i++)
|
||||
{
|
||||
num >>= 1;
|
||||
if(num == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
NV_CLOTH_ASSERT(0);
|
||||
return uint32_t(-1);
|
||||
}
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSBITUTILS_H
|
||||
167
Source/ThirdParty/NvCloth/ps/PsHash.h
vendored
Normal file
167
Source/ThirdParty/NvCloth/ps/PsHash.h
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSHASH_H
|
||||
#define PSFOUNDATION_PSHASH_H
|
||||
|
||||
#include "Ps.h"
|
||||
#include "PsBasicTemplates.h"
|
||||
|
||||
#if PX_VC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4302)
|
||||
#endif
|
||||
|
||||
#if PX_LINUX
|
||||
#include "foundation/PxSimpleTypes.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Central definition of hash functions
|
||||
*/
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
// Hash functions
|
||||
|
||||
// Thomas Wang's 32 bit mix
|
||||
// http://www.cris.com/~Ttwang/tech/inthash.htm
|
||||
PX_FORCE_INLINE uint32_t hash(const uint32_t key)
|
||||
{
|
||||
uint32_t k = key;
|
||||
k += ~(k << 15);
|
||||
k ^= (k >> 10);
|
||||
k += (k << 3);
|
||||
k ^= (k >> 6);
|
||||
k += ~(k << 11);
|
||||
k ^= (k >> 16);
|
||||
return uint32_t(k);
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE uint32_t hash(const int32_t key)
|
||||
{
|
||||
return hash(uint32_t(key));
|
||||
}
|
||||
|
||||
// Thomas Wang's 64 bit mix
|
||||
// http://www.cris.com/~Ttwang/tech/inthash.htm
|
||||
PX_FORCE_INLINE uint32_t hash(const uint64_t key)
|
||||
{
|
||||
uint64_t k = key;
|
||||
k += ~(k << 32);
|
||||
k ^= (k >> 22);
|
||||
k += ~(k << 13);
|
||||
k ^= (k >> 8);
|
||||
k += (k << 3);
|
||||
k ^= (k >> 15);
|
||||
k += ~(k << 27);
|
||||
k ^= (k >> 31);
|
||||
return uint32_t(UINT32_MAX & k);
|
||||
}
|
||||
|
||||
#if PX_APPLE_FAMILY
|
||||
// hash for size_t, to make gcc happy
|
||||
PX_INLINE uint32_t hash(const size_t key)
|
||||
{
|
||||
#if PX_P64_FAMILY
|
||||
return hash(uint64_t(key));
|
||||
#else
|
||||
return hash(uint32_t(key));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Hash function for pointers
|
||||
PX_INLINE uint32_t hash(const void* ptr)
|
||||
{
|
||||
#if PX_P64_FAMILY
|
||||
return hash(uint64_t(ptr));
|
||||
#else
|
||||
return hash(uint32_t(UINT32_MAX & size_t(ptr)));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Hash function for pairs
|
||||
template <typename F, typename S>
|
||||
PX_INLINE uint32_t hash(const Pair<F, S>& p)
|
||||
{
|
||||
uint32_t seed = 0x876543;
|
||||
uint32_t m = 1000007;
|
||||
return hash(p.second) ^ (m * (hash(p.first) ^ (m * seed)));
|
||||
}
|
||||
|
||||
// hash object for hash map template parameter
|
||||
template <class Key>
|
||||
struct Hash
|
||||
{
|
||||
uint32_t operator()(const Key& k) const
|
||||
{
|
||||
return hash(k);
|
||||
}
|
||||
bool equal(const Key& k0, const Key& k1) const
|
||||
{
|
||||
return k0 == k1;
|
||||
}
|
||||
};
|
||||
|
||||
// specialization for strings
|
||||
template <>
|
||||
struct Hash<const char*>
|
||||
{
|
||||
public:
|
||||
uint32_t operator()(const char* _string) const
|
||||
{
|
||||
// "DJB" string hash
|
||||
const uint8_t* string = reinterpret_cast<const uint8_t*>(_string);
|
||||
uint32_t h = 5381;
|
||||
for(const uint8_t* ptr = string; *ptr; ptr++)
|
||||
h = ((h << 5) + h) ^ uint32_t(*ptr);
|
||||
return h;
|
||||
}
|
||||
bool equal(const char* string0, const char* string1) const
|
||||
{
|
||||
return !strcmp(string0, string1);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#if PX_VC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSHASH_H
|
||||
800
Source/ThirdParty/NvCloth/ps/PsHashInternals.h
vendored
Normal file
800
Source/ThirdParty/NvCloth/ps/PsHashInternals.h
vendored
Normal file
@@ -0,0 +1,800 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSHASHINTERNALS_H
|
||||
#define PSFOUNDATION_PSHASHINTERNALS_H
|
||||
|
||||
#include "PsBasicTemplates.h"
|
||||
#include "PsArray.h"
|
||||
#include "PsBitUtils.h"
|
||||
#include "PsHash.h"
|
||||
#include "foundation/PxIntrinsics.h"
|
||||
|
||||
#if PX_VC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template <class Entry, class Key, class HashFn, class GetKey, class Allocator, bool compacting>
|
||||
class HashBase : private Allocator
|
||||
{
|
||||
void init(uint32_t initialTableSize, float loadFactor)
|
||||
{
|
||||
mBuffer = NULL;
|
||||
mEntries = NULL;
|
||||
mEntriesNext = NULL;
|
||||
mHash = NULL;
|
||||
mEntriesCapacity = 0;
|
||||
mHashSize = 0;
|
||||
mLoadFactor = loadFactor;
|
||||
mFreeList = uint32_t(EOL);
|
||||
mTimestamp = 0;
|
||||
mEntriesCount = 0;
|
||||
|
||||
if(initialTableSize)
|
||||
reserveInternal(initialTableSize);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef Entry EntryType;
|
||||
|
||||
HashBase(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : Allocator(PX_DEBUG_EXP("hashBase"))
|
||||
{
|
||||
init(initialTableSize, loadFactor);
|
||||
}
|
||||
|
||||
HashBase(uint32_t initialTableSize, float loadFactor, const Allocator& alloc) : Allocator(alloc)
|
||||
{
|
||||
init(initialTableSize, loadFactor);
|
||||
}
|
||||
|
||||
HashBase(const Allocator& alloc) : Allocator(alloc)
|
||||
{
|
||||
init(64, 0.75f);
|
||||
}
|
||||
|
||||
~HashBase()
|
||||
{
|
||||
destroy(); // No need to clear()
|
||||
|
||||
if(mBuffer)
|
||||
Allocator::deallocate(mBuffer);
|
||||
}
|
||||
|
||||
static const uint32_t EOL = 0xffffffff;
|
||||
|
||||
PX_INLINE Entry* create(const Key& k, bool& exists)
|
||||
{
|
||||
uint32_t h = 0;
|
||||
if(mHashSize)
|
||||
{
|
||||
h = hash(k);
|
||||
uint32_t index = mHash[h];
|
||||
while(index != EOL && !HashFn().equal(GetKey()(mEntries[index]), k))
|
||||
index = mEntriesNext[index];
|
||||
exists = index != EOL;
|
||||
if(exists)
|
||||
return mEntries + index;
|
||||
}
|
||||
else
|
||||
exists = false;
|
||||
|
||||
if(freeListEmpty())
|
||||
{
|
||||
grow();
|
||||
h = hash(k);
|
||||
}
|
||||
|
||||
uint32_t entryIndex = freeListGetNext();
|
||||
|
||||
mEntriesNext[entryIndex] = mHash[h];
|
||||
mHash[h] = entryIndex;
|
||||
|
||||
mEntriesCount++;
|
||||
mTimestamp++;
|
||||
|
||||
return mEntries + entryIndex;
|
||||
}
|
||||
|
||||
PX_INLINE const Entry* find(const Key& k) const
|
||||
{
|
||||
if(!mEntriesCount)
|
||||
return NULL;
|
||||
|
||||
const uint32_t h = hash(k);
|
||||
uint32_t index = mHash[h];
|
||||
while(index != EOL && !HashFn().equal(GetKey()(mEntries[index]), k))
|
||||
index = mEntriesNext[index];
|
||||
return index != EOL ? mEntries + index : NULL;
|
||||
}
|
||||
|
||||
PX_INLINE bool erase(const Key& k, Entry& e)
|
||||
{
|
||||
if(!mEntriesCount)
|
||||
return false;
|
||||
|
||||
const uint32_t h = hash(k);
|
||||
uint32_t* ptr = mHash + h;
|
||||
while(*ptr != EOL && !HashFn().equal(GetKey()(mEntries[*ptr]), k))
|
||||
ptr = mEntriesNext + *ptr;
|
||||
|
||||
if(*ptr == EOL)
|
||||
return false;
|
||||
|
||||
PX_PLACEMENT_NEW(&e, Entry)(mEntries[*ptr]);
|
||||
|
||||
return eraseInternal(ptr);
|
||||
}
|
||||
|
||||
PX_INLINE bool erase(const Key& k)
|
||||
{
|
||||
if(!mEntriesCount)
|
||||
return false;
|
||||
|
||||
const uint32_t h = hash(k);
|
||||
uint32_t* ptr = mHash + h;
|
||||
while(*ptr != EOL && !HashFn().equal(GetKey()(mEntries[*ptr]), k))
|
||||
ptr = mEntriesNext + *ptr;
|
||||
|
||||
if(*ptr == EOL)
|
||||
return false;
|
||||
|
||||
return eraseInternal(ptr);
|
||||
}
|
||||
|
||||
PX_INLINE uint32_t size() const
|
||||
{
|
||||
return mEntriesCount;
|
||||
}
|
||||
|
||||
PX_INLINE uint32_t capacity() const
|
||||
{
|
||||
return mHashSize;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if(!mHashSize || mEntriesCount == 0)
|
||||
return;
|
||||
|
||||
destroy();
|
||||
|
||||
physx::intrinsics::memSet(mHash, EOL, mHashSize * sizeof(uint32_t));
|
||||
|
||||
const uint32_t sizeMinus1 = mEntriesCapacity - 1;
|
||||
for(uint32_t i = 0; i < sizeMinus1; i++)
|
||||
{
|
||||
PxPrefetchLine(mEntriesNext + i, 128);
|
||||
mEntriesNext[i] = i + 1;
|
||||
}
|
||||
mEntriesNext[mEntriesCapacity - 1] = uint32_t(EOL);
|
||||
mFreeList = 0;
|
||||
mEntriesCount = 0;
|
||||
}
|
||||
|
||||
void reserve(uint32_t size)
|
||||
{
|
||||
if(size > mHashSize)
|
||||
reserveInternal(size);
|
||||
}
|
||||
|
||||
PX_INLINE const Entry* getEntries() const
|
||||
{
|
||||
return mEntries;
|
||||
}
|
||||
|
||||
PX_INLINE Entry* insertUnique(const Key& k)
|
||||
{
|
||||
NV_CLOTH_ASSERT(find(k) == NULL);
|
||||
uint32_t h = hash(k);
|
||||
|
||||
uint32_t entryIndex = freeListGetNext();
|
||||
|
||||
mEntriesNext[entryIndex] = mHash[h];
|
||||
mHash[h] = entryIndex;
|
||||
|
||||
mEntriesCount++;
|
||||
mTimestamp++;
|
||||
|
||||
return mEntries + entryIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
void destroy()
|
||||
{
|
||||
for(uint32_t i = 0; i < mHashSize; i++)
|
||||
{
|
||||
for(uint32_t j = mHash[i]; j != EOL; j = mEntriesNext[j])
|
||||
mEntries[j].~Entry();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename HK, typename GK, class A, bool comp>
|
||||
PX_NOINLINE void copy(const HashBase<Entry, Key, HK, GK, A, comp>& other);
|
||||
|
||||
// free list management - if we're coalescing, then we use mFreeList to hold
|
||||
// the top of the free list and it should always be equal to size(). Otherwise,
|
||||
// we build a free list in the next() pointers.
|
||||
|
||||
PX_INLINE void freeListAdd(uint32_t index)
|
||||
{
|
||||
if(compacting)
|
||||
{
|
||||
mFreeList--;
|
||||
NV_CLOTH_ASSERT(mFreeList == mEntriesCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntriesNext[index] = mFreeList;
|
||||
mFreeList = index;
|
||||
}
|
||||
}
|
||||
|
||||
PX_INLINE void freeListAdd(uint32_t start, uint32_t end)
|
||||
{
|
||||
if(!compacting)
|
||||
{
|
||||
for(uint32_t i = start; i < end - 1; i++) // add the new entries to the free list
|
||||
mEntriesNext[i] = i + 1;
|
||||
|
||||
// link in old free list
|
||||
mEntriesNext[end - 1] = mFreeList;
|
||||
NV_CLOTH_ASSERT(mFreeList != end - 1);
|
||||
mFreeList = start;
|
||||
}
|
||||
else if(mFreeList == EOL) // don't reset the free ptr for the compacting hash unless it's empty
|
||||
mFreeList = start;
|
||||
}
|
||||
|
||||
PX_INLINE uint32_t freeListGetNext()
|
||||
{
|
||||
NV_CLOTH_ASSERT(!freeListEmpty());
|
||||
if(compacting)
|
||||
{
|
||||
NV_CLOTH_ASSERT(mFreeList == mEntriesCount);
|
||||
return mFreeList++;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t entryIndex = mFreeList;
|
||||
mFreeList = mEntriesNext[mFreeList];
|
||||
return entryIndex;
|
||||
}
|
||||
}
|
||||
|
||||
PX_INLINE bool freeListEmpty() const
|
||||
{
|
||||
if(compacting)
|
||||
return mEntriesCount == mEntriesCapacity;
|
||||
else
|
||||
return mFreeList == EOL;
|
||||
}
|
||||
|
||||
PX_INLINE void replaceWithLast(uint32_t index)
|
||||
{
|
||||
PX_PLACEMENT_NEW(mEntries + index, Entry)(mEntries[mEntriesCount]);
|
||||
mEntries[mEntriesCount].~Entry();
|
||||
mEntriesNext[index] = mEntriesNext[mEntriesCount];
|
||||
|
||||
uint32_t h = hash(GetKey()(mEntries[index]));
|
||||
uint32_t* ptr;
|
||||
for(ptr = mHash + h; *ptr != mEntriesCount; ptr = mEntriesNext + *ptr)
|
||||
NV_CLOTH_ASSERT(*ptr != EOL);
|
||||
*ptr = index;
|
||||
}
|
||||
|
||||
PX_INLINE uint32_t hash(const Key& k, uint32_t hashSize) const
|
||||
{
|
||||
return HashFn()(k) & (hashSize - 1);
|
||||
}
|
||||
|
||||
PX_INLINE uint32_t hash(const Key& k) const
|
||||
{
|
||||
return hash(k, mHashSize);
|
||||
}
|
||||
|
||||
PX_INLINE bool eraseInternal(uint32_t* ptr)
|
||||
{
|
||||
const uint32_t index = *ptr;
|
||||
|
||||
*ptr = mEntriesNext[index];
|
||||
|
||||
mEntries[index].~Entry();
|
||||
|
||||
mEntriesCount--;
|
||||
mTimestamp++;
|
||||
|
||||
if (compacting && index != mEntriesCount)
|
||||
replaceWithLast(index);
|
||||
|
||||
freeListAdd(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
void reserveInternal(uint32_t size)
|
||||
{
|
||||
if(!isPowerOfTwo(size))
|
||||
size = nextPowerOfTwo(size);
|
||||
|
||||
NV_CLOTH_ASSERT(!(size & (size - 1)));
|
||||
|
||||
// decide whether iteration can be done on the entries directly
|
||||
bool resizeCompact = compacting || freeListEmpty();
|
||||
|
||||
// define new table sizes
|
||||
uint32_t oldEntriesCapacity = mEntriesCapacity;
|
||||
uint32_t newEntriesCapacity = uint32_t(float(size) * mLoadFactor);
|
||||
uint32_t newHashSize = size;
|
||||
|
||||
// allocate new common buffer and setup pointers to new tables
|
||||
uint8_t* newBuffer;
|
||||
uint32_t* newHash;
|
||||
uint32_t* newEntriesNext;
|
||||
Entry* newEntries;
|
||||
{
|
||||
uint32_t newHashByteOffset = 0;
|
||||
uint32_t newEntriesNextBytesOffset = newHashByteOffset + newHashSize * sizeof(uint32_t);
|
||||
uint32_t newEntriesByteOffset = newEntriesNextBytesOffset + newEntriesCapacity * sizeof(uint32_t);
|
||||
newEntriesByteOffset += (16 - (newEntriesByteOffset & 15)) & 15;
|
||||
uint32_t newBufferByteSize = newEntriesByteOffset + newEntriesCapacity * sizeof(Entry);
|
||||
|
||||
newBuffer = reinterpret_cast<uint8_t*>(Allocator::allocate(newBufferByteSize, __FILE__, __LINE__));
|
||||
NV_CLOTH_ASSERT(newBuffer);
|
||||
|
||||
newHash = reinterpret_cast<uint32_t*>(newBuffer + newHashByteOffset);
|
||||
newEntriesNext = reinterpret_cast<uint32_t*>(newBuffer + newEntriesNextBytesOffset);
|
||||
newEntries = reinterpret_cast<Entry*>(newBuffer + newEntriesByteOffset);
|
||||
}
|
||||
|
||||
// initialize new hash table
|
||||
physx::intrinsics::memSet(newHash, uint32_t(EOL), newHashSize * sizeof(uint32_t));
|
||||
|
||||
// iterate over old entries, re-hash and create new entries
|
||||
if(resizeCompact)
|
||||
{
|
||||
// check that old free list is empty - we don't need to copy the next entries
|
||||
NV_CLOTH_ASSERT(compacting || mFreeList == EOL);
|
||||
|
||||
for(uint32_t index = 0; index < mEntriesCount; ++index)
|
||||
{
|
||||
uint32_t h = hash(GetKey()(mEntries[index]), newHashSize);
|
||||
newEntriesNext[index] = newHash[h];
|
||||
newHash[h] = index;
|
||||
|
||||
PX_PLACEMENT_NEW(newEntries + index, Entry)(mEntries[index]);
|
||||
mEntries[index].~Entry();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy old free list, only required for non compact resizing
|
||||
physx::intrinsics::memCopy(newEntriesNext, mEntriesNext, mEntriesCapacity * sizeof(uint32_t));
|
||||
|
||||
for(uint32_t bucket = 0; bucket < mHashSize; bucket++)
|
||||
{
|
||||
uint32_t index = mHash[bucket];
|
||||
while(index != EOL)
|
||||
{
|
||||
uint32_t h = hash(GetKey()(mEntries[index]), newHashSize);
|
||||
newEntriesNext[index] = newHash[h];
|
||||
NV_CLOTH_ASSERT(index != newHash[h]);
|
||||
|
||||
newHash[h] = index;
|
||||
|
||||
PX_PLACEMENT_NEW(newEntries + index, Entry)(mEntries[index]);
|
||||
mEntries[index].~Entry();
|
||||
|
||||
index = mEntriesNext[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swap buffer and pointers
|
||||
Allocator::deallocate(mBuffer);
|
||||
mBuffer = newBuffer;
|
||||
mHash = newHash;
|
||||
mHashSize = newHashSize;
|
||||
mEntriesNext = newEntriesNext;
|
||||
mEntries = newEntries;
|
||||
mEntriesCapacity = newEntriesCapacity;
|
||||
|
||||
freeListAdd(oldEntriesCapacity, newEntriesCapacity);
|
||||
}
|
||||
|
||||
void grow()
|
||||
{
|
||||
NV_CLOTH_ASSERT((mFreeList == EOL) || (compacting && (mEntriesCount == mEntriesCapacity)));
|
||||
|
||||
uint32_t size = mHashSize == 0 ? 16 : mHashSize * 2;
|
||||
reserve(size);
|
||||
}
|
||||
|
||||
uint8_t* mBuffer;
|
||||
Entry* mEntries;
|
||||
uint32_t* mEntriesNext; // same size as mEntries
|
||||
uint32_t* mHash;
|
||||
uint32_t mEntriesCapacity;
|
||||
uint32_t mHashSize;
|
||||
float mLoadFactor;
|
||||
uint32_t mFreeList;
|
||||
uint32_t mTimestamp;
|
||||
uint32_t mEntriesCount; // number of entries
|
||||
|
||||
public:
|
||||
class Iter
|
||||
{
|
||||
public:
|
||||
PX_INLINE Iter(HashBase& b) : mBucket(0), mEntry(uint32_t(b.EOL)), mTimestamp(b.mTimestamp), mBase(b)
|
||||
{
|
||||
if(mBase.mEntriesCapacity > 0)
|
||||
{
|
||||
mEntry = mBase.mHash[0];
|
||||
skip();
|
||||
}
|
||||
}
|
||||
|
||||
PX_INLINE void check() const
|
||||
{
|
||||
NV_CLOTH_ASSERT(mTimestamp == mBase.mTimestamp);
|
||||
}
|
||||
PX_INLINE const Entry& operator*() const
|
||||
{
|
||||
check();
|
||||
return mBase.mEntries[mEntry];
|
||||
}
|
||||
PX_INLINE Entry& operator*()
|
||||
{
|
||||
check();
|
||||
return mBase.mEntries[mEntry];
|
||||
}
|
||||
PX_INLINE const Entry* operator->() const
|
||||
{
|
||||
check();
|
||||
return mBase.mEntries + mEntry;
|
||||
}
|
||||
PX_INLINE Entry* operator->()
|
||||
{
|
||||
check();
|
||||
return mBase.mEntries + mEntry;
|
||||
}
|
||||
PX_INLINE Iter operator++()
|
||||
{
|
||||
check();
|
||||
advance();
|
||||
return *this;
|
||||
}
|
||||
PX_INLINE Iter operator++(int)
|
||||
{
|
||||
check();
|
||||
Iter i = *this;
|
||||
advance();
|
||||
return i;
|
||||
}
|
||||
PX_INLINE bool done() const
|
||||
{
|
||||
check();
|
||||
return mEntry == mBase.EOL;
|
||||
}
|
||||
|
||||
private:
|
||||
PX_INLINE void advance()
|
||||
{
|
||||
mEntry = mBase.mEntriesNext[mEntry];
|
||||
skip();
|
||||
}
|
||||
PX_INLINE void skip()
|
||||
{
|
||||
while(mEntry == mBase.EOL)
|
||||
{
|
||||
if(++mBucket == mBase.mHashSize)
|
||||
break;
|
||||
mEntry = mBase.mHash[mBucket];
|
||||
}
|
||||
}
|
||||
|
||||
Iter& operator=(const Iter&);
|
||||
|
||||
uint32_t mBucket;
|
||||
uint32_t mEntry;
|
||||
uint32_t mTimestamp;
|
||||
HashBase& mBase;
|
||||
};
|
||||
|
||||
/*!
|
||||
Iterate over entries in a hash base and allow entry erase while iterating
|
||||
*/
|
||||
class EraseIterator
|
||||
{
|
||||
public:
|
||||
PX_INLINE EraseIterator(HashBase& b): mBase(b)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
PX_INLINE Entry* eraseCurrentGetNext(bool eraseCurrent)
|
||||
{
|
||||
if(eraseCurrent && mCurrentEntryIndexPtr)
|
||||
{
|
||||
mBase.eraseInternal(mCurrentEntryIndexPtr);
|
||||
// if next was valid return the same ptr, if next was EOL search new hash entry
|
||||
if(*mCurrentEntryIndexPtr != mBase.EOL)
|
||||
return mBase.mEntries + *mCurrentEntryIndexPtr;
|
||||
else
|
||||
return traverseHashEntries();
|
||||
}
|
||||
|
||||
// traverse mHash to find next entry
|
||||
if(mCurrentEntryIndexPtr == NULL)
|
||||
return traverseHashEntries();
|
||||
|
||||
const uint32_t index = *mCurrentEntryIndexPtr;
|
||||
if(mBase.mEntriesNext[index] == mBase.EOL)
|
||||
{
|
||||
return traverseHashEntries();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentEntryIndexPtr = mBase.mEntriesNext + index;
|
||||
return mBase.mEntries + *mCurrentEntryIndexPtr;
|
||||
}
|
||||
}
|
||||
|
||||
PX_INLINE void reset()
|
||||
{
|
||||
mCurrentHashIndex = 0;
|
||||
mCurrentEntryIndexPtr = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
PX_INLINE Entry* traverseHashEntries()
|
||||
{
|
||||
mCurrentEntryIndexPtr = NULL;
|
||||
while (mCurrentEntryIndexPtr == NULL && mCurrentHashIndex < mBase.mHashSize)
|
||||
{
|
||||
if (mBase.mHash[mCurrentHashIndex] != mBase.EOL)
|
||||
{
|
||||
mCurrentEntryIndexPtr = mBase.mHash + mCurrentHashIndex;
|
||||
mCurrentHashIndex++;
|
||||
return mBase.mEntries + *mCurrentEntryIndexPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentHashIndex++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EraseIterator& operator=(const EraseIterator&);
|
||||
private:
|
||||
uint32_t* mCurrentEntryIndexPtr;
|
||||
uint32_t mCurrentHashIndex;
|
||||
HashBase& mBase;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Entry, class Key, class HashFn, class GetKey, class Allocator, bool compacting>
|
||||
template <typename HK, typename GK, class A, bool comp>
|
||||
PX_NOINLINE void
|
||||
HashBase<Entry, Key, HashFn, GetKey, Allocator, compacting>::copy(const HashBase<Entry, Key, HK, GK, A, comp>& other)
|
||||
{
|
||||
reserve(other.mEntriesCount);
|
||||
|
||||
for(uint32_t i = 0; i < other.mEntriesCount; i++)
|
||||
{
|
||||
for(uint32_t j = other.mHash[i]; j != EOL; j = other.mEntriesNext[j])
|
||||
{
|
||||
const Entry& otherEntry = other.mEntries[j];
|
||||
|
||||
bool exists;
|
||||
Entry* newEntry = create(GK()(otherEntry), exists);
|
||||
NV_CLOTH_ASSERT(!exists);
|
||||
|
||||
PX_PLACEMENT_NEW(newEntry, Entry)(otherEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class HashFn, class Allocator = typename AllocatorTraits<Key>::Type, bool Coalesced = false>
|
||||
class HashSetBase
|
||||
{
|
||||
PX_NOCOPY(HashSetBase)
|
||||
public:
|
||||
struct GetKey
|
||||
{
|
||||
PX_INLINE const Key& operator()(const Key& e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashBase<Key, Key, HashFn, GetKey, Allocator, Coalesced> BaseMap;
|
||||
typedef typename BaseMap::Iter Iterator;
|
||||
|
||||
HashSetBase(uint32_t initialTableSize, float loadFactor, const Allocator& alloc)
|
||||
: mBase(initialTableSize, loadFactor, alloc)
|
||||
{
|
||||
}
|
||||
|
||||
HashSetBase(const Allocator& alloc) : mBase(64, 0.75f, alloc)
|
||||
{
|
||||
}
|
||||
|
||||
HashSetBase(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : mBase(initialTableSize, loadFactor)
|
||||
{
|
||||
}
|
||||
|
||||
bool insert(const Key& k)
|
||||
{
|
||||
bool exists;
|
||||
Key* e = mBase.create(k, exists);
|
||||
if(!exists)
|
||||
PX_PLACEMENT_NEW(e, Key)(k);
|
||||
return !exists;
|
||||
}
|
||||
|
||||
PX_INLINE bool contains(const Key& k) const
|
||||
{
|
||||
return mBase.find(k) != 0;
|
||||
}
|
||||
PX_INLINE bool erase(const Key& k)
|
||||
{
|
||||
return mBase.erase(k);
|
||||
}
|
||||
PX_INLINE uint32_t size() const
|
||||
{
|
||||
return mBase.size();
|
||||
}
|
||||
PX_INLINE uint32_t capacity() const
|
||||
{
|
||||
return mBase.capacity();
|
||||
}
|
||||
PX_INLINE void reserve(uint32_t size)
|
||||
{
|
||||
mBase.reserve(size);
|
||||
}
|
||||
PX_INLINE void clear()
|
||||
{
|
||||
mBase.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
BaseMap mBase;
|
||||
};
|
||||
|
||||
template <class Key, class Value, class HashFn, class Allocator = typename AllocatorTraits<Pair<const Key, Value> >::Type>
|
||||
class HashMapBase
|
||||
{
|
||||
PX_NOCOPY(HashMapBase)
|
||||
public:
|
||||
typedef Pair<const Key, Value> Entry;
|
||||
|
||||
struct GetKey
|
||||
{
|
||||
PX_INLINE const Key& operator()(const Entry& e)
|
||||
{
|
||||
return e.first;
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashBase<Entry, Key, HashFn, GetKey, Allocator, true> BaseMap;
|
||||
typedef typename BaseMap::Iter Iterator;
|
||||
typedef typename BaseMap::EraseIterator EraseIterator;
|
||||
|
||||
HashMapBase(uint32_t initialTableSize, float loadFactor, const Allocator& alloc)
|
||||
: mBase(initialTableSize, loadFactor, alloc)
|
||||
{
|
||||
}
|
||||
|
||||
HashMapBase(const Allocator& alloc) : mBase(64, 0.75f, alloc)
|
||||
{
|
||||
}
|
||||
|
||||
HashMapBase(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : mBase(initialTableSize, loadFactor)
|
||||
{
|
||||
}
|
||||
|
||||
bool insert(const Key /*&*/ k, const Value /*&*/ v)
|
||||
{
|
||||
bool exists;
|
||||
Entry* e = mBase.create(k, exists);
|
||||
if(!exists)
|
||||
PX_PLACEMENT_NEW(e, Entry)(k, v);
|
||||
return !exists;
|
||||
}
|
||||
|
||||
Value& operator[](const Key& k)
|
||||
{
|
||||
bool exists;
|
||||
Entry* e = mBase.create(k, exists);
|
||||
if(!exists)
|
||||
PX_PLACEMENT_NEW(e, Entry)(k, Value());
|
||||
|
||||
return e->second;
|
||||
}
|
||||
|
||||
PX_INLINE const Entry* find(const Key& k) const
|
||||
{
|
||||
return mBase.find(k);
|
||||
}
|
||||
PX_INLINE bool erase(const Key& k)
|
||||
{
|
||||
return mBase.erase(k);
|
||||
}
|
||||
PX_INLINE bool erase(const Key& k, Entry& e)
|
||||
{
|
||||
return mBase.erase(k, e);
|
||||
}
|
||||
PX_INLINE uint32_t size() const
|
||||
{
|
||||
return mBase.size();
|
||||
}
|
||||
PX_INLINE uint32_t capacity() const
|
||||
{
|
||||
return mBase.capacity();
|
||||
}
|
||||
PX_INLINE Iterator getIterator()
|
||||
{
|
||||
return Iterator(mBase);
|
||||
}
|
||||
PX_INLINE EraseIterator getEraseIterator()
|
||||
{
|
||||
return EraseIterator(mBase);
|
||||
}
|
||||
PX_INLINE void reserve(uint32_t size)
|
||||
{
|
||||
mBase.reserve(size);
|
||||
}
|
||||
PX_INLINE void clear()
|
||||
{
|
||||
mBase.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
BaseMap mBase;
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#if PX_VC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#endif // #ifndef PSFOUNDATION_PSHASHINTERNALS_H
|
||||
123
Source/ThirdParty/NvCloth/ps/PsHashMap.h
vendored
Normal file
123
Source/ThirdParty/NvCloth/ps/PsHashMap.h
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSHASHMAP_H
|
||||
#define PSFOUNDATION_PSHASHMAP_H
|
||||
|
||||
#include "PsHashInternals.h"
|
||||
|
||||
// TODO: make this doxy-format
|
||||
//
|
||||
// This header defines two hash maps. Hash maps
|
||||
// * support custom initial table sizes (rounded up internally to power-of-2)
|
||||
// * support custom static allocator objects
|
||||
// * auto-resize, based on a load factor (i.e. a 64-entry .75 load factor hash will resize
|
||||
// when the 49th element is inserted)
|
||||
// * are based on open hashing
|
||||
// * have O(1) contains, erase
|
||||
//
|
||||
// Maps have STL-like copying semantics, and properly initialize and destruct copies of objects
|
||||
//
|
||||
// There are two forms of map: coalesced and uncoalesced. Coalesced maps keep the entries in the
|
||||
// initial segment of an array, so are fast to iterate over; however deletion is approximately
|
||||
// twice as expensive.
|
||||
//
|
||||
// HashMap<T>:
|
||||
// bool insert(const Key& k, const Value& v) O(1) amortized (exponential resize policy)
|
||||
// Value & operator[](const Key& k) O(1) for existing objects, else O(1) amortized
|
||||
// const Entry * find(const Key& k); O(1)
|
||||
// bool erase(const T& k); O(1)
|
||||
// uint32_t size(); constant
|
||||
// void reserve(uint32_t size); O(MAX(currentOccupancy,size))
|
||||
// void clear(); O(currentOccupancy) (with zero constant for objects
|
||||
// without
|
||||
// destructors)
|
||||
// Iterator getIterator();
|
||||
//
|
||||
// operator[] creates an entry if one does not exist, initializing with the default constructor.
|
||||
// CoalescedHashMap<T> does not support getIterator, but instead supports
|
||||
// const Key *getEntries();
|
||||
//
|
||||
// Use of iterators:
|
||||
//
|
||||
// for(HashMap::Iterator iter = test.getIterator(); !iter.done(); ++iter)
|
||||
// myFunction(iter->first, iter->second);
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
template <class Key, class Value, class HashFn = Hash<Key>, class Allocator = NonTrackingAllocator>
|
||||
class HashMap : public internal::HashMapBase<Key, Value, HashFn, Allocator>
|
||||
{
|
||||
public:
|
||||
typedef internal::HashMapBase<Key, Value, HashFn, Allocator> HashMapBase;
|
||||
typedef typename HashMapBase::Iterator Iterator;
|
||||
|
||||
HashMap(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : HashMapBase(initialTableSize, loadFactor)
|
||||
{
|
||||
}
|
||||
HashMap(uint32_t initialTableSize, float loadFactor, const Allocator& alloc)
|
||||
: HashMapBase(initialTableSize, loadFactor, alloc)
|
||||
{
|
||||
}
|
||||
HashMap(const Allocator& alloc) : HashMapBase(64, 0.75f, alloc)
|
||||
{
|
||||
}
|
||||
Iterator getIterator()
|
||||
{
|
||||
return Iterator(HashMapBase::mBase);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Key, class Value, class HashFn = Hash<Key>, class Allocator = NonTrackingAllocator>
|
||||
class CoalescedHashMap : public internal::HashMapBase<Key, Value, HashFn, Allocator>
|
||||
{
|
||||
public:
|
||||
typedef internal::HashMapBase<Key, Value, HashFn, Allocator> HashMapBase;
|
||||
|
||||
CoalescedHashMap(uint32_t initialTableSize = 64, float loadFactor = 0.75f)
|
||||
: HashMapBase(initialTableSize, loadFactor)
|
||||
{
|
||||
}
|
||||
const Pair<const Key, Value>* getEntries() const
|
||||
{
|
||||
return HashMapBase::mBase.getEntries();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSHASHMAP_H
|
||||
47
Source/ThirdParty/NvCloth/ps/PsIntrinsics.h
vendored
Normal file
47
Source/ThirdParty/NvCloth/ps/PsIntrinsics.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSINTRINSICS_H
|
||||
#define PSFOUNDATION_PSINTRINSICS_H
|
||||
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
|
||||
#if PX_WINDOWS_FAMILY
|
||||
#include "windows/PsWindowsIntrinsics.h"
|
||||
#elif(PX_LINUX || PX_ANDROID || PX_APPLE_FAMILY || PX_PS4 || PX_PS5)
|
||||
#include "unix/PsUnixIntrinsics.h"
|
||||
#elif PX_XBOXONE
|
||||
#include "XboxOne/PsXboxOneIntrinsics.h"
|
||||
#elif PX_SWITCH
|
||||
#include "switch/PsSwitchIntrinsics.h"
|
||||
#else
|
||||
#error "Platform not supported!"
|
||||
#endif
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSINTRINSICS_H
|
||||
699
Source/ThirdParty/NvCloth/ps/PsMathUtils.h
vendored
Normal file
699
Source/ThirdParty/NvCloth/ps/PsMathUtils.h
vendored
Normal file
@@ -0,0 +1,699 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSMATHUTILS_H
|
||||
#define PSFOUNDATION_PSMATHUTILS_H
|
||||
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
#include "foundation/PxTransform.h"
|
||||
#include "foundation/PxMat33.h"
|
||||
#include "NvCloth/ps/Ps.h"
|
||||
#include "NvCloth/ps/PsIntrinsics.h"
|
||||
#include "NvCloth/Callbacks.h"
|
||||
|
||||
// General guideline is: if it's an abstract math function, it belongs here.
|
||||
// If it's a math function where the inputs have specific semantics (e.g.
|
||||
// separateSwingTwist) it doesn't.
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
/**
|
||||
\brief sign returns the sign of its argument. The sign of zero is undefined.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 sign(const physx::PxF32 a)
|
||||
{
|
||||
return physx::intrinsics::sign(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief sign returns the sign of its argument. The sign of zero is undefined.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 sign(const physx::PxF64 a)
|
||||
{
|
||||
return (a >= 0.0) ? 1.0 : -1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief sign returns the sign of its argument. The sign of zero is undefined.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxI32 sign(const physx::PxI32 a)
|
||||
{
|
||||
return (a >= 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Returns true if the two numbers are within eps of each other.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE bool equals(const physx::PxF32 a, const physx::PxF32 b, const physx::PxF32 eps)
|
||||
{
|
||||
return (physx::PxAbs(a - b) < eps);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Returns true if the two numbers are within eps of each other.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE bool equals(const physx::PxF64 a, const physx::PxF64 b, const physx::PxF64 eps)
|
||||
{
|
||||
return (physx::PxAbs(a - b) < eps);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief The floor function returns a floating-point value representing the largest integer that is less than or equal to
|
||||
x.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 floor(const physx::PxF32 a)
|
||||
{
|
||||
return ::floorf(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief The floor function returns a floating-point value representing the largest integer that is less than or equal to
|
||||
x.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 floor(const physx::PxF64 a)
|
||||
{
|
||||
return ::floor(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief The ceil function returns a single value representing the smallest integer that is greater than or equal to x.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 ceil(const physx::PxF32 a)
|
||||
{
|
||||
return ::ceilf(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief The ceil function returns a double value representing the smallest integer that is greater than or equal to x.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 ceil(const physx::PxF64 a)
|
||||
{
|
||||
return ::ceil(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief mod returns the floating-point remainder of x / y.
|
||||
|
||||
If the value of y is 0.0, mod returns a quiet NaN.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 mod(const physx::PxF32 x, const physx::PxF32 y)
|
||||
{
|
||||
return physx::PxF32(::fmodf(x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief mod returns the floating-point remainder of x / y.
|
||||
|
||||
If the value of y is 0.0, mod returns a quiet NaN.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 mod(const physx::PxF64 x, const physx::PxF64 y)
|
||||
{
|
||||
return ::fmod(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Square.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 sqr(const physx::PxF32 a)
|
||||
{
|
||||
return a * a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Square.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 sqr(const physx::PxF64 a)
|
||||
{
|
||||
return a * a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates x raised to the power of y.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 pow(const physx::PxF32 x, const physx::PxF32 y)
|
||||
{
|
||||
return ::powf(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates x raised to the power of y.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 pow(const physx::PxF64 x, const physx::PxF64 y)
|
||||
{
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates e^n
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 exp(const physx::PxF32 a)
|
||||
{
|
||||
return ::expf(a);
|
||||
}
|
||||
/**
|
||||
|
||||
\brief Calculates e^n
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 exp(const physx::PxF64 a)
|
||||
{
|
||||
return ::exp(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates 2^n
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 exp2(const physx::PxF32 a)
|
||||
{
|
||||
return ::expf(a * 0.693147180559945309417f);
|
||||
}
|
||||
/**
|
||||
|
||||
\brief Calculates 2^n
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 exp2(const physx::PxF64 a)
|
||||
{
|
||||
return ::exp(a * 0.693147180559945309417);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates logarithms.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 logE(const physx::PxF32 a)
|
||||
{
|
||||
return ::logf(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates logarithms.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 logE(const physx::PxF64 a)
|
||||
{
|
||||
return ::log(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates logarithms.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 log2(const physx::PxF32 a)
|
||||
{
|
||||
return ::logf(a) / 0.693147180559945309417f;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates logarithms.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 log2(const physx::PxF64 a)
|
||||
{
|
||||
return ::log(a) / 0.693147180559945309417;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates logarithms.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 log10(const physx::PxF32 a)
|
||||
{
|
||||
return ::log10f(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calculates logarithms.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 log10(const physx::PxF64 a)
|
||||
{
|
||||
return ::log10(a);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Converts degrees to radians.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 degToRad(const physx::PxF32 a)
|
||||
{
|
||||
return 0.01745329251994329547f * a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Converts degrees to radians.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 degToRad(const physx::PxF64 a)
|
||||
{
|
||||
return 0.01745329251994329547 * a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Converts radians to degrees.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 radToDeg(const physx::PxF32 a)
|
||||
{
|
||||
return 57.29577951308232286465f * a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Converts radians to degrees.
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF64 radToDeg(const physx::PxF64 a)
|
||||
{
|
||||
return 57.29577951308232286465 * a;
|
||||
}
|
||||
|
||||
//! \brief compute sine and cosine at the same time. There is a 'fsincos' on PC that we probably want to use here
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE void sincos(const physx::PxF32 radians, physx::PxF32& sin, physx::PxF32& cos)
|
||||
{
|
||||
/* something like:
|
||||
_asm fld Local
|
||||
_asm fsincos
|
||||
_asm fstp LocalCos
|
||||
_asm fstp LocalSin
|
||||
*/
|
||||
sin = physx::PxSin(radians);
|
||||
cos = physx::PxCos(radians);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief uniform random number in [a,b]
|
||||
*/
|
||||
PX_FORCE_INLINE physx::PxI32 rand(const physx::PxI32 a, const physx::PxI32 b)
|
||||
{
|
||||
return a + physx::PxI32(::rand() % (b - a + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief uniform random number in [a,b]
|
||||
*/
|
||||
PX_FORCE_INLINE physx::PxF32 rand(const physx::PxF32 a, const physx::PxF32 b)
|
||||
{
|
||||
return a + (b - a) * ::rand() / RAND_MAX;
|
||||
}
|
||||
|
||||
//! \brief return angle between two vectors in radians
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxF32 angle(const physx::PxVec3& v0, const physx::PxVec3& v1)
|
||||
{
|
||||
const physx::PxF32 cos = v0.dot(v1); // |v0|*|v1|*Cos(Angle)
|
||||
const physx::PxF32 sin = (v0.cross(v1)).magnitude(); // |v0|*|v1|*Sin(Angle)
|
||||
return physx::PxAtan2(sin, cos);
|
||||
}
|
||||
|
||||
//! If possible use instead fsel on the dot product /*fsel(d.dot(p),onething,anotherthing);*/
|
||||
//! Compares orientations (more readable, user-friendly function)
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE bool sameDirection(const physx::PxVec3& d, const physx::PxVec3& p)
|
||||
{
|
||||
return d.dot(p) >= 0.0f;
|
||||
}
|
||||
|
||||
//! Checks 2 values have different signs
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE IntBool differentSign(physx::PxReal f0, physx::PxReal f1)
|
||||
{
|
||||
#if !PX_EMSCRIPTEN
|
||||
union
|
||||
{
|
||||
physx::PxU32 u;
|
||||
physx::PxReal f;
|
||||
} u1, u2;
|
||||
u1.f = f0;
|
||||
u2.f = f1;
|
||||
return IntBool((u1.u ^ u2.u) & PX_SIGN_BITMASK);
|
||||
#else
|
||||
// javascript floats are 64-bits...
|
||||
return IntBool( (f0*f1) < 0.0f );
|
||||
#endif
|
||||
}
|
||||
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxMat33 star(const physx::PxVec3& v)
|
||||
{
|
||||
return physx::PxMat33(physx::PxVec3(0, v.z, -v.y), physx::PxVec3(-v.z, 0, v.x), physx::PxVec3(v.y, -v.x, 0));
|
||||
}
|
||||
|
||||
PX_CUDA_CALLABLE PX_INLINE physx::PxVec3 log(const physx::PxQuat& q)
|
||||
{
|
||||
const physx::PxReal s = q.getImaginaryPart().magnitude();
|
||||
if(s < 1e-12f)
|
||||
return physx::PxVec3(0.0f);
|
||||
// force the half-angle to have magnitude <= pi/2
|
||||
physx::PxReal halfAngle = q.w < 0 ? physx::PxAtan2(-s, -q.w) : physx::PxAtan2(s, q.w);
|
||||
NV_CLOTH_ASSERT(halfAngle >= -physx::PxPi / 2 && halfAngle <= physx::PxPi / 2);
|
||||
|
||||
return q.getImaginaryPart().getNormalized() * 2.f * halfAngle;
|
||||
}
|
||||
|
||||
PX_CUDA_CALLABLE PX_INLINE physx::PxQuat exp(const physx::PxVec3& v)
|
||||
{
|
||||
const physx::PxReal m = v.magnitudeSquared();
|
||||
return m < 1e-24f ? physx::PxQuat(physx::PxIdentity) : physx::PxQuat(physx::PxSqrt(m), v * physx::PxRecipSqrt(m));
|
||||
}
|
||||
|
||||
// quat to rotate v0 t0 v1
|
||||
PX_CUDA_CALLABLE PX_INLINE physx::PxQuat rotationArc(const physx::PxVec3& v0, const physx::PxVec3& v1)
|
||||
{
|
||||
const physx::PxVec3 cross = v0.cross(v1);
|
||||
const physx::PxReal d = v0.dot(v1);
|
||||
if(d <= -0.99999f)
|
||||
return (physx::PxAbs(v0.x) < 0.1f ? physx::PxQuat(0.0f, v0.z, -v0.y, 0.0f) : physx::PxQuat(v0.y, -v0.x, 0.0, 0.0)).getNormalized();
|
||||
|
||||
const physx::PxReal s = physx::PxSqrt((1 + d) * 2), r = 1 / s;
|
||||
|
||||
return physx::PxQuat(cross.x * r, cross.y * r, cross.z * r, s * 0.5f).getNormalized();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief returns largest axis
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxU32 largestAxis(const physx::PxVec3& v)
|
||||
{
|
||||
physx::PxU32 m = physx::PxU32(v.y > v.x ? 1 : 0);
|
||||
return v.z > v[m] ? 2 : m;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief returns indices for the largest axis and 2 other axii
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxU32 largestAxis(const physx::PxVec3& v, physx::PxU32& other1, physx::PxU32& other2)
|
||||
{
|
||||
if(v.x >= physx::PxMax(v.y, v.z))
|
||||
{
|
||||
other1 = 1;
|
||||
other2 = 2;
|
||||
return 0;
|
||||
}
|
||||
else if(v.y >= v.z)
|
||||
{
|
||||
other1 = 0;
|
||||
other2 = 2;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
other1 = 0;
|
||||
other2 = 1;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief returns axis with smallest absolute value
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxU32 closestAxis(const physx::PxVec3& v)
|
||||
{
|
||||
physx::PxU32 m = physx::PxU32(physx::PxAbs(v.y) > physx::PxAbs(v.x) ? 1 : 0);
|
||||
return physx::PxAbs(v.z) > physx::PxAbs(v[m]) ? 2 : m;
|
||||
}
|
||||
|
||||
PX_CUDA_CALLABLE PX_INLINE physx::PxU32 closestAxis(const physx::PxVec3& v, physx::PxU32& j, physx::PxU32& k)
|
||||
{
|
||||
// find largest 2D plane projection
|
||||
const physx::PxF32 absPx = physx::PxAbs(v.x);
|
||||
const physx::PxF32 absNy = physx::PxAbs(v.y);
|
||||
const physx::PxF32 absNz = physx::PxAbs(v.z);
|
||||
|
||||
physx::PxU32 m = 0; // x biggest axis
|
||||
j = 1;
|
||||
k = 2;
|
||||
if(absNy > absPx && absNy > absNz)
|
||||
{
|
||||
// y biggest
|
||||
j = 2;
|
||||
k = 0;
|
||||
m = 1;
|
||||
}
|
||||
else if(absNz > absPx)
|
||||
{
|
||||
// z biggest
|
||||
j = 0;
|
||||
k = 1;
|
||||
m = 2;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/*!
|
||||
Extend an edge along its length by a factor
|
||||
*/
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE void makeFatEdge(physx::PxVec3& p0, physx::PxVec3& p1, physx::PxReal fatCoeff)
|
||||
{
|
||||
physx::PxVec3 delta = p1 - p0;
|
||||
|
||||
const physx::PxReal m = delta.magnitude();
|
||||
if(m > 0.0f)
|
||||
{
|
||||
delta *= fatCoeff / m;
|
||||
p0 -= delta;
|
||||
p1 += delta;
|
||||
}
|
||||
}
|
||||
|
||||
//! Compute point as combination of barycentric coordinates
|
||||
PX_CUDA_CALLABLE PX_FORCE_INLINE physx::PxVec3
|
||||
computeBarycentricPoint(const physx::PxVec3& p0, const physx::PxVec3& p1, const physx::PxVec3& p2, physx::PxReal u, physx::PxReal v)
|
||||
{
|
||||
// This seems to confuse the compiler...
|
||||
// return (1.0f - u - v)*p0 + u*p1 + v*p2;
|
||||
const physx::PxF32 w = 1.0f - u - v;
|
||||
return physx::PxVec3(w * p0.x + u * p1.x + v * p2.x, w * p0.y + u * p1.y + v * p2.y, w * p0.z + u * p1.z + v * p2.z);
|
||||
}
|
||||
|
||||
// generates a pair of quaternions (swing, twist) such that in = swing * twist, with
|
||||
// swing.x = 0
|
||||
// twist.y = twist.z = 0, and twist is a unit quat
|
||||
PX_FORCE_INLINE void separateSwingTwist(const physx::PxQuat& q, physx::PxQuat& swing, physx::PxQuat& twist)
|
||||
{
|
||||
twist = q.x != 0.0f ? physx::PxQuat(q.x, 0, 0, q.w).getNormalized() : physx::PxQuat(physx::PxIdentity);
|
||||
swing = q * twist.getConjugate();
|
||||
}
|
||||
|
||||
// generate two tangent vectors to a given normal
|
||||
PX_FORCE_INLINE void normalToTangents(const physx::PxVec3& normal, physx::PxVec3& tangent0, physx::PxVec3& tangent1)
|
||||
{
|
||||
tangent0 = physx::PxAbs(normal.x) < 0.70710678f ? physx::PxVec3(0, -normal.z, normal.y) : physx::PxVec3(-normal.y, normal.x, 0);
|
||||
tangent0.normalize();
|
||||
tangent1 = normal.cross(tangent0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief computes a oriented bounding box around the scaled basis.
|
||||
\param basis Input = skewed basis, Output = (normalized) orthogonal basis.
|
||||
\return Bounding box extent.
|
||||
*/
|
||||
NV_CLOTH_IMPORT physx::PxVec3 optimizeBoundingBox(physx::PxMat33& basis);
|
||||
|
||||
NV_CLOTH_IMPORT physx::PxQuat slerp(const physx::PxReal t, const physx::PxQuat& left, const physx::PxQuat& right);
|
||||
|
||||
PX_CUDA_CALLABLE PX_INLINE physx::PxVec3 ellipseClamp(const physx::PxVec3& point, const physx::PxVec3& radii)
|
||||
{
|
||||
// This function need to be implemented in the header file because
|
||||
// it is included in a spu shader program.
|
||||
|
||||
// finds the closest point on the ellipse to a given point
|
||||
|
||||
// (p.y, p.z) is the input point
|
||||
// (e.y, e.z) are the radii of the ellipse
|
||||
|
||||
// lagrange multiplier method with Newton/Halley hybrid root-finder.
|
||||
// see http://www.geometrictools.com/Documentation/DistancePointToEllipse2.pdf
|
||||
// for proof of Newton step robustness and initial estimate.
|
||||
// Halley converges much faster but sometimes overshoots - when that happens we take
|
||||
// a newton step instead
|
||||
|
||||
// converges in 1-2 iterations where D&C works well, and it's good with 4 iterations
|
||||
// with any ellipse that isn't completely crazy
|
||||
|
||||
const physx::PxU32 MAX_ITERATIONS = 20;
|
||||
const physx::PxReal convergenceThreshold = 1e-4f;
|
||||
|
||||
// iteration requires first quadrant but we recover generality later
|
||||
|
||||
physx::PxVec3 q(0, physx::PxAbs(point.y), physx::PxAbs(point.z));
|
||||
const physx::PxReal tinyEps = 1e-6f; // very close to minor axis is numerically problematic but trivial
|
||||
if(radii.y >= radii.z)
|
||||
{
|
||||
if(q.z < tinyEps)
|
||||
return physx::PxVec3(0, point.y > 0 ? radii.y : -radii.y, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(q.y < tinyEps)
|
||||
return physx::PxVec3(0, 0, point.z > 0 ? radii.z : -radii.z);
|
||||
}
|
||||
|
||||
physx::PxVec3 denom, e2 = radii.multiply(radii), eq = radii.multiply(q);
|
||||
|
||||
// we can use any initial guess which is > maximum(-e.y^2,-e.z^2) and for which f(t) is > 0.
|
||||
// this guess works well near the axes, but is weak along the diagonals.
|
||||
|
||||
physx::PxReal t = physx::PxMax(eq.y - e2.y, eq.z - e2.z);
|
||||
|
||||
for(physx::PxU32 i = 0; i < MAX_ITERATIONS; i++)
|
||||
{
|
||||
denom = physx::PxVec3(0, 1 / (t + e2.y), 1 / (t + e2.z));
|
||||
physx::PxVec3 denom2 = eq.multiply(denom);
|
||||
|
||||
physx::PxVec3 fv = denom2.multiply(denom2);
|
||||
physx::PxReal f = fv.y + fv.z - 1;
|
||||
|
||||
// although in exact arithmetic we are guaranteed f>0, we can get here
|
||||
// on the first iteration via catastrophic cancellation if the point is
|
||||
// very close to the origin. In that case we just behave as if f=0
|
||||
|
||||
if(f < convergenceThreshold)
|
||||
return e2.multiply(point).multiply(denom);
|
||||
|
||||
physx::PxReal df = fv.dot(denom) * -2.0f;
|
||||
t = t - f / df;
|
||||
}
|
||||
|
||||
// we didn't converge, so clamp what we have
|
||||
physx::PxVec3 r = e2.multiply(point).multiply(denom);
|
||||
return r * physx::PxRecipSqrt(sqr(r.y / radii.y) + sqr(r.z / radii.z));
|
||||
}
|
||||
|
||||
PX_CUDA_CALLABLE PX_INLINE physx::PxReal tanHalf(physx::PxReal sin, physx::PxReal cos)
|
||||
{
|
||||
return sin / (1 + cos);
|
||||
}
|
||||
|
||||
PX_INLINE physx::PxQuat quatFromTanQVector(const physx::PxVec3& v)
|
||||
{
|
||||
physx::PxReal v2 = v.dot(v);
|
||||
if(v2 < 1e-12f)
|
||||
return physx::PxQuat(physx::PxIdentity);
|
||||
physx::PxReal d = 1 / (1 + v2);
|
||||
return physx::PxQuat(v.x * 2, v.y * 2, v.z * 2, 1 - v2) * d;
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE physx::PxVec3 cross100(const physx::PxVec3& b)
|
||||
{
|
||||
return physx::PxVec3(0.0f, -b.z, b.y);
|
||||
}
|
||||
PX_FORCE_INLINE physx::PxVec3 cross010(const physx::PxVec3& b)
|
||||
{
|
||||
return physx::PxVec3(b.z, 0.0f, -b.x);
|
||||
}
|
||||
PX_FORCE_INLINE physx::PxVec3 cross001(const physx::PxVec3& b)
|
||||
{
|
||||
return physx::PxVec3(-b.y, b.x, 0.0f);
|
||||
}
|
||||
|
||||
PX_INLINE void decomposeVector(physx::PxVec3& normalCompo, physx::PxVec3& tangentCompo, const physx::PxVec3& outwardDir,
|
||||
const physx::PxVec3& outwardNormal)
|
||||
{
|
||||
normalCompo = outwardNormal * (outwardDir.dot(outwardNormal));
|
||||
tangentCompo = outwardDir - normalCompo;
|
||||
}
|
||||
|
||||
//! \brief Return (i+1)%3
|
||||
// Avoid variable shift for XBox:
|
||||
// PX_INLINE physx::PxU32 Ps::getNextIndex3(physx::PxU32 i) { return (1<<i) & 3; }
|
||||
PX_INLINE physx::PxU32 getNextIndex3(physx::PxU32 i)
|
||||
{
|
||||
return (i + 1 + (i >> 1)) & 3;
|
||||
}
|
||||
|
||||
PX_INLINE physx::PxMat33 rotFrom2Vectors(const physx::PxVec3& from, const physx::PxVec3& to)
|
||||
{
|
||||
// See bottom of http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/index.htm
|
||||
|
||||
// Early exit if to = from
|
||||
if((from - to).magnitudeSquared() < 1e-4f)
|
||||
return physx::PxMat33(physx::PxIdentity);
|
||||
|
||||
// Early exit if to = -from
|
||||
if((from + to).magnitudeSquared() < 1e-4f)
|
||||
return physx::PxMat33::createDiagonal(physx::PxVec3(1.0f, -1.0f, -1.0f));
|
||||
|
||||
physx::PxVec3 n = from.cross(to);
|
||||
|
||||
physx::PxReal C = from.dot(to), S = physx::PxSqrt(1 - C * C), CC = 1 - C;
|
||||
|
||||
physx::PxReal xx = n.x * n.x, yy = n.y * n.y, zz = n.z * n.z, xy = n.x * n.y, yz = n.y * n.z, xz = n.x * n.z;
|
||||
|
||||
physx::PxMat33 R;
|
||||
|
||||
R(0, 0) = 1 + CC * (xx - 1);
|
||||
R(0, 1) = -n.z * S + CC * xy;
|
||||
R(0, 2) = n.y * S + CC * xz;
|
||||
|
||||
R(1, 0) = n.z * S + CC * xy;
|
||||
R(1, 1) = 1 + CC * (yy - 1);
|
||||
R(1, 2) = -n.x * S + CC * yz;
|
||||
|
||||
R(2, 0) = -n.y * S + CC * xz;
|
||||
R(2, 1) = n.x * S + CC * yz;
|
||||
R(2, 2) = 1 + CC * (zz - 1);
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
NV_CLOTH_IMPORT void integrateTransform(const physx::PxTransform& curTrans, const physx::PxVec3& linvel, const physx::PxVec3& angvel,
|
||||
physx::PxReal timeStep, physx::PxTransform& result);
|
||||
|
||||
PX_INLINE void computeBasis(const physx::PxVec3& dir, physx::PxVec3& right, physx::PxVec3& up)
|
||||
{
|
||||
// Derive two remaining vectors
|
||||
if(physx::PxAbs(dir.y) <= 0.9999f)
|
||||
{
|
||||
right = physx::PxVec3(dir.z, 0.0f, -dir.x);
|
||||
right.normalize();
|
||||
|
||||
// PT: normalize not needed for 'up' because dir & right are unit vectors,
|
||||
// and by construction the angle between them is 90 degrees (i.e. sin(angle)=1)
|
||||
up = physx::PxVec3(dir.y * right.z, dir.z * right.x - dir.x * right.z, -dir.y * right.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
right = physx::PxVec3(1.0f, 0.0f, 0.0f);
|
||||
|
||||
up = physx::PxVec3(0.0f, dir.z, -dir.y);
|
||||
up.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
PX_INLINE void computeBasis(const physx::PxVec3& p0, const physx::PxVec3& p1, physx::PxVec3& dir, physx::PxVec3& right, physx::PxVec3& up)
|
||||
{
|
||||
// Compute the new direction vector
|
||||
dir = p1 - p0;
|
||||
dir.normalize();
|
||||
|
||||
// Derive two remaining vectors
|
||||
computeBasis(dir, right, up);
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE bool isAlmostZero(const physx::PxVec3& v)
|
||||
{
|
||||
if(physx::PxAbs(v.x) > 1e-6f || physx::PxAbs(v.y) > 1e-6f || physx::PxAbs(v.z) > 1e-6f)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif
|
||||
97
Source/ThirdParty/NvCloth/ps/PsUserAllocated.h
vendored
Normal file
97
Source/ThirdParty/NvCloth/ps/PsUserAllocated.h
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSUSERALLOCATED_H
|
||||
#define PSFOUNDATION_PSUSERALLOCATED_H
|
||||
|
||||
#include "PsAllocator.h"
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
/**
|
||||
Provides new and delete using a UserAllocator.
|
||||
Guarantees that 'delete x;' uses the UserAllocator too.
|
||||
*/
|
||||
class UserAllocated
|
||||
{
|
||||
public:
|
||||
// PX_SERIALIZATION
|
||||
PX_INLINE void* operator new(size_t, void* address)
|
||||
{
|
||||
return address;
|
||||
}
|
||||
//~PX_SERIALIZATION
|
||||
// Matching operator delete to the above operator new. Don't ask me
|
||||
// how this makes any sense - Nuernberger.
|
||||
PX_INLINE void operator delete(void*, void*)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
PX_INLINE void* operator new(size_t size, Alloc alloc, const char* fileName, int line)
|
||||
{
|
||||
return alloc.allocate(size, fileName, line);
|
||||
}
|
||||
template <typename Alloc>
|
||||
PX_INLINE void* operator new [](size_t size, Alloc alloc, const char* fileName, int line)
|
||||
{ return alloc.allocate(size, fileName, line); }
|
||||
|
||||
// placement delete
|
||||
template <typename Alloc>
|
||||
PX_INLINE void operator delete(void* ptr, Alloc alloc, const char* fileName, int line)
|
||||
{
|
||||
PX_UNUSED(fileName);
|
||||
PX_UNUSED(line);
|
||||
alloc.deallocate(ptr);
|
||||
}
|
||||
template <typename Alloc>
|
||||
PX_INLINE void operator delete [](void* ptr, Alloc alloc, const char* fileName, int line)
|
||||
{
|
||||
PX_UNUSED(fileName);
|
||||
PX_UNUSED(line);
|
||||
alloc.deallocate(ptr);
|
||||
} PX_INLINE void
|
||||
operator delete(void* ptr)
|
||||
{
|
||||
NonTrackingAllocator().deallocate(ptr);
|
||||
}
|
||||
PX_INLINE void operator delete [](void* ptr)
|
||||
{ NonTrackingAllocator().deallocate(ptr); }
|
||||
};
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSUSERALLOCATED_H
|
||||
138
Source/ThirdParty/NvCloth/ps/unix/PsUnixIntrinsics.h
vendored
Normal file
138
Source/ThirdParty/NvCloth/ps/unix/PsUnixIntrinsics.h
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSUNIXINTRINSICS_H
|
||||
#define PSFOUNDATION_PSUNIXINTRINSICS_H
|
||||
|
||||
#include "NvCloth/ps/Ps.h"
|
||||
#include "NvCloth/Callbacks.h"
|
||||
#include <math.h>
|
||||
|
||||
#if PX_ANDROID || (PX_LINUX && !(PX_X64 || PX_X64)) // x86[_64] Linux uses inline assembly for debug break
|
||||
#include <signal.h> // for Ns::debugBreak() { raise(SIGTRAP); }
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
// this file is for internal intrinsics - that is, intrinsics that are used in
|
||||
// cross platform code but do not appear in the API
|
||||
|
||||
#if !(PX_LINUX || PX_ANDROID || PX_PS4 || PX_PS5 || PX_APPLE_FAMILY)
|
||||
#error "This file should only be included by unix builds!!"
|
||||
#endif
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
|
||||
|
||||
PX_FORCE_INLINE void PxMemoryBarrier()
|
||||
{
|
||||
__sync_synchronize();
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the index of the highest set bit. Undefined for zero arg.
|
||||
*/
|
||||
PX_INLINE uint32_t PxHighestSetBitUnsafe(uint32_t v)
|
||||
{
|
||||
|
||||
return 31 - __builtin_clz(v);
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the index of the highest set bit. Undefined for zero arg.
|
||||
*/
|
||||
PX_INLINE int32_t PxLowestSetBitUnsafe(uint32_t v)
|
||||
{
|
||||
return __builtin_ctz(v);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the index of the highest set bit. Returns 32 for v=0.
|
||||
*/
|
||||
PX_INLINE uint32_t PxCountLeadingZeros(uint32_t v)
|
||||
{
|
||||
if(v)
|
||||
return __builtin_clz(v);
|
||||
else
|
||||
return 32;
|
||||
}
|
||||
|
||||
/*!
|
||||
Prefetch aligned 64B x86, 32b ARM around \c ptr+offset.
|
||||
*/
|
||||
PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0)
|
||||
{
|
||||
__builtin_prefetch(reinterpret_cast<const char* PX_RESTRICT>(ptr) + offset, 0, 3);
|
||||
}
|
||||
|
||||
/*!
|
||||
Prefetch \c count bytes starting at \c ptr.
|
||||
*/
|
||||
#if PX_ANDROID || PX_IOS
|
||||
PX_FORCE_INLINE void prefetch(const void* ptr, uint32_t count = 1)
|
||||
{
|
||||
const char* cp = static_cast<const char*>(ptr);
|
||||
size_t p = reinterpret_cast<size_t>(ptr);
|
||||
uint32_t startLine = uint32_t(p >> 5), endLine = uint32_t((p + count - 1) >> 5);
|
||||
uint32_t lines = endLine - startLine + 1;
|
||||
do
|
||||
{
|
||||
PxPrefetchLine(cp);
|
||||
cp += 32;
|
||||
} while(--lines);
|
||||
}
|
||||
#else
|
||||
PX_FORCE_INLINE void prefetch(const void* ptr, uint32_t count = 1)
|
||||
{
|
||||
const char* cp = reinterpret_cast<const char*>(ptr);
|
||||
uint64_t p = size_t(ptr);
|
||||
uint64_t startLine = p >> 6, endLine = (p + count - 1) >> 6;
|
||||
uint64_t lines = endLine - startLine + 1;
|
||||
do
|
||||
{
|
||||
PxPrefetchLine(cp);
|
||||
cp += 64;
|
||||
} while(--lines);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSUNIXINTRINSICS_H
|
||||
173
Source/ThirdParty/NvCloth/ps/windows/PsWindowsIntrinsics.h
vendored
Normal file
173
Source/ThirdParty/NvCloth/ps/windows/PsWindowsIntrinsics.h
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
// 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-2020 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PSFOUNDATION_PSWINDOWSINTRINSICS_H
|
||||
#define PSFOUNDATION_PSWINDOWSINTRINSICS_H
|
||||
|
||||
#include "Ps.h"
|
||||
|
||||
// this file is for internal intrinsics - that is, intrinsics that are used in
|
||||
// cross platform code but do not appear in the API
|
||||
|
||||
#if !PX_WINDOWS_FAMILY
|
||||
#error "This file should only be included by Windows builds!!"
|
||||
#endif
|
||||
|
||||
#pragma warning(push)
|
||||
//'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
|
||||
#pragma warning(disable : 4668)
|
||||
#if PX_VC == 10
|
||||
#pragma warning(disable : 4987) // nonstandard extension used: 'throw (...)'
|
||||
#endif
|
||||
#include <intrin.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4985) // 'symbol name': attributes not present on previous declaration
|
||||
#include <math.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <float.h>
|
||||
#include <mmintrin.h>
|
||||
|
||||
#pragma intrinsic(_BitScanForward)
|
||||
#pragma intrinsic(_BitScanReverse)
|
||||
|
||||
/** \brief NVidia namespace */
|
||||
namespace nv
|
||||
{
|
||||
/** \brief nvcloth namespace */
|
||||
namespace cloth
|
||||
{
|
||||
namespace ps
|
||||
{
|
||||
|
||||
/*
|
||||
* Implements a memory barrier
|
||||
*/
|
||||
PX_FORCE_INLINE void PxMemoryBarrier()
|
||||
{
|
||||
_ReadWriteBarrier();
|
||||
/* long Barrier;
|
||||
__asm {
|
||||
xchg Barrier, eax
|
||||
}*/
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the index of the highest set bit. Not valid for zero arg.
|
||||
*/
|
||||
PX_FORCE_INLINE uint32_t PxHighestSetBitUnsafe(uint32_t v)
|
||||
{
|
||||
unsigned long retval;
|
||||
_BitScanReverse(&retval, v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the index of the highest set bit. Undefined for zero arg.
|
||||
*/
|
||||
PX_FORCE_INLINE uint32_t PxLowestSetBitUnsafe(uint32_t v)
|
||||
{
|
||||
unsigned long retval;
|
||||
_BitScanForward(&retval, v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the number of leading zeros in v. Returns 32 for v=0.
|
||||
*/
|
||||
PX_FORCE_INLINE uint32_t PxCountLeadingZeros(uint32_t v)
|
||||
{
|
||||
if(v)
|
||||
{
|
||||
unsigned long bsr = (unsigned long)-1;
|
||||
_BitScanReverse(&bsr, v);
|
||||
return 31 - bsr;
|
||||
}
|
||||
else
|
||||
return 32;
|
||||
}
|
||||
|
||||
/*!
|
||||
Prefetch aligned cache size around \c ptr+offset.
|
||||
*/
|
||||
#if !PX_ARM
|
||||
PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0)
|
||||
{
|
||||
// cache line on X86/X64 is 64-bytes so a 128-byte prefetch would require 2 prefetches.
|
||||
// However, we can only dispatch a limited number of prefetch instructions so we opt to prefetch just 1 cache line
|
||||
/*_mm_prefetch(((const char*)ptr + offset), _MM_HINT_T0);*/
|
||||
// We get slightly better performance prefetching to non-temporal addresses instead of all cache levels
|
||||
_mm_prefetch(((const char*)ptr + offset), _MM_HINT_NTA);
|
||||
}
|
||||
#else
|
||||
PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0)
|
||||
{
|
||||
// arm does have 32b cache line size
|
||||
__prefetch(((const char*)ptr + offset));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Prefetch \c count bytes starting at \c ptr.
|
||||
*/
|
||||
#if !PX_ARM
|
||||
PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1)
|
||||
{
|
||||
const char* cp = (char*)ptr;
|
||||
uint64_t p = size_t(ptr);
|
||||
uint64_t startLine = p >> 6, endLine = (p + count - 1) >> 6;
|
||||
uint64_t lines = endLine - startLine + 1;
|
||||
do
|
||||
{
|
||||
PxPrefetchLine(cp);
|
||||
cp += 64;
|
||||
} while(--lines);
|
||||
}
|
||||
#else
|
||||
PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1)
|
||||
{
|
||||
const char* cp = (char*)ptr;
|
||||
uint32_t p = size_t(ptr);
|
||||
uint32_t startLine = p >> 5, endLine = (p + count - 1) >> 5;
|
||||
uint32_t lines = endLine - startLine + 1;
|
||||
do
|
||||
{
|
||||
PxPrefetchLine(cp);
|
||||
cp += 32;
|
||||
} while(--lines);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ps
|
||||
} // namespace cloth
|
||||
} // namespace nv
|
||||
|
||||
#endif // #ifndef PSFOUNDATION_PSWINDOWSINTRINSICS_H
|
||||
Reference in New Issue
Block a user