diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /sdk/extensions/physx | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/extensions/physx')
29 files changed, 1899 insertions, 2164 deletions
diff --git a/sdk/extensions/physx/include/NvBlastExtCustomProfiler.h b/sdk/extensions/physx/include/NvBlastExtCustomProfiler.h new file mode 100644 index 0000000..4130964 --- /dev/null +++ b/sdk/extensions/physx/include/NvBlastExtCustomProfiler.h @@ -0,0 +1,143 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTDEFAULTPROFILER_H +#define NVBLASTDEFAULTPROFILER_H + +#include "NvBlastProfiler.h" +#include "PxProfiler.h" + +#if NV_NVTX +#include "nvToolsExt.h" +NV_INLINE void platformZoneStart(const char* name) { nvtxRangePushA(name); } +NV_INLINE void platformZoneEnd() { nvtxRangePop(); } + +#elif NV_XBOXONE +#include "xboxone/NvBlastProfilerXB1.h" + +#elif NV_PS4 +#include "ps4/NvBlastProfilerPS4.h" + +#else +NV_INLINE void platformZoneStart(const char*) { } +NV_INLINE void platformZoneEnd() { } + +#endif + +#define SUPPORTS_THREAD_LOCAL (!NV_VC || NV_VC > 12) + +namespace Nv +{ +namespace Blast +{ + +struct ExtProfileData +{ + const char* name; + void* data; +}; + +#if SUPPORTS_THREAD_LOCAL +static const int32_t PROFILER_MAX_NESTED_DEPTH = 64; +static thread_local ExtProfileData th_ProfileData[PROFILER_MAX_NESTED_DEPTH]; +static thread_local int32_t th_depth = 0; +#endif + +class ExtCustomProfiler : public ProfilerCallback +{ +public: + ExtCustomProfiler() : m_platformEnabled(false) {} + + virtual void zoneStart(const char* name) override + { + +#if SUPPORTS_THREAD_LOCAL + if (PxGetProfilerCallback()) + { + void* data = PxGetProfilerCallback()->zoneStart(name, false, 0xb1a57); + + if (th_depth < PROFILER_MAX_NESTED_DEPTH && th_depth >= 0) + { + th_ProfileData[th_depth].name = name; + th_ProfileData[th_depth].data = data; + th_depth++; + } + else + { + assert(th_depth < PROFILER_MAX_NESTED_DEPTH && th_depth >= 0); + } + } +#endif + + if (m_platformEnabled) + { + platformZoneStart(name); + } + } + + virtual void zoneEnd() override + { + +#if SUPPORTS_THREAD_LOCAL + if (PxGetProfilerCallback()) + { + th_depth--; + + if (th_depth >= 0) + { + ExtProfileData& pd = th_ProfileData[th_depth]; + PxGetProfilerCallback()->zoneEnd(pd.data, pd.name, false, 0xb1a57); + } + else + { + assert(th_depth >= 0); + } + } +#endif + + if (m_platformEnabled) + { + platformZoneEnd(); + } + } + + + void setPlatformEnabled(bool enabled) + { + m_platformEnabled = enabled; + } + +private: + bool m_platformEnabled; +}; + +} // namespace Blast +} // namespace Nv + + +#endif diff --git a/sdk/extensions/physx/include/NvBlastExtImpactDamageManager.h b/sdk/extensions/physx/include/NvBlastExtImpactDamageManager.h index ac3576d..28d0947 100644 --- a/sdk/extensions/physx/include/NvBlastExtImpactDamageManager.h +++ b/sdk/extensions/physx/include/NvBlastExtImpactDamageManager.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTIMPACTDAMAGEMANAGER_H #define NVBLASTEXTIMPACTDAMAGEMANAGER_H @@ -43,16 +61,27 @@ Impact Damage Manager Settings. */ struct ExtImpactSettings { - bool isSelfCollissionEnabled; //!< family's self collision enabled - float fragility; //!< global fragility factor + bool isSelfCollissionEnabled; //!< family's self collision enabled. + bool shearDamage; //!< use shear damage program (otherwise simple radial damage is used) + float impulseMinThreshold; //!< min impulse value to apply impact damage. + float impulseMaxThreshold; //!< max impulse value, damage is interpolated value between min and max impulses. + float damageMax; //!< max damage to be applied (if impulse is >= impulseMaxThreshold). + float damageRadiusMax; //!< max penetration depth (if impulse is >= impulseMaxThreshold). + float damageAttenuation; //!< penetration attenuation ([0..1], where 1 means damage attenuates linearly from 0 to max penetration depth). ExtImpactDamageFunction damageFunction; //!< custom damage function, can be nullptr, default internal one will be used in that case. - void* damageFunctionData; //!< data to be passed in custom damage function + void* damageFunctionData; //!< data to be passed in custom damage function. ExtImpactSettings() : isSelfCollissionEnabled(false), - fragility(1.0f), - damageFunction(nullptr) + shearDamage(true), + impulseMinThreshold(0.0f), + impulseMaxThreshold(1000000.0f), + damageMax(100.f), + damageRadiusMax(5.0f), + damageAttenuation(1.f), + damageFunction(nullptr), + damageFunctionData(nullptr) {} }; diff --git a/sdk/extensions/physx/include/NvBlastExtPx.h b/sdk/extensions/physx/include/NvBlastExtPx.h index b2d938b..a34182a 100644 --- a/sdk/extensions/physx/include/NvBlastExtPx.h +++ b/sdk/extensions/physx/include/NvBlastExtPx.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPX_H #define NVBLASTEXTPX_H diff --git a/sdk/extensions/physx/include/NvBlastExtPxActor.h b/sdk/extensions/physx/include/NvBlastExtPxActor.h index 994ace7..79d6404 100644 --- a/sdk/extensions/physx/include/NvBlastExtPxActor.h +++ b/sdk/extensions/physx/include/NvBlastExtPxActor.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXACTOR_H #define NVBLASTEXTPXACTOR_H diff --git a/sdk/extensions/physx/include/NvBlastExtPxAsset.h b/sdk/extensions/physx/include/NvBlastExtPxAsset.h index a4dbe0e..136f0d2 100644 --- a/sdk/extensions/physx/include/NvBlastExtPxAsset.h +++ b/sdk/extensions/physx/include/NvBlastExtPxAsset.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXASSET_H #define NVBLASTEXTPXASSET_H @@ -114,6 +132,16 @@ public: */ static ExtPxAsset* create(const ExtPxAssetDesc& desc, TkFramework& framework); + /** + Create a new ExtPxAsset. + + \param[in] desc The ExtPxAssetDesc descriptor to be used, @see ExtPxAssetDesc. + \param[in] framework The TkFramework instance to be used to create TkAsset. + + \return the new ExtPxAsset if successful, NULL otherwise. + */ + static ExtPxAsset* create(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework); + /* Factory method for deserialization @@ -123,17 +151,18 @@ public: */ static ExtPxAsset* create(TkAsset* asset); + /* + Create a new ExtPxAsset. - /** - Deserialize an ExtPxAsset object from the given stream. + \param[in] asset TkAsset from which ExtPxAsset will be created + \param[in] chunks Array of physics chunks descriptors + \param[in] chunkCount Size of chunks descriptors array - \param[in] stream User-defined stream object. - \param[in] framework The TkFramework instance to be used to deserialize TkAsset. - \param[in] physics The PxPhysics instance to be to deserialize PxConvexMesh(s). - \return pointer the deserialized ExtPxAsset object if successful, or NULL if unsuccessful. + \return the new ExtPxAsset if successful, NULL otherwise. + */ - static ExtPxAsset* deserialize(physx::general_PxIOStream2::PxFileBuf& stream, TkFramework& framework, physx::PxPhysics& physics); + static ExtPxAsset* create(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount); /** Release this ExtPxAsset. @@ -141,16 +170,6 @@ public: virtual void release() = 0; /** - Write the asset's data to the user-defined PxFileBuf stream. Underlying TkAsset would be also serialized. - - \param[in] stream User-defined stream object. - \param[in] cooking The PxCooking instance to be used to serialize PxConvexMesh(s). - - \return true if serialization was successful, false otherwise. - */ - virtual bool serialize(physx::general_PxIOStream2::PxFileBuf& stream, physx::PxCooking& cooking) const = 0; - - /** Every ExtPxAsset has corresponding TkAsset. /return a pointer to TkAsset actor. @@ -187,6 +206,28 @@ public: virtual const ExtPxSubchunk* getSubchunks() const = 0; /** + Get the default NvBlastActorDesc to be used when creating family from this asset. It is called 'default', + because it can be overwritten in ExtPxManager::createFamily(...) function. + + Initially default NvBlastActorDesc contains only uniform health values, and 'nullptr' is set in arrays of health. + Call setUniformHealth(false) in order to set health per bond/chunk. You can then access directly values stored in NvBlastActorDesc, + change them and they will be serialized/deserialized as withing asset itself. + + NOTE: do not change actual pointers in NvBlastActorDesc: initialBondHealths and initialSupportChunkHealths. You can change actual values + in those arrays or if they are 'nullptr' call setUniformHealth(false) before. Or call setUniformHealth(true) to make them 'nullptr'. + + \return the default NvBlastActorDesc. + */ + virtual NvBlastActorDesc& getDefaultActorDesc() = 0; + + virtual const NvBlastActorDesc& getDefaultActorDesc() const = 0; + + /** + Set if uniform health values should be used in NvBlastActorDesc or per bond/chunk ones. @see getDefaultActorDesc. + */ + virtual void setUniformHealth(bool enabled) = 0; + + /** Pointer field available to the user. */ void* userData; diff --git a/sdk/extensions/physx/include/NvBlastExtPxFamily.h b/sdk/extensions/physx/include/NvBlastExtPxFamily.h index 7805c15..ae48769 100644 --- a/sdk/extensions/physx/include/NvBlastExtPxFamily.h +++ b/sdk/extensions/physx/include/NvBlastExtPxFamily.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXFAMILY_H #define NVBLASTEXTPXFAMILY_H diff --git a/sdk/extensions/physx/include/NvBlastExtPxListener.h b/sdk/extensions/physx/include/NvBlastExtPxListener.h index 4c43283..f3a52a3 100644 --- a/sdk/extensions/physx/include/NvBlastExtPxListener.h +++ b/sdk/extensions/physx/include/NvBlastExtPxListener.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXLISTENER_H #define NVBLASTEXTPXLISTENER_H diff --git a/sdk/extensions/physx/include/NvBlastExtPxManager.h b/sdk/extensions/physx/include/NvBlastExtPxManager.h index 9d73898..d4dd50c 100644 --- a/sdk/extensions/physx/include/NvBlastExtPxManager.h +++ b/sdk/extensions/physx/include/NvBlastExtPxManager.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXMANAGER_H #define NVBLASTEXTPXMANAGER_H @@ -54,9 +72,9 @@ Used to create Physics Family. */ struct ExtPxFamilyDesc { - const ExtPxAsset* pxAsset; //!< px asset to create from, pointer will be stored in family. - NvBlastActorDesc actorDesc; //!< actor descriptor to be used when creating TkActor. - TkGroup* group; //!< if not nullptr, created TkActor will be placed in group + const ExtPxAsset* pxAsset; //!< px asset to create from, pointer will be stored in family. + const NvBlastActorDesc* actorDesc; //!< actor descriptor to be used when creating TkActor. If nullptr, default NvBlastActorDesc from ExtPxAsset will be used. + TkGroup* group; //!< if not nullptr, created TkActor will be placed in group }; diff --git a/sdk/extensions/physx/include/NvBlastExtPxStressSolver.h b/sdk/extensions/physx/include/NvBlastExtPxStressSolver.h new file mode 100644 index 0000000..fcf4d85 --- /dev/null +++ b/sdk/extensions/physx/include/NvBlastExtPxStressSolver.h @@ -0,0 +1,98 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTPXSTRESSSOLVER_H +#define NVBLASTEXTPXSTRESSSOLVER_H + +#include "NvBlastExtStressSolver.h" +#include "common/PxRenderBuffer.h" + + +namespace Nv +{ +namespace Blast +{ + +// forward declarations +class ExtPxFamily; + + +/** +Px Stress Solver. Px wrapper over ExtStressSolver. + +Uses ExtPxFamily and ExtStressSolver. see #ExtStressSolver for more details. +Works on both dynamic and static actor's within family. +For static actors it applies gravity. +For dynamic actors it applies centrifugal force. +*/ +class NV_DLL_EXPORT ExtPxStressSolver +{ +public: + //////// creation //////// + + /** + Create a new ExtStressSolver. + + \param[in] family The ExtPxFamily instance to calculate stress on. + \param[in] settings The settings to be set on ExtStressSolver. + + \return the new ExtStressSolver if successful, NULL otherwise. + */ + static ExtPxStressSolver* create(ExtPxFamily& family, ExtStressSolverSettings settings = ExtStressSolverSettings()); + + + //////// interface //////// + + /** + Release this stress solver. + */ + virtual void release() = 0; + + /** + Get actual ExtStressSolver used. + + \return the pointer to ExtStressSolver used internally. + */ + virtual ExtStressSolver& getSolver() const = 0; + + /** + Update stress solver. + + Calculate stress and optionally apply damage. + + \param[in] doDamage If 'true' damage will be applied after stress solver. + */ + virtual void update(bool doDamage = true) = 0; +}; + + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTPXSTRESSSOLVER_H diff --git a/sdk/extensions/physx/include/NvBlastExtPxTask.h b/sdk/extensions/physx/include/NvBlastExtPxTask.h new file mode 100644 index 0000000..b692ce8 --- /dev/null +++ b/sdk/extensions/physx/include/NvBlastExtPxTask.h @@ -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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTPXTASK_H +#define NVBLASTEXTPXTASK_H + +#include "NvBlastTypes.h" + + +// Forward declarations +namespace physx +{ +class PxTaskManager; +} + + +namespace Nv +{ +namespace Blast +{ + + +// Forward declarations +class TkGroup; + + +/** +Uses a physx::PxTaskManager to process a TkGroup concurrently. +*/ +class NV_DLL_EXPORT ExtGroupTaskManager +{ +protected: + virtual ~ExtGroupTaskManager() {} + +public: + static ExtGroupTaskManager* create(physx::PxTaskManager&); + static ExtGroupTaskManager* create(physx::PxTaskManager&, TkGroup&); + + /** + Change the group to process. Cannot be changed while the group being processed. + */ + virtual void setGroup(TkGroup*) = 0; + + /** + Start processing the group. + The parallelizing strategy is to have all worker tasks running concurrently. + The number of started tasks may be smaller than the requested value, + when the task manager's dispatcher thread count or the number of group jobs are + smaller. + + \param[in] workerCount The number of worker tasks to start, + 0 uses the dispatcher's worker thread count. + \return The number of worker tasks started. + */ + virtual uint32_t process(uint32_t workerCount = 0) = 0; + + /** + Wait for the group to end processing. + */ + virtual bool wait(bool block = true) = 0; + + /** + Release this object. + */ + virtual void release() = 0; +}; + + +} // namespace Blast +} // namespace Nv + +#endif // NVBLASTEXTPXTASK_H diff --git a/sdk/extensions/physx/include/NvBlastExtStressSolver.h b/sdk/extensions/physx/include/NvBlastExtStressSolver.h deleted file mode 100644 index 2fd389d..0000000 --- a/sdk/extensions/physx/include/NvBlastExtStressSolver.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ - -#ifndef NVBLASTEXTSTRESSSOLVER_H -#define NVBLASTEXTSTRESSSOLVER_H - -#include "common/PxRenderBuffer.h" -#include <vector> -#include "NvPreprocessor.h" - - -namespace Nv -{ -namespace Blast -{ - -// forward declarations -class ExtPxFamily; -class ExtPxActor; - -/** -Stress Solver Settings - -Stress on every bond is calculated as -stress = bond.linearStress * stressLinearFactor + bond.angularStress * stressAngularFactor -where: -bond.linearStress - is linear stress force on particular bond -bond.angularStress - is angular stress force on particular bond -stressLinearFactor, stressAngularFactor - are a multiplier parameter set by this struct - -Support graph reduction: -2 ^ reduction level = max node count to be aggregated during graph reduction, so 0 is 2 % 0 = 1, basically use support graph. -So N nodes graph will be simplified to contain ~ N / (2 ^ reduction level) -*/ -struct ExtStressSolverSettings -{ - float stressLinearFactor; //!< linear stress on bond multiplier - float stressAngularFactor; //!< angular stress on bond multiplier - uint32_t bondIterationsPerFrame; //!< number of bond iterations to perform per frame, @see getIterationsPerFrame() below - uint32_t graphReductionLevel; //!< graph reduction level - - ExtStressSolverSettings() : - stressLinearFactor(0.00004f), - stressAngularFactor(0.00007f), - bondIterationsPerFrame(18000), - graphReductionLevel(3) - {} -}; - - -/** -Stress Solver. - -Uses ExtPxFamily, allocates and prepares it's graph once when it's created. Then it's being quickly updated on every -actor split. -Works on both dynamic and static actor's within family. -For static actors it applies gravity. -For dynamic actors it applies centrifugal force. -Additionally applyImpulse() method can be used to apply external impulse (like impact damage). -*/ -class NV_DLL_EXPORT ExtStressSolver -{ -public: - //////// creation //////// - - /** - Create a new ExtStressSolver. - - \param[in] family The ExtPxFamily instance to calculate stress on. - \param[in] settings The settings to be set on ExtStressSolver. - - \return the new ExtStressSolver if successful, NULL otherwise. - */ - static ExtStressSolver* create(ExtPxFamily& family, ExtStressSolverSettings settings = ExtStressSolverSettings()); - - - //////// interface //////// - - /** - Release this stress solver. - */ - virtual void release() = 0; - - /** - Set stress solver settings. - Changing graph reduction level will lead to graph being rebuilt (which is fast, but still not recommended). - All other settings are applied instantly and can be changed every frame. - - \param[in] settings The settings to be set on ExtStressSolver. - */ - virtual void setSettings(const ExtStressSolverSettings& settings) = 0; - - /** - Get stress solver settings. - - \return the pointer to stress solver settings currently set. - */ - virtual const ExtStressSolverSettings& getSettings() const = 0; - - /** - Apply external impulse on particular actor of family - - \param[in] actor The ExtPxActor to apply impulse on. - \param[in] position Local position in actor's coordinates to apply impulse on. - \param[in] force Impulse to apply (kg * m / s). - */ - virtual void applyImpulse(ExtPxActor& actor, physx::PxVec3 position, physx::PxVec3 force) = 0; - - /** - Update stress solver. - - Calculate stress and optionally apply damage. - - \param[in] doDamage If 'true' damage will be applied after stress solver. - */ - virtual void update(bool doDamage = true) = 0; - - /** - Reset stress solver. - - Stress solver uses warm start internally, calling this function will flush all previous data calculated and also zeros frame count. - This function is to be used for debug purposes. - */ - virtual void reset() = 0; - - /** - Debug Render Mode - */ - enum DebugRenderMode - { - STRESS_GRAPH = 0, //!< render only stress graph - STRESS_GRAPH_NODES_IMPULSES = 1, //!< render stress graph + nodes impulses after solving stress - STRESS_GRAPH_BONDS_IMPULSES = 2 //!< render stress graph + bonds impulses after solving stress - }; - - /** - Fill debug render for passed array of support graph nodes. - - \param[in] nodes Node indices of support graph to debug render for. - \param[out] lines Lines array to fill. - \param[in] mode Debug render mode. - \param[in] scale Scale to be applied on impulses. - */ - virtual void fillDebugRender(const std::vector<uint32_t>& nodes, std::vector<physx::PxDebugLine>& lines, DebugRenderMode mode, float scale = 1.0f) = 0; - - /** - Get stress solver linear error. - - \return the total linear error of stress calculation. - */ - virtual float getStressErrorLinear() const = 0; - - /** - Get stress solver angular error. - - \return the total angular error of stress calculation. - */ - virtual float getStressErrorAngular() const = 0; - - /** - Get stress solver total iterations count since it was created (or reset). - - \return the iterations count. - */ - virtual uint32_t getIterationCount() const = 0; - - /** - Get stress solver total frames count (update() calls) since it was created (or reset). - - \return the frames count. - */ - virtual uint32_t getFrameCount() const = 0; - - /** - Get stress solver bonds count, after graph reduction was applied. - - \return the bonds count. - */ - virtual uint32_t getBondCount() const = 0; - - - //////// helpers //////// - - /** - Get iteration per frame (update() call). - - Helper method to know how many solver iterations are made per frame. - - \return the iterations per frame count. - */ - uint32_t getIterationsPerFrame() const - { - uint32_t perFrame = getSettings().bondIterationsPerFrame / (getBondCount() + 1); - return perFrame > 0 ? perFrame : 1; - } -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTSTRESSSOLVER_H diff --git a/sdk/extensions/physx/include/NvBlastExtSync.h b/sdk/extensions/physx/include/NvBlastExtSync.h index 805378a..170a386 100644 --- a/sdk/extensions/physx/include/NvBlastExtSync.h +++ b/sdk/extensions/physx/include/NvBlastExtSync.h @@ -1,20 +1,38 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTSYNC_H #define NVBLASTEXTSYNC_H #include "NvBlastTk.h" #include "foundation/PxTransform.h" -#include "foundation/PxAllocatorCallback.h" #include "NvPreprocessor.h" +#include "NvBlastGlobals.h" namespace Nv @@ -80,7 +98,7 @@ struct ExtSyncEventInstance : public ExtSyncEvent ExtSyncEvent* clone() const override { - return new (NvBlastTkFrameworkGet()->getAllocatorCallback().allocate(sizeof(T), nullptr, __FILE__, __LINE__)) T(*(T*)this); + return NVBLAST_NEW (T) (*(T*)this); } }; diff --git a/sdk/extensions/physx/include/NvBlastPxCallbacks.h b/sdk/extensions/physx/include/NvBlastPxCallbacks.h new file mode 100644 index 0000000..323f298 --- /dev/null +++ b/sdk/extensions/physx/include/NvBlastPxCallbacks.h @@ -0,0 +1,73 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTPXCALLBACKS_H +#define NVBLASTPXCALLBACKS_H + +#include "NvBlastGlobals.h" +#include "PxErrorCallback.h" +#include "PxAllocatorCallback.h" + +/** +This file contains helper functions to get PxShared compatible versions of global AllocatorCallback and ErrorCallback. +*/ + + +NV_INLINE physx::PxErrorCallback& NvBlastGetPxErrorCallback() +{ + class PxErrorCallbackWrapper : public physx::PxErrorCallback + { + virtual void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line) override + { + NvBlastGlobalGetErrorCallback()->reportError((Nv::Blast::ErrorCode::Enum)code, message, file, line); + } + }; + static PxErrorCallbackWrapper wrapper; + return wrapper; +} + +NV_INLINE physx::PxAllocatorCallback& NvBlastGetPxAllocatorCallback() +{ + class PxAllocatorCallbackWrapper : public physx::PxAllocatorCallback + { + virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) override + { + return NvBlastGlobalGetAllocatorCallback()->allocate(size, typeName, filename, line); + } + + virtual void deallocate(void* ptr) override + { + NvBlastGlobalGetAllocatorCallback()->deallocate(ptr); + } + }; + static PxAllocatorCallbackWrapper wrapper; + return wrapper; +} + + +#endif // #ifndef NVBLASTPXCALLBACKS_H diff --git a/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp b/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp index 54d2696..fc1f514 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtImpactDamageManager.h" #include "NvBlastExtPxManager.h" @@ -17,8 +35,7 @@ #include "NvBlastAssert.h" #include "NvBlastExtDamageShaders.h" -#include "NvBlastExtArray.h" -#include "NvBlastExtDefs.h" +#include "NvBlastArray.h" #include "PxRigidDynamic.h" #include "PxSimulationEventCallback.h" @@ -59,7 +76,7 @@ public: virtual void release() override { - NVBLASTEXT_DELETE(this, ExtImpactDamageManagerImpl); + NVBLAST_DELETE(this, ExtImpactDamageManagerImpl); } @@ -124,7 +141,7 @@ private: ExtPxManager* m_pxManager; ExtImpactSettings m_settings; PxManagerListener m_listener; - ExtArray<PxContactPairPoint>::type m_pairPointBuffer; + Array<PxContactPairPoint>::type m_pairPointBuffer; bool m_usePxUserData; struct ImpactDamageData @@ -135,10 +152,10 @@ private: PxShape* shape; }; - ExtArray<ImpactDamageData>::type m_impactDamageBuffer; + Array<ImpactDamageData>::type m_impactDamageBuffer; NvBlastFractureBuffers m_fractureBuffers; - ExtArray<uint8_t>::type m_fractureData; + Array<uint8_t>::type m_fractureData; }; @@ -148,7 +165,7 @@ private: ExtImpactDamageManager* ExtImpactDamageManager::create(ExtPxManager* pxManager, ExtImpactSettings settings) { - return NVBLASTEXT_NEW(ExtImpactDamageManagerImpl) (pxManager, settings); + return NVBLAST_NEW(ExtImpactDamageManagerImpl) (pxManager, settings); } @@ -310,12 +327,6 @@ void ExtImpactDamageManagerImpl::onContact(const PxContactPairHeader& pairHeader // ExtImpactDamageManager damage processing /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -float clampedLerp(float from, float to, float t) -{ - t = PxClamp(t, 0.0f, 1.0f); - return (1 - t) * from + to * t; -} - void ExtImpactDamageManagerImpl::applyDamage() { const auto damageFn = m_settings.damageFunction; @@ -323,10 +334,7 @@ void ExtImpactDamageManagerImpl::applyDamage() for (const ImpactDamageData& data : m_impactDamageBuffer) { - float forceMag = data.force.magnitude(); - float acceleration = forceMag / data.actor->getPhysXActor().getMass(); - float factor = acceleration * m_settings.fragility * 0.001f; - if (factor > 0.05f) + if (data.force.magnitudeSquared() > m_settings.impulseMinThreshold * m_settings.impulseMinThreshold) { PxTransform t(data.actor->getPhysXActor().getGlobalPose().getInverse()); PxVec3 force = t.rotate(data.force); @@ -334,7 +342,7 @@ void ExtImpactDamageManagerImpl::applyDamage() if (!damageFn || !damageFn(damageFnData, data.actor, data.shape, position, force)) { - damageActor(data.actor, data.shape, position, force*.00001f); + damageActor(data.actor, data.shape, position, force); } } } @@ -358,32 +366,73 @@ void ExtImpactDamageManagerImpl::damageActor(ExtPxActor* actor, PxShape* /*shape { ensureBuffersSize(actor); - NvBlastExtShearDamageDesc damage[] = { - { - { force[0], force[1], force[2] }, // shear - { position[0], position[1], position[2] } // position - } - }; + const float f0 = m_settings.impulseMinThreshold; + const float f1 = m_settings.impulseMaxThreshold; + const float impulse01 = PxClamp<float>((force.magnitude() - f0) / PxMax<float>(f1 - f0, 1.0f), 0, 1); + const float damage = m_settings.damageMax * impulse01; - const void* familyMaterial = actor->getTkActor().getFamily().getMaterial(); + const void* material = actor->getTkActor().getFamily().getMaterial(); + if (!material) + { + return; + } - // default material params settings - const NvBlastExtMaterial defaultMaterial = { 3.0f, 0.1f, 0.2f, 1.5f + 1e-5f, 0.95f }; + const float normalizedDamage = reinterpret_cast<const NvBlastExtMaterial*>(material)->getNormalizedDamage(damage); + if (normalizedDamage == 0.f) + { + return; + } + + const PxVec3 normal = force.getNormalized(); + const float maxDistance = m_settings.damageRadiusMax * impulse01; + const float minDistance = maxDistance * PxClamp<float>(1 - m_settings.damageAttenuation, 0, 1); NvBlastProgramParams programParams; programParams.damageDescCount = 1; - programParams.damageDescBuffer = &damage; - programParams.material = familyMaterial == nullptr ? &defaultMaterial : familyMaterial; + programParams.material = nullptr; + NvBlastDamageProgram program; - NvBlastDamageProgram program = { - NvBlastExtShearGraphShader, - NvBlastExtShearSubgraphShader - }; + if (m_settings.shearDamage) + { + NvBlastExtShearDamageDesc desc[] = { + { + normalizedDamage, + { normal[0], normal[1], normal[2] }, // shear + { position[0], position[1], position[2] }, // position + minDistance, + maxDistance + } + }; + + programParams.damageDescBuffer = &desc; + + program.graphShaderFunction = NvBlastExtShearGraphShader; + program.subgraphShaderFunction = NvBlastExtShearSubgraphShader; + + NvBlastFractureBuffers fractureEvents = m_fractureBuffers; + actor->getTkActor().generateFracture(&fractureEvents, program, &programParams); + actor->getTkActor().applyFracture(nullptr, &fractureEvents); + } + else + { + NvBlastExtRadialDamageDesc desc[] = { + { + normalizedDamage, + { position[0], position[1], position[2] }, // position + minDistance, + maxDistance + } + }; + + programParams.damageDescBuffer = &desc; - NvBlastFractureBuffers fractureEvents = m_fractureBuffers; + program.graphShaderFunction = NvBlastExtFalloffGraphShader; + program.subgraphShaderFunction = NvBlastExtFalloffSubgraphShader; - actor->getTkActor().generateFracture(&fractureEvents, program, &programParams); - actor->getTkActor().applyFracture(nullptr, &fractureEvents); + NvBlastFractureBuffers fractureEvents = m_fractureBuffers; + actor->getTkActor().generateFracture(&fractureEvents, program, &programParams); + actor->getTkActor().applyFracture(nullptr, &fractureEvents); + } } diff --git a/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.cpp b/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.cpp deleted file mode 100644 index 8329de5..0000000 --- a/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.cpp +++ /dev/null @@ -1,1312 +0,0 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ - -#include "NvBlastExtImpulseStressSolver.h" -#include "NvBlastExtPxAsset.h" -#include "NvBlastExtPxFamily.h" -#include "NvBlastExtPxActor.h" -#include "NvBlastAssert.h" -#include "NvBlastIndexFns.h" -#include "NvBlastExtDefs.h" - -#include "NvBlastTkAsset.h" -#include "NvBlastTkActor.h" -#include "NvBlastTkFamily.h" - -#include "PxScene.h" -#include "PxRigidDynamic.h" - -#include <PsVecMath.h> -#include "PsFPU.h" - -#include <algorithm> -#include <set> - -#define USE_SCALAR_IMPL 0 -#define WARM_START 1 -#define USE_PHYSX_CONVEX_DATA 1 -#define GRAPH_INTERGRIRY_CHECK 0 - - -namespace Nv -{ -namespace Blast -{ - -using namespace physx; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Solver -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class SequentialImpulseSolver -{ -public: - PX_ALIGN_PREFIX(16) - struct BondData - { - physx::PxVec3 impulseLinear; - uint32_t node0; - physx::PxVec3 impulseAngular; - uint32_t node1; - physx::PxVec3 offset0; - float invOffsetSqrLength; - - float getStressHealth(const ExtStressSolverSettings& settings) const - { - return (impulseLinear.magnitude() * settings.stressLinearFactor + impulseAngular.magnitude() * settings.stressAngularFactor); - } - } - PX_ALIGN_SUFFIX(16); - - PX_ALIGN_PREFIX(16) - struct NodeData - { - physx::PxVec3 velocityLinear; - float invI; - physx::PxVec3 velocityAngular; - float invMass; - } - PX_ALIGN_SUFFIX(16); - - SequentialImpulseSolver(uint32_t nodeCount, uint32_t maxBondCount) - { - m_nodesData.resize(nodeCount); - m_bondsData.reserve(maxBondCount); - } - - NV_INLINE const NodeData& getNodeData(uint32_t node) const - { - return m_nodesData[node]; - } - - NV_INLINE const BondData& getBondData(uint32_t bond) const - { - return m_bondsData[bond]; - } - - NV_INLINE uint32_t getBondCount() const - { - return m_bondsData.size(); - } - - NV_INLINE uint32_t getNodeCount() const - { - return m_nodesData.size();; - } - - NV_INLINE void setNodeMassInfo(uint32_t node, float invMass, float invI) - { - m_nodesData[node].invMass = invMass; - m_nodesData[node].invI = invI; - } - - NV_INLINE void initialize() - { - for (auto& node : m_nodesData) - { - node.velocityLinear = PxVec3(PxZero); - node.velocityAngular = PxVec3(PxZero); - } - } - - NV_INLINE void setNodeVelocities(uint32_t node, const PxVec3& velocityLinear, const PxVec3& velocityAngular) - { - m_nodesData[node].velocityLinear = velocityLinear; - m_nodesData[node].velocityAngular = velocityAngular; - } - - NV_INLINE uint32_t addBond(uint32_t node0, uint32_t node1, const PxVec3& offset) - { - const BondData data = { - PxVec3(PxZero), - node0, - PxVec3(PxZero), - node1, - offset, - 1.0f / offset.magnitudeSquared() - }; - m_bondsData.pushBack(data); - return m_bondsData.size() - 1; - } - - NV_INLINE void replaceWithLast(uint32_t bondIndex) - { - m_bondsData.replaceWithLast(bondIndex); - } - - NV_INLINE void reset(uint32_t nodeCount) - { - m_bondsData.clear(); - m_nodesData.resize(nodeCount); - } - - NV_INLINE void clearBonds() - { - m_bondsData.clear(); - } - - void solve(uint32_t iterationCount, bool warmStart = false) - { - solveInit(warmStart); - - for (uint32_t i = 0; i < iterationCount; ++i) - { - iterate(); - } - } - - void calcError(float& linear, float& angular) - { - linear = 0.0f; - angular = 0.0f; - for (BondData& bond : m_bondsData) - { - NodeData* node0 = &m_nodesData[bond.node0]; - NodeData* node1 = &m_nodesData[bond.node1]; - - const PxVec3 vA = node0->velocityLinear - node0->velocityAngular.cross(bond.offset0); - const PxVec3 vB = node1->velocityLinear + node1->velocityAngular.cross(bond.offset0); - - const PxVec3 vErrorLinear = vA - vB; - const PxVec3 vErrorAngular = node0->velocityAngular - node1->velocityAngular; - - linear += vErrorLinear.magnitude(); - angular += vErrorAngular.magnitude(); - } - } - -private: - void solveInit(bool warmStart = false) - { - if (warmStart) - { - for (BondData& bond : m_bondsData) - { - NodeData* node0 = &m_nodesData[bond.node0]; - NodeData* node1 = &m_nodesData[bond.node1]; - - const PxVec3 velocityLinearCorr0 = bond.impulseLinear * node0->invMass; - const PxVec3 velocityLinearCorr1 = bond.impulseLinear * node1->invMass; - - const PxVec3 velocityAngularCorr0 = bond.impulseAngular * node0->invI - bond.offset0.cross(velocityLinearCorr0) * bond.invOffsetSqrLength; - const PxVec3 velocityAngularCorr1 = bond.impulseAngular * node1->invI + bond.offset0.cross(velocityLinearCorr1) * bond.invOffsetSqrLength; - - node0->velocityLinear += velocityLinearCorr0; - node1->velocityLinear -= velocityLinearCorr1; - - node0->velocityAngular += velocityAngularCorr0; - node1->velocityAngular -= velocityAngularCorr1; - } - } - else - { - for (BondData& bond : m_bondsData) - { - bond.impulseLinear = PxVec3(PxZero); - bond.impulseAngular = PxVec3(PxZero); - } - } - } - - - NV_INLINE void iterate() - { - using namespace physx::shdfnd::aos; - - for (BondData& bond : m_bondsData) - { - NodeData* node0 = &m_nodesData[bond.node0]; - NodeData* node1 = &m_nodesData[bond.node1]; - -#if USE_SCALAR_IMPL - const PxVec3 vA = node0->velocityLinear - node0->velocityAngular.cross(bond.offset0); - const PxVec3 vB = node1->velocityLinear + node1->velocityAngular.cross(bond.offset0); - - const PxVec3 vErrorLinear = vA - vB; - const PxVec3 vErrorAngular = node0->velocityAngular - node1->velocityAngular; - - const float weightedMass = 1.0f / (node0->invMass + node1->invMass); - const float weightedInertia = 1.0f / (node0->invI + node1->invI); - - const PxVec3 outImpulseLinear = -vErrorLinear * weightedMass * 0.5f; - const PxVec3 outImpulseAngular = -vErrorAngular * weightedInertia * 0.5f; - - bond.impulseLinear += outImpulseLinear; - bond.impulseAngular += outImpulseAngular; - - const PxVec3 velocityLinearCorr0 = outImpulseLinear * node0->invMass; - const PxVec3 velocityLinearCorr1 = outImpulseLinear * node1->invMass; - - const PxVec3 velocityAngularCorr0 = outImpulseAngular * node0->invI - bond.offset0.cross(velocityLinearCorr0) * bond.invOffsetSqrLength; - const PxVec3 velocityAngularCorr1 = outImpulseAngular * node1->invI + bond.offset0.cross(velocityLinearCorr1) * bond.invOffsetSqrLength; - - node0->velocityLinear += velocityLinearCorr0; - node1->velocityLinear -= velocityLinearCorr1; - - node0->velocityAngular += velocityAngularCorr0; - node1->velocityAngular -= velocityAngularCorr1; -#else - const Vec3V velocityLinear0 = V3LoadUnsafeA(node0->velocityLinear); - const Vec3V velocityLinear1 = V3LoadUnsafeA(node1->velocityLinear); - const Vec3V velocityAngular0 = V3LoadUnsafeA(node0->velocityAngular); - const Vec3V velocityAngular1 = V3LoadUnsafeA(node1->velocityAngular); - - const Vec3V offset = V3LoadUnsafeA(bond.offset0); - const Vec3V vA = V3Add(velocityLinear0, V3Neg(V3Cross(velocityAngular0, offset))); - const Vec3V vB = V3Add(velocityLinear1, V3Cross(velocityAngular1, offset)); - - const Vec3V vErrorLinear = V3Sub(vA, vB); - const Vec3V vErrorAngular = V3Sub(velocityAngular0, velocityAngular1); - - const FloatV invM0 = FLoad(node0->invMass); - const FloatV invM1 = FLoad(node1->invMass); - const FloatV invI0 = FLoad(node0->invI); - const FloatV invI1 = FLoad(node1->invI); - const FloatV invOffsetSqrLength = FLoad(bond.invOffsetSqrLength); - - const FloatV weightedMass = FLoad(-0.5f / (node0->invMass + node1->invMass)); - const FloatV weightedInertia = FLoad(-0.5f / (node0->invI + node1->invI)); - - const Vec3V outImpulseLinear = V3Scale(vErrorLinear, weightedMass); - const Vec3V outImpulseAngular = V3Scale(vErrorAngular, weightedInertia); - - V3StoreA(V3Add(V3LoadUnsafeA(bond.impulseLinear), outImpulseLinear), bond.impulseLinear); - V3StoreA(V3Add(V3LoadUnsafeA(bond.impulseAngular), outImpulseAngular), bond.impulseAngular); - - const Vec3V velocityLinearCorr0 = V3Scale(outImpulseLinear, invM0); - const Vec3V velocityLinearCorr1 = V3Scale(outImpulseLinear, invM1); - - const Vec3V velocityAngularCorr0 = V3Sub(V3Scale(outImpulseAngular, invI0), V3Scale(V3Cross(offset, velocityLinearCorr0), invOffsetSqrLength)); - const Vec3V velocityAngularCorr1 = V3Add(V3Scale(outImpulseAngular, invI1), V3Scale(V3Cross(offset, velocityLinearCorr1), invOffsetSqrLength)); - - V3StoreA(V3Add(velocityLinear0, velocityLinearCorr0), node0->velocityLinear); - V3StoreA(V3Sub(velocityLinear1, velocityLinearCorr1), node1->velocityLinear); - - V3StoreA(V3Add(velocityAngular0, velocityAngularCorr0), node0->velocityAngular); - V3StoreA(V3Sub(velocityAngular1, velocityAngularCorr1), node1->velocityAngular); -#endif - } - } - - shdfnd::Array<BondData, ExtAlignedAllocator<16>> m_bondsData; - shdfnd::Array<NodeData, ExtAlignedAllocator<16>> m_nodesData; -}; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Graph Processor -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#if GRAPH_INTERGRIRY_CHECK -#define CHECK_GRAPH_INTEGRITY checkGraphIntegrity() -#else -#define CHECK_GRAPH_INTEGRITY ((void)0) -#endif - -class SupportGraphProcessor -{ - -public: - struct BondData - { - uint32_t node0; - uint32_t node1; - uint32_t blastBondIndex; - }; - - struct NodeData - { - float mass; - float volume; - PxVec3 localPos; - bool isStatic; - uint32_t solverNode; - uint32_t neighborsCount; - PxVec3 impulse; - }; - - struct SolverNodeData - { - uint32_t supportNodesCount; - PxVec3 localPos; - union - { - float mass; - int32_t indexShift; - }; - float volume; - bool isStatic; - }; - - struct SolverBondData - { - ExtInlineArray<uint32_t, 8>::type blastBondIndices; - }; - - SupportGraphProcessor(uint32_t nodeCount, uint32_t maxBondCount) : m_solver(nodeCount, maxBondCount), m_nodesDirty(true) - { - m_nodesData.resize(nodeCount); - m_bondsData.reserve(maxBondCount); - - m_solverNodesData.resize(nodeCount); - m_solverBondsData.reserve(maxBondCount); - - m_solverBondsMap.reserve(maxBondCount); - - m_blastBondIndexMap.resize(maxBondCount); - memset(m_blastBondIndexMap.begin(), 0xFF, m_blastBondIndexMap.size() * sizeof(uint32_t)); - } - - NV_INLINE const NodeData& getNodeData(uint32_t node) const - { - return m_nodesData[node]; - } - - NV_INLINE const BondData& getBondData(uint32_t bond) const - { - return m_bondsData[bond]; - } - - NV_INLINE const SolverNodeData& getSolverNodeData(uint32_t node) const - { - return m_solverNodesData[node]; - } - - NV_INLINE const SolverBondData& getSolverBondData(uint32_t bond) const - { - return m_solverBondsData[bond]; - } - - NV_INLINE const SequentialImpulseSolver::BondData& getSolverInternalBondData(uint32_t bond) const - { - return m_solver.getBondData(bond); - } - - NV_INLINE const SequentialImpulseSolver::NodeData& getSolverInternalNodeData(uint32_t node) const - { - return m_solver.getNodeData(node); - } - - NV_INLINE uint32_t getBondCount() const - { - return m_bondsData.size(); - } - - NV_INLINE uint32_t getNodeCount() const - { - return m_nodesData.size();; - } - - NV_INLINE uint32_t getSolverBondCount() const - { - return m_solverBondsData.size(); - } - - NV_INLINE uint32_t getSolverNodeCount() const - { - return m_solverNodesData.size();; - } - - NV_INLINE void setNodeInfo(uint32_t node, float mass, float volume, PxVec3 localPos, bool isStatic) - { - m_nodesData[node].mass = mass; - m_nodesData[node].volume = volume; - m_nodesData[node].localPos = localPos; - m_nodesData[node].isStatic = isStatic; - } - - NV_INLINE void setNodeNeighborsCount(uint32_t node, uint32_t neighborsCount) - { - // neighbors count is expected to be the number of nodes on 1 island/actor. - m_nodesData[node].neighborsCount = neighborsCount; - - // check for too huge aggregates (happens after island's split) - if (!m_nodesDirty) - { - m_nodesDirty |= (m_solverNodesData[m_nodesData[node].solverNode].supportNodesCount > neighborsCount / 2); - } - } - - NV_INLINE void initialize() - { - sync(); - - m_solver.initialize(); - - for (auto& node : m_nodesData) - { - node.impulse = PxVec3(PxZero); - } - } - - NV_INLINE void addNodeImpulse(uint32_t node, const PxVec3& impulse) - { - m_nodesData[node].impulse += impulse; - } - - NV_INLINE void addNodeVelocity(uint32_t node, const PxVec3& velocity) - { - PxVec3 impulse = velocity * m_nodesData[node].mass; - addNodeImpulse(node, impulse); - } - - NV_INLINE void addBond(uint32_t node0, uint32_t node1, uint32_t blastBondIndex) - { - if (isInvalidIndex(m_blastBondIndexMap[blastBondIndex])) - { - const BondData data = { - node0, - node1, - blastBondIndex - }; - m_bondsData.pushBack(data); - m_blastBondIndexMap[blastBondIndex] = m_bondsData.size() - 1; - } - } - - NV_INLINE void removeBondIfExists(uint32_t blastBondIndex) - { - const uint32_t bondIndex = m_blastBondIndexMap[blastBondIndex]; - - if (!isInvalidIndex(bondIndex)) - { - const BondData& bond = m_bondsData[bondIndex]; - const uint32_t solverNode0 = m_nodesData[bond.node0].solverNode; - const uint32_t solverNode1 = m_nodesData[bond.node1].solverNode; - bool isBondInternal = (solverNode0 == solverNode1); - - if (isBondInternal) - { - // internal bond sadly requires graph resync (it never happens on reduction level '0') - m_nodesDirty = true; - } - else if (!m_nodesDirty) - { - // otherwise it's external bond, we can remove it manually and keep graph synced - // we don't need to spend time there if (m_nodesDirty == true), graph will be resynced anyways - - BondKey solverBondKey(solverNode0, solverNode1); - auto entry = m_solverBondsMap.find(solverBondKey); - if (entry) - { - const uint32_t solverBondIndex = entry->second; - auto& blastBondIndices = m_solverBondsData[solverBondIndex].blastBondIndices; - blastBondIndices.findAndReplaceWithLast(blastBondIndex); - if (blastBondIndices.empty()) - { - // all bonds associated with this solver bond were removed, so let's remove solver bond - - m_solverBondsData.replaceWithLast(solverBondIndex); - m_solver.replaceWithLast(solverBondIndex); - if (m_solver.getBondCount() > 0) - { - // update 'previously last' solver bond mapping - const auto& solverBond = m_solver.getBondData(solverBondIndex); - m_solverBondsMap[BondKey(solverBond.node0, solverBond.node1)] = solverBondIndex; - } - - m_solverBondsMap.erase(solverBondKey); - } - } - - CHECK_GRAPH_INTEGRITY; - } - - // remove bond from graph processor's list - m_blastBondIndexMap[blastBondIndex] = invalidIndex<uint32_t>(); - m_bondsData.replaceWithLast(bondIndex); - m_blastBondIndexMap[m_bondsData[bondIndex].blastBondIndex] = m_bondsData.size() > bondIndex ? bondIndex : invalidIndex<uint32_t>(); - } - } - - NV_INLINE void setGraphReductionLevel(uint32_t level) - { - m_graphReductionLevel = level; - m_nodesDirty = true; - } - - uint32_t getGraphReductionLevel() const - { - return m_graphReductionLevel; - } - - void solve(uint32_t iterationCount, bool warmStart = false) - { - CHECK_GRAPH_INTEGRITY; - - for (const NodeData& node : m_nodesData) - { - const SequentialImpulseSolver::NodeData& solverNode = m_solver.getNodeData(node.solverNode); - m_solver.setNodeVelocities(node.solverNode, solverNode.velocityLinear + node.impulse * solverNode.invMass, PxVec3(PxZero)); - } - - m_solver.solve(iterationCount, warmStart); - } - - void calcError(float& linear, float& angular) - { - m_solver.calcError(linear, angular); - } - - void generateFracture(ExtArray<NvBlastBondFractureData>::type& bondFractureBuffer, const ExtStressSolverSettings& settings, const float* blastBondHealths) - { - CHECK_GRAPH_INTEGRITY; - - for (uint32_t i = 0; i < m_solverBondsData.size(); ++i) - { - const SequentialImpulseSolver::BondData& solverInternalBond = m_solver.getBondData(i); - if (solverInternalBond.getStressHealth(settings) > 1.0f) - { - const auto& blastBondIndices = m_solverBondsData[i].blastBondIndices; - for (auto blastBondIndex : blastBondIndices) - { - const uint32_t bondIndex = m_blastBondIndexMap[blastBondIndex]; - if (!isInvalidIndex(bondIndex)) - { - const BondData& bond = m_bondsData[bondIndex]; - - NVBLAST_ASSERT(getNodeData(bond.node0).solverNode != getNodeData(bond.node1).solverNode); - NVBLAST_ASSERT(bond.blastBondIndex == blastBondIndex); - - NvBlastBondFractureData data; - data.health = blastBondHealths[blastBondIndex]; - data.nodeIndex0 = bond.node0; - data.nodeIndex1 = bond.node1; - bondFractureBuffer.pushBack(data); - } - } - } - } - } - -private: - - NV_INLINE void sync() - { - if (m_nodesDirty) - { - syncNodes(); - } - if (m_bondsDirty) - { - syncBonds(); - } - - CHECK_GRAPH_INTEGRITY; - } - - void syncNodes() - { - // init with 1<->1 blast nodes to solver nodes mapping - m_solverNodesData.resize(m_nodesData.size()); - for (uint32_t i = 0; i < m_nodesData.size(); ++i) - { - m_nodesData[i].solverNode = i; - m_solverNodesData[i].supportNodesCount = 1; - m_solverNodesData[i].indexShift = 0; - } - - // for static nodes aggregate size per graph reduction level is lower, it - // falls behind on few levels. (can be made as parameter) - const uint32_t STATIC_NODES_COUNT_PENALTY = 2 << 2; - - // reducing graph by aggregating nodes level by level - for (uint32_t k = 0; k < m_graphReductionLevel; k++) - { - const uint32_t maxAggregateSize = 1 << (k + 1); - - for (const BondData& bond : m_bondsData) - { - NodeData& node0 = m_nodesData[bond.node0]; - NodeData& node1 = m_nodesData[bond.node1]; - - if (node0.isStatic != node1.isStatic) - continue; - - if (node0.solverNode == node1.solverNode) - continue; - - SolverNodeData& solverNode0 = m_solverNodesData[node0.solverNode]; - SolverNodeData& solverNode1 = m_solverNodesData[node1.solverNode]; - - const int countPenalty = node0.isStatic ? STATIC_NODES_COUNT_PENALTY : 1; - const uint32_t aggregateSize = std::min<uint32_t>(maxAggregateSize, node0.neighborsCount / 2); - - if (solverNode0.supportNodesCount * countPenalty >= aggregateSize) - continue; - if (solverNode1.supportNodesCount * countPenalty >= aggregateSize) - continue; - - if (solverNode0.supportNodesCount >= solverNode1.supportNodesCount) - { - solverNode1.supportNodesCount--; - solverNode0.supportNodesCount++; - node1.solverNode = node0.solverNode; - } - else if (solverNode1.supportNodesCount >= solverNode0.supportNodesCount) - { - solverNode1.supportNodesCount++; - solverNode0.supportNodesCount--; - node0.solverNode = node1.solverNode; - } - } - } - - // Solver Nodes now sparse, a lot of empty ones. Rearrange them by moving all non-empty to the front - // 2 passes used for that - { - uint32_t currentNode = 0; - for (; currentNode < m_solverNodesData.size(); ++currentNode) - { - if (m_solverNodesData[currentNode].supportNodesCount > 0) - continue; - - // 'currentNode' is free - - // search next occupied node - uint32_t k = currentNode + 1; - for (; k < m_solverNodesData.size(); ++k) - { - if (m_solverNodesData[k].supportNodesCount > 0) - { - // replace currentNode and keep indexShift - m_solverNodesData[currentNode].supportNodesCount = m_solverNodesData[k].supportNodesCount; - m_solverNodesData[k].indexShift = k - currentNode; - m_solverNodesData[k].supportNodesCount = 0; - break; - } - } - - if (k == m_solverNodesData.size()) - { - break; - } - } - for (auto& node : m_nodesData) - { - node.solverNode -= m_solverNodesData[node.solverNode].indexShift; - } - - // now, we know total solver nodes count and which nodes are aggregated into them - m_solverNodesData.resize(currentNode); - } - - - // calculate all needed data - for (SolverNodeData& solverNode : m_solverNodesData) - { - solverNode.supportNodesCount = 0; - solverNode.localPos = PxVec3(PxZero); - solverNode.mass = 0.0f; - solverNode.volume = 0.0f; - solverNode.isStatic = false; - } - - for (NodeData& node : m_nodesData) - { - SolverNodeData& solverNode = m_solverNodesData[node.solverNode]; - solverNode.supportNodesCount++; - solverNode.localPos += node.localPos; - solverNode.mass += node.mass; - solverNode.volume += node.volume; - solverNode.isStatic |= node.isStatic; - } - - for (SolverNodeData& solverNode : m_solverNodesData) - { - solverNode.localPos /= (float)solverNode.supportNodesCount; - } - - m_solver.reset(m_solverNodesData.size()); - for (uint32_t nodeIndex = 0; nodeIndex < m_solverNodesData.size(); ++nodeIndex) - { - const SolverNodeData& solverNode = m_solverNodesData[nodeIndex]; - - const float invMass = solverNode.isStatic ? 0.0f : 1.0f / solverNode.mass; - const float R = PxPow(solverNode.volume * 3.0f * PxInvPi / 4.0f, 1.0f / 3.0f); // sphere volume approximation - const float invI = invMass / (R * R * 0.4f); // sphere inertia tensor approximation: I = 2/5 * M * R^2 ; invI = 1 / I; - m_solver.setNodeMassInfo(nodeIndex, invMass, invI); - } - - m_nodesDirty = false; - - syncBonds(); - } - - void syncBonds() - { - // traverse all blast bonds and aggregate - m_solver.clearBonds(); - m_solverBondsMap.clear(); - m_solverBondsData.clear(); - for (const BondData& bond : m_bondsData) - { - const NodeData& node0 = m_nodesData[bond.node0]; - const NodeData& node1 = m_nodesData[bond.node1]; - - if (node0.solverNode == node1.solverNode) - continue; // skip (internal) - - if (node0.isStatic && node1.isStatic) - continue; - - BondKey key(node0.solverNode, node1.solverNode); - auto entry = m_solverBondsMap.find(key); - SolverBondData* data; - if (!entry) - { - m_solverBondsData.pushBack(SolverBondData()); - data = &m_solverBondsData.back(); - m_solverBondsMap[key] = m_solverBondsData.size() - 1; - - SolverNodeData& solverNode0 = m_solverNodesData[node0.solverNode]; - SolverNodeData& solverNode1 = m_solverNodesData[node1.solverNode]; - m_solver.addBond(node0.solverNode, node1.solverNode, (solverNode1.localPos - solverNode0.localPos) * 0.5f); - } - else - { - data = &m_solverBondsData[entry->second]; - } - data->blastBondIndices.pushBack(bond.blastBondIndex); - } - - m_bondsDirty = false; - } - -#if GRAPH_INTERGRIRY_CHECK - void checkGraphIntegrity() - { - NVBLAST_ASSERT(m_solver.getBondCount() == m_solverBondsData.size()); - NVBLAST_ASSERT(m_solver.getNodeCount() == m_solverNodesData.size()); - - std::set<uint64_t> solverBonds; - for (uint32_t i = 0; i < m_solverBondsData.size(); ++i) - { - const auto& bondData = m_solver.getBondData(i); - BondKey key(bondData.node0, bondData.node1); - NVBLAST_ASSERT(solverBonds.find(key) == solverBonds.end()); - solverBonds.emplace(key); - auto entry = m_solverBondsMap.find(key); - NVBLAST_ASSERT(entry != nullptr); - const auto& solverBond = m_solverBondsData[entry->second]; - for (auto& blastBondIndex : solverBond.blastBondIndices) - { - if (!isInvalidIndex(m_blastBondIndexMap[blastBondIndex])) - { - auto& b = m_bondsData[m_blastBondIndexMap[blastBondIndex]]; - BondKey key2(m_nodesData[b.node0].solverNode, m_nodesData[b.node1].solverNode); - NVBLAST_ASSERT(key2 == key); - } - } - } - - for (auto& solverBond : m_solverBondsData) - { - for (auto& blastBondIndex : solverBond.blastBondIndices) - { - if (!isInvalidIndex(m_blastBondIndexMap[blastBondIndex])) - { - auto& b = m_bondsData[m_blastBondIndexMap[blastBondIndex]]; - NVBLAST_ASSERT(m_nodesData[b.node0].solverNode != m_nodesData[b.node1].solverNode); - } - } - } - uint32_t mappedBondCount = 0; - for (uint32_t i = 0; i < m_blastBondIndexMap.size(); i++) - { - const auto& bondIndex = m_blastBondIndexMap[i]; - if (!isInvalidIndex(bondIndex)) - { - mappedBondCount++; - NVBLAST_ASSERT(m_bondsData[bondIndex].blastBondIndex == i); - } - } - NVBLAST_ASSERT(m_bondsData.size() == mappedBondCount); - } -#endif - - struct BondKey - { - uint32_t node0; - uint32_t node1; - - BondKey(uint32_t n0, uint32_t n1) - { - node0 = n0 < n1 ? n0 : n1; - node1 = n0 < n1 ? n1 : n0; - } - - operator uint64_t() const - { - return static_cast<uint64_t>(node0) + (static_cast<uint64_t>(node1) << 32); - } - }; - - SequentialImpulseSolver m_solver; - ExtArray<SolverNodeData>::type m_solverNodesData; - ExtArray<SolverBondData>::type m_solverBondsData; - - uint32_t m_graphReductionLevel; - - bool m_nodesDirty; - bool m_bondsDirty; - - ExtHashMap<BondKey, uint32_t>::type m_solverBondsMap; - ExtArray<uint32_t>::type m_blastBondIndexMap; - - ExtArray<BondData>::type m_bondsData; - ExtArray<NodeData>::type m_nodesData; -}; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtImpulseStressSolver -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Creation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ExtImpulseStressSolver::ExtImpulseStressSolver(ExtPxFamily& family, ExtStressSolverSettings settings) - : m_family(family), m_settings(settings), m_isDirty(false), m_reset(false), - m_errorAngular(std::numeric_limits<float>::max()), m_errorLinear(std::numeric_limits<float>::max()), m_framesCount(0) -{ - - const TkAsset* tkAsset = m_family.getTkFamily().getAsset(); - const ExtPxAsset& asset = m_family.getPxAsset(); - const ExtPxChunk* chunks = asset.getChunks(); - const ExtPxSubchunk* subChunks = asset.getSubchunks(); - m_graph = tkAsset->getGraph(); - const uint32_t bondCount = tkAsset->getBondCount(); - - TkActor* tkActor; - m_family.getTkFamily().getActors(&tkActor, 1); - m_bondHealths = tkActor->getBondHealths(); - - m_graphProcessor = NVBLASTEXT_NEW(SupportGraphProcessor)(m_graph.nodeCount, bondCount); - - // traverse graph and fill node info - for (uint32_t i = 0; i < m_graph.nodeCount; ++i) - { - uint32_t node0 = i; - uint32_t chunkIndex0 = m_graph.chunkIndices[node0]; - const ExtPxChunk& chunk0 = chunks[chunkIndex0]; - - bool isChunkStatic = chunk0.isStatic; - - for (uint32_t adjacencyIndex = m_graph.adjacencyPartition[node0]; adjacencyIndex < m_graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) - { - uint32_t bondIndex = m_graph.adjacentBondIndices[adjacencyIndex]; - if (m_bondHealths[bondIndex] <= 0.0f) - continue; - uint32_t node1 = m_graph.adjacentNodeIndices[adjacencyIndex]; - uint32_t chunkIndex1 = m_graph.chunkIndices[node1]; - const ExtPxChunk& chunk1 = chunks[chunkIndex1]; - - if (chunk1.subchunkCount == 0 || chunk1.isStatic) - { - isChunkStatic |= chunk1.isStatic; - continue; - } - } - - // fill node info - - float mass; - float volume; - PxVec3 localPos; - if (chunk0.subchunkCount > 0) - { -#if USE_PHYSX_CONVEX_DATA - const ExtPxSubchunk& subChunk = subChunks[chunk0.firstSubchunkIndex]; - PxVec3 localCenterOfMass; - PxMat33 intertia; - PxVec3 scale = subChunk.geometry.scale.scale; - subChunk.geometry.convexMesh->getMassInformation(mass, intertia, localCenterOfMass); - mass *= scale.x * scale.y * scale.z; - const PxTransform& chunk0LocalTransform = subChunk.transform; - localPos = chunk0LocalTransform.transform(localCenterOfMass); - volume = mass / 1.0f; // unit density -#else - volume = solverChunk0.volume; - mass = volume * 1.0f; // density - localPos = *reinterpret_cast<const PxVec3*>(solverChunk0.centroid); -#endif - } - else - { - mass = 0.0f; - volume = 0.0f; - localPos = PxVec3(PxZero); - isChunkStatic = true; - } - m_graphProcessor->setNodeInfo(node0, mass, volume, localPos, isChunkStatic); - } - - // traverse graph and fill bond info - for (uint32_t node0 = 0; node0 < m_graph.nodeCount; ++node0) - { - for (uint32_t adjacencyIndex = m_graph.adjacencyPartition[node0]; adjacencyIndex < m_graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) - { - uint32_t bondIndex = m_graph.adjacentBondIndices[adjacencyIndex]; - if (m_bondHealths[bondIndex] <= 0.0f) - continue; - uint32_t node1 = m_graph.adjacentNodeIndices[adjacencyIndex]; - - if (node0 < node1) - { - m_graphProcessor->addBond(node0, node1, bondIndex); - } - } - } - - // fire initial actor's created - ExtInlineArray<ExtPxActor*, 4>::type actors;; - actors.resize((uint32_t)m_family.getActorCount()); - m_family.getActors(actors.begin(), actors.size()); - for (const auto actor : actors) - { - onActorCreated(m_family, *actor); - } - - m_family.subscribe(*this); -} - -ExtImpulseStressSolver::~ExtImpulseStressSolver() -{ - NVBLASTEXT_DELETE(m_graphProcessor, SupportGraphProcessor); - m_family.unsubscribe(*this); -} - -ExtStressSolver* ExtStressSolver::create(ExtPxFamily& family, ExtStressSolverSettings settings) -{ - return NVBLASTEXT_NEW(ExtImpulseStressSolver) (family, settings); -} - -void ExtImpulseStressSolver::release() -{ - NVBLASTEXT_DELETE(this, ExtImpulseStressSolver); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Actors -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ExtImpulseStressSolver::onActorCreated(ExtPxFamily& /*family*/, ExtPxActor& actor) -{ - if (actor.getTkActor().getGraphNodeCount() > 1) - { - // update neighbors - { - const uint32_t graphNodeCount = actor.getTkActor().getGraphNodeCount(); - uint32_t* graphNodeIndices = getScratchArray<uint32_t>(graphNodeCount); - actor.getTkActor().getGraphNodeIndices(graphNodeIndices, graphNodeCount); - for (uint32_t i = 0; i < graphNodeCount; ++i) - { - m_graphProcessor->setNodeNeighborsCount(graphNodeIndices[i], graphNodeCount); - } - } - - m_actors.insert(&actor); - m_isDirty = true; - } -} - -void ExtImpulseStressSolver::onActorDestroyed(ExtPxFamily& /*family*/, ExtPxActor& actor) -{ - if (m_actors.erase(&actor)) - { - m_isDirty = true; - } -} - -void ExtImpulseStressSolver::syncSolver() -{ - // traverse graph and remove dead bonds - for (uint32_t node0 = 0; node0 < m_graph.nodeCount; ++node0) - { - for (uint32_t adjacencyIndex = m_graph.adjacencyPartition[node0]; adjacencyIndex < m_graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) - { - uint32_t node1 = m_graph.adjacentNodeIndices[adjacencyIndex]; - if (node0 < node1) - { - uint32_t bondIndex = m_graph.adjacentBondIndices[adjacencyIndex]; - - if (m_bondHealths[bondIndex] <= 0.0f) - { - m_graphProcessor->removeBondIfExists(bondIndex); - } - } - } - } - - m_isDirty = false; -} - - -void ExtImpulseStressSolver::initialize() -{ - if (m_reset) - { - m_framesCount = 0; - } - - if (m_isDirty) - { - syncSolver(); - } - - if (m_settings.graphReductionLevel != m_graphProcessor->getGraphReductionLevel()) - { - m_graphProcessor->setGraphReductionLevel(m_settings.graphReductionLevel); - } - - m_graphProcessor->initialize(); - - for (auto it = m_actors.getIterator(); !it.done(); ++it) - { - const ExtPxActor* actor = *it; - const uint32_t graphNodeCount = actor->getTkActor().getGraphNodeCount(); - uint32_t* graphNodeIndices = getScratchArray<uint32_t>(graphNodeCount); - actor->getTkActor().getGraphNodeIndices(graphNodeIndices, graphNodeCount); - - PxRigidDynamic& rigidDynamic = actor->getPhysXActor(); - const bool isStatic = rigidDynamic.getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC; - if (isStatic) - { - PxVec3 gravity = rigidDynamic.getScene()->getGravity(); - gravity = rigidDynamic.getGlobalPose().rotateInv(gravity); - - for (uint32_t i = 0; i < graphNodeCount; ++i) - { - const uint32_t node = graphNodeIndices[i]; - m_graphProcessor->addNodeVelocity(node, gravity); - } - } - else - { - PxVec3 cMassPose = rigidDynamic.getCMassLocalPose().p; - - PxVec3 angularVelocity = rigidDynamic.getGlobalPose().rotateInv(rigidDynamic.getAngularVelocity()); - //PxVec3 linearVelocity = rigidDynamic.getGlobalPose().rotateInv(rigidDynamic.getLinearVelocity()); - - // Apply centrifugal force - for (uint32_t i = 0; i < graphNodeCount; ++i) - { - const uint32_t node = graphNodeIndices[i]; - const auto& localPos = m_graphProcessor->getNodeData(node).localPos; - // a = w x (w x r) - const PxVec3 centrifugalAcceleration = angularVelocity.cross(angularVelocity.cross(localPos - cMassPose)); - m_graphProcessor->addNodeVelocity(node, centrifugalAcceleration); - } - } - - const auto entry = m_impulseBuffer.find(actor); - if (entry) - { - for (const ImpulseData& data : entry->second) - { - float bestDist = FLT_MAX; - uint32_t bestNode = invalidIndex<uint32_t>(); - - for (uint32_t i = 0; i < graphNodeCount; ++i) - { - const uint32_t node = graphNodeIndices[i]; - const float sqrDist = (data.position - m_graphProcessor->getNodeData(node).localPos).magnitudeSquared(); - if (sqrDist < bestDist) - { - bestDist = sqrDist; - bestNode = node; - } - } - - if (!isInvalidIndex(bestNode)) - { - m_graphProcessor->addNodeImpulse(bestNode, data.impulse); - } - } - m_impulseBuffer[actor].clear(); - } - } -} - -void ExtImpulseStressSolver::applyImpulse(ExtPxActor& actor, physx::PxVec3 position, physx::PxVec3 force) -{ - ImpulseData data = { position, force }; - - m_impulseBuffer[&actor].pushBack(data); -} - -uint32_t ExtImpulseStressSolver::getBondCount() const -{ - return m_graphProcessor->getSolverBondCount(); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Update -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ExtImpulseStressSolver::update(bool doDamage) -{ - initialize(); - - solve(); - - if (doDamage) - { - applyDamage(); - } - - m_framesCount++; -} - -void ExtImpulseStressSolver::solve() -{ - PX_SIMD_GUARD; - - const uint32_t iterations = getIterationsPerFrame(); - m_graphProcessor->solve(iterations, WARM_START && !m_reset); - m_reset = false; - - m_graphProcessor->calcError(m_errorLinear, m_errorAngular); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Damage -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ExtImpulseStressSolver::applyDamage() -{ - m_bondFractureBuffer.clear(); - m_graphProcessor->generateFracture(m_bondFractureBuffer, m_settings, m_bondHealths); - - if (m_bondFractureBuffer.size() > 0) - { - NvBlastFractureBuffers fractureCommands; - fractureCommands.chunkFractureCount = 0; - fractureCommands.bondFractureCount = m_bondFractureBuffer.size(); - fractureCommands.bondFractures = m_bondFractureBuffer.begin(); - - m_family.getTkFamily().applyFracture(&fractureCommands); - } -} - -uint32_t ExtImpulseStressSolver::getIterationCount() const -{ - return getFrameCount() * getIterationsPerFrame(); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Debug Render -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static PxU32 PxVec4ToU32Color(const PxVec4& color) -{ - PxU32 c = 0; - c |= (int)(color.w * 255); c <<= 8; - c |= (int)(color.z * 255); c <<= 8; - c |= (int)(color.y * 255); c <<= 8; - c |= (int)(color.x * 255); - return c; -} - -static PxVec4 PxVec4Lerp(const PxVec4 v0, const PxVec4 v1, float val) -{ - PxVec4 v( - v0.x * (1 - val) + v1.x * val, - v0.y * (1 - val) + v1.y * val, - v0.z * (1 - val) + v1.z * val, - v0.w * (1 - val) + v1.w * val - ); - return v; -} - -inline float clamp01(float v) -{ - return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v); -} - -inline PxVec4 bondHealthColor(float healthFraction) -{ - healthFraction = clamp01(healthFraction); - - const PxVec4 BOND_HEALTHY_COLOR(0.0f, 1.0f, 1.0f, 1.0f); - const PxVec4 BOND_MID_COLOR(1.0f, 1.0f, 0.0f, 1.0f); - const PxVec4 BOND_BROKEN_COLOR(1.0f, 0.0f, 0.0f, 1.0f); - - return healthFraction < 0.5 ? PxVec4Lerp(BOND_BROKEN_COLOR, BOND_MID_COLOR, 2.0f * healthFraction) : PxVec4Lerp(BOND_MID_COLOR, BOND_HEALTHY_COLOR, 2.0f * healthFraction - 1.0f); -} - -void ExtImpulseStressSolver::fillDebugRender(const std::vector<uint32_t>& nodes, std::vector<PxDebugLine>& lines, DebugRenderMode mode, float scale) -{ - const PxVec4 BOND_IMPULSE_LINEAR_COLOR(0.0f, 1.0f, 0.0f, 1.0f); - const PxVec4 BOND_IMPULSE_ANGULAR_COLOR(1.0f, 0.0f, 0.0f, 1.0f); - - if (m_isDirty) - return; - - ExtArray<uint8_t>::type& nodesSet = m_scratch; - - nodesSet.resize(m_graphProcessor->getSolverNodeCount()); - memset(nodesSet.begin(), 0, nodesSet.size() * sizeof(uint8_t)); - for (auto& nodeIndex : nodes) - { - nodesSet[m_graphProcessor->getNodeData(nodeIndex).solverNode] = 1; - } - - const uint32_t bondCount = m_graphProcessor->getSolverBondCount(); - for (uint32_t i = 0; i < bondCount; ++i) - { - const auto& solverInternalBondData = m_graphProcessor->getSolverInternalBondData(i); - if (nodesSet[solverInternalBondData.node0] != 0) - { - NVBLAST_ASSERT(nodesSet[solverInternalBondData.node1] != 0); - - const auto& solverInternalNode0 = m_graphProcessor->getSolverInternalNodeData(solverInternalBondData.node0); - const auto& solverInternalNode1 = m_graphProcessor->getSolverInternalNodeData(solverInternalBondData.node1); - const auto& solverNode0 = m_graphProcessor->getSolverNodeData(solverInternalBondData.node0); - const auto& solverNode1 = m_graphProcessor->getSolverNodeData(solverInternalBondData.node1); - - PxVec3 p0 = solverNode0.localPos; - PxVec3 p1 = solverNode1.localPos; - PxVec3 center = (p0 + p1) * 0.5f; - - const float stress = std::min<float>(solverInternalBondData.getStressHealth(m_settings), 1.0f); - PxVec4 color = bondHealthColor(1.0f - stress); - - lines.push_back(PxDebugLine(p0, p1, PxVec4ToU32Color(color))); - - float impulseScale = scale; - - if (mode == DebugRenderMode::STRESS_GRAPH_NODES_IMPULSES) - { - lines.push_back(PxDebugLine(p0, p0 + solverInternalNode0.velocityLinear * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR))); - lines.push_back(PxDebugLine(p0, p0 + solverInternalNode0.velocityAngular * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR))); - lines.push_back(PxDebugLine(p1, p1 + solverInternalNode1.velocityLinear * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR))); - lines.push_back(PxDebugLine(p1, p1 + solverInternalNode1.velocityAngular * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR))); - } - else if (mode == DebugRenderMode::STRESS_GRAPH_BONDS_IMPULSES) - { - lines.push_back(PxDebugLine(center, center + solverInternalBondData.impulseLinear * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR))); - lines.push_back(PxDebugLine(center, center + solverInternalBondData.impulseAngular * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR))); - } - } - } -} - - -} // namespace Blast -} // namespace Nv diff --git a/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.h b/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.h deleted file mode 100644 index d274789..0000000 --- a/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ - -#ifndef NVBLASTEXTIMPULSESTRESSSOLVER_H -#define NVBLASTEXTIMPULSESTRESSSOLVER_H - -#include "NvBlastExtStressSolver.h" -#include "NvBlastExtPxManager.h" -#include "NvBlastExtPxListener.h" -#include "NvBlastTypes.h" -#include <NvBlastExtArray.h> -#include <NvBlastExtHashSet.h> -#include <NvBlastExtHashMap.h> - -namespace Nv -{ -namespace Blast -{ - - -struct ExtStressNodeCachedData -{ - physx::PxVec3 localPos; - bool isStatic; -}; - - -struct ExtStressBondCachedData -{ - uint32_t bondIndex; -}; - -class SupportGraphProcessor; - -/** -*/ -class ExtImpulseStressSolver : public ExtStressSolver, ExtPxListener -{ - NV_NOCOPY(ExtImpulseStressSolver) - -public: - ExtImpulseStressSolver(ExtPxFamily& family, ExtStressSolverSettings settings); - virtual void release() override; - - - //////// ExtStressSolver interface //////// - - virtual void setSettings(const ExtStressSolverSettings& settings) override - { - m_settings = settings; - } - - virtual const ExtStressSolverSettings& getSettings() const override - { - return m_settings; - } - - virtual void applyImpulse(ExtPxActor& actor, physx::PxVec3 position, physx::PxVec3 force) override; - - virtual void update(bool doDamage) override; - - void reset() override - { - m_reset = true; - } - - virtual float getStressErrorLinear() const override - { - return m_errorLinear; - } - - virtual float getStressErrorAngular() const override - { - return m_errorAngular; - } - - virtual uint32_t getIterationCount() const override; - - virtual uint32_t getFrameCount() const override - { - return m_framesCount; - } - - virtual uint32_t getBondCount() const override; - - virtual void fillDebugRender(const std::vector<uint32_t>& nodes, std::vector<physx::PxDebugLine>& lines, DebugRenderMode mode, float scale) override; - - - //////// ExtPxListener interface //////// - - virtual void onActorCreated(ExtPxFamily& family, ExtPxActor& actor) final; - - virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) final; - - -private: - ~ExtImpulseStressSolver(); - - - //////// private methods //////// - - void solve(); - - void applyDamage(); - - void initialize(); - - NV_INLINE void iterate(); - - void syncSolver(); - - template<class T> - NV_INLINE T* getScratchArray(uint32_t size); - - - //////// data //////// - - struct ImpulseData - { - physx::PxVec3 position; - physx::PxVec3 impulse; - }; - - ExtPxFamily& m_family; - ExtHashSet<ExtPxActor*>::type m_actors; - ExtStressSolverSettings m_settings; - NvBlastSupportGraph m_graph; - bool m_isDirty; - bool m_reset; - const float* m_bondHealths; - SupportGraphProcessor* m_graphProcessor; - float m_errorAngular; - float m_errorLinear; - uint32_t m_framesCount; - ExtArray<NvBlastBondFractureData>::type m_bondFractureBuffer; - ExtHashMap<const ExtPxActor*, ExtArray<ImpulseData>::type>::type m_impulseBuffer; - ExtArray<uint8_t>::type m_scratch; -}; - - -template<class T> -NV_INLINE T* ExtImpulseStressSolver::getScratchArray(uint32_t size) -{ - const uint32_t scratchSize = sizeof(T) * size; - if (m_scratch.size() < scratchSize) - { - m_scratch.resize(scratchSize); - } - return reinterpret_cast<T*>(m_scratch.begin()); -} - - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTIMPULSESTRESSSOLVER_H diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp index 7732d18..c298e07 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtPxActorImpl.h" #include "NvBlastExtPxAsset.h" @@ -16,6 +34,8 @@ #include "PxRigidDynamic.h" #include "PxPhysics.h" +#include "NvBlastAssert.h" + #include "NvBlastTkActor.h" #include "NvBlastTkAsset.h" @@ -57,7 +77,7 @@ ExtPxActorImpl::ExtPxActorImpl(ExtPxFamilyImpl* family, TkActor* tkActor, const // Single lower-support chunk actors might be leaf actors, check for this and disable contact callbacks if so if (nodeCount <= 1) { - PX_ASSERT(chunkIndices.size() == 1); + NVBLAST_ASSERT(chunkIndices.size() == 1); if (chunkIndices.size() > 0) { const NvBlastChunk& chunk = chunks[chunkIndices[0]]; @@ -106,23 +126,23 @@ ExtPxActorImpl::ExtPxActorImpl(ExtPxFamilyImpl* family, TkActor* tkActor, const m_rigidDynamic->attachShape(*shape); - PX_ASSERT_WITH_MESSAGE(m_family->m_subchunkShapes[subchunkIndex] == nullptr, "Chunk has some shapes(live)."); + NVBLAST_ASSERT_WITH_MESSAGE(m_family->m_subchunkShapes[subchunkIndex] == nullptr, "Chunk has some shapes(live)."); m_family->m_subchunkShapes[subchunkIndex] = shape; } } // search for static chunk in actor's graph (make actor static if it contains static chunk) - bool staticFound = false; + bool staticFound = m_tkActor->isBoundToWorld(); if (nodeCount > 0) { - auto& graphChunkIndices = m_family->m_indicesScratch; - graphChunkIndices.resize(nodeCount); - m_tkActor->getGraphNodeIndices(graphChunkIndices.begin(), static_cast<uint32_t>(graphChunkIndices.size())); + auto& graphNodeIndices = m_family->m_indicesScratch; + graphNodeIndices.resize(nodeCount); + m_tkActor->getGraphNodeIndices(graphNodeIndices.begin(), static_cast<uint32_t>(graphNodeIndices.size())); const NvBlastSupportGraph graph = m_tkActor->getAsset()->getGraph(); - for (uint32_t i = 0; !staticFound && i < graphChunkIndices.size(); ++i) + for (uint32_t i = 0; !staticFound && i < graphNodeIndices.size(); ++i) { - uint32_t chunkIndex = graph.chunkIndices[graphChunkIndices[i]]; + const uint32_t chunkIndex = graph.chunkIndices[graphNodeIndices[i]]; const ExtPxChunk& chunk = pxChunks[chunkIndex]; staticFound = chunk.isStatic; } diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h index a592293..5635591 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h @@ -1,18 +1,36 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXACTORIMPL_H #define NVBLASTEXTPXACTORIMPL_H #include "NvBlastExtPxActor.h" -#include "NvBlastExtArray.h" +#include "NvBlastArray.h" #include "PxTransform.h" @@ -82,7 +100,7 @@ private: ExtPxFamilyImpl* m_family; TkActor* m_tkActor; PxRigidDynamic* m_rigidDynamic; - ExtInlineArray<uint32_t, 4>::type m_chunkIndices; + InlineArray<uint32_t, 4>::type m_chunkIndices; }; diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp index a0f75fc..948cd84 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp @@ -1,15 +1,33 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtPxAssetImpl.h" -#include "NvBlastExtHashMap.h" +#include "NvBlastHashMap.h" #include "NvBlastAssert.h" #include "NvBlastIndexFns.h" @@ -30,65 +48,106 @@ namespace Blast /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helpers/Wrappers +// ExtPxAssetImpl Implementation /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class FileBufToPxInputStream final : public PxInputStream +ExtPxAssetImpl::ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework) +#if !defined(NV_VC) || NV_VC >= 14 + : m_defaultActorDesc { 1.0f, nullptr, 1.0f, nullptr } { -public: - FileBufToPxInputStream(PxFileBuf& filebuf) : m_filebuf(filebuf) {} - - virtual uint32_t read(void* dest, uint32_t count) - { - return m_filebuf.read(dest, count); - } +#else +{ + m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; +#endif + m_tkAsset = framework.createAsset(desc); + fillPhysicsChunks(desc.pxChunks, desc.chunkCount); +} -private: - FileBufToPxInputStream& operator=(const FileBufToPxInputStream&); +ExtPxAssetImpl::ExtPxAssetImpl(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework) +#if !defined(NV_VC) || NV_VC >= 14 + : m_defaultActorDesc{ 1.0f, nullptr, 1.0f, nullptr } +{ +#else +{ + m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; +#endif + m_tkAsset = framework.createAsset(desc); + fillPhysicsChunks(pxChunks, pxSubchunks, desc.chunkCount); +} - PxFileBuf& m_filebuf; -}; +ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount) + : m_tkAsset(asset) +#if !defined(NV_VC) || NV_VC >= 14 + , m_defaultActorDesc{ 1.0f, nullptr, 1.0f, nullptr } +{ +#else +{ + m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; +#endif + m_tkAsset = asset; + fillPhysicsChunks(chunks, chunkCount); +} -class FileBufToPxOutputStream final : public PxOutputStream +ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* asset) + : m_tkAsset(asset) +#if !defined(NV_VC) || NV_VC >= 14 + , m_defaultActorDesc { 1.0f, nullptr, 1.0f, nullptr } { -public: - FileBufToPxOutputStream(PxFileBuf& filebuf) : m_filebuf(filebuf) {} +#else +{ + m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; +#endif +} - virtual uint32_t write(const void* src, uint32_t count) override +ExtPxAssetImpl::~ExtPxAssetImpl() +{ + if (m_tkAsset) { - return m_filebuf.write(src, count); + m_tkAsset->release(); } +} -private: - FileBufToPxOutputStream& operator=(const FileBufToPxOutputStream&); - - PxFileBuf& m_filebuf; -}; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtPxAssetImpl Implementation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void ExtPxAssetImpl::release() +{ + NVBLAST_DELETE(this, ExtPxAssetImpl); +} -ExtPxAssetImpl::ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework) +void ExtPxAssetImpl::fillPhysicsChunks(ExtPxChunk* pxChunks, ExtPxSubchunk* pxSuchunks, uint32_t chunkCount) { - m_tkAsset = framework.createAsset(desc); + // count subchunks and reserve memory + uint32_t subchunkCount = 0; + for (uint32_t i = 0; i < chunkCount; ++i) + { + const auto& chunk = pxChunks[i]; + subchunkCount += static_cast<uint32_t>(chunk.subchunkCount); + } + m_subchunks.resize(subchunkCount); + m_chunks.resize(chunkCount); + memcpy(&m_subchunks.front(), pxSuchunks, sizeof(ExtPxSubchunk) * subchunkCount); + memcpy(&m_chunks.front(), pxChunks, sizeof(ExtPxChunk) * chunkCount); +} +void ExtPxAssetImpl::fillPhysicsChunks(ExtPxAssetDesc::ChunkDesc* pxChunks, uint32_t chunkCount) +{ // count subchunks and reserve memory uint32_t subchunkCount = 0; - for (uint32_t i = 0; i < desc.chunkCount; ++i) + for (uint32_t i = 0; i < chunkCount; ++i) { - const auto& chunk = desc.pxChunks[i]; + const auto& chunk = pxChunks[i]; subchunkCount += static_cast<uint32_t>(chunk.subchunkCount); } m_subchunks.reserve(subchunkCount); // fill chunks and subchunks - m_chunks.resize(desc.chunkCount); - for (uint32_t i = 0; i < desc.chunkCount; ++i) + m_chunks.resize(chunkCount); + for (uint32_t i = 0; i < chunkCount; ++i) { - const auto& chunk = desc.pxChunks[i]; + const auto& chunk = pxChunks[i]; m_chunks[i].isStatic = chunk.isStatic; m_chunks[i].firstSubchunkIndex = m_subchunks.size(); m_chunks[i].subchunkCount = chunk.subchunkCount; @@ -104,27 +163,9 @@ ExtPxAssetImpl::ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framewor } } -ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* tkAsset): - m_tkAsset(tkAsset) -{ - -} -ExtPxAssetImpl::~ExtPxAssetImpl() -{ - if (m_tkAsset) - { - m_tkAsset->release(); - } -} - -void ExtPxAssetImpl::release() -{ - NVBLASTEXT_DELETE(this, ExtPxAssetImpl); -} - -NV_INLINE bool serializeConvexMesh(const PxConvexMesh& convexMesh, PxCooking& cooking, ExtArray<uint32_t>::type& indicesScratch, - ExtArray<PxHullPolygon>::type hullPolygonsScratch, PxOutputStream& stream) +NV_INLINE bool serializeConvexMesh(const PxConvexMesh& convexMesh, PxCooking& cooking, Array<uint32_t>::type& indicesScratch, + Array<PxHullPolygon>::type hullPolygonsScratch, PxOutputStream& stream) { PxConvexMeshDesc desc; desc.points.data = convexMesh.getVertices(); @@ -168,64 +209,25 @@ NV_INLINE bool serializeConvexMesh(const PxConvexMesh& convexMesh, PxCooking& co return cooking.cookConvexMesh(desc, stream); } -bool ExtPxAssetImpl::serialize(PxFileBuf& stream, PxCooking& cooking) const -{ - // Header data - stream.storeDword(ClassID); - stream.storeDword(Version::Current); - - m_tkAsset->serialize(stream); - // Chunks - const uint32_t chunkCount = m_tkAsset->getChunkCount(); - for (uint32_t i = 0; i < chunkCount; ++i) - { - const ExtPxChunk& chunk = m_chunks[i]; - stream.storeDword(chunk.firstSubchunkIndex); - stream.storeDword(chunk.subchunkCount); - stream.storeDword(chunk.isStatic ? 1 : 0); - } - - stream.storeDword(m_subchunks.size()); - - ExtArray<uint32_t>::type indicesScratch(512); - ExtArray<PxHullPolygon>::type hullPolygonsScratch(512); - ExtHashMap<PxConvexMesh*, uint32_t>::type convexReuseMap; - - FileBufToPxOutputStream outputStream(stream); - for (uint32_t i = 0; i < m_subchunks.size(); ++i) +void ExtPxAssetImpl::setUniformHealth(bool enabled) +{ + if (m_bondHealths.empty() != enabled) { - auto& subchunk = m_subchunks[i]; - - // Subchunk transform - stream.storeFloat(subchunk.transform.q.x); stream.storeFloat(subchunk.transform.q.y); stream.storeFloat(subchunk.transform.q.z); stream.storeFloat(subchunk.transform.q.w); - stream.storeFloat(subchunk.transform.p.x); stream.storeFloat(subchunk.transform.p.y); stream.storeFloat(subchunk.transform.p.z); - - // Subchunk scale - stream.storeFloat(subchunk.geometry.scale.scale.x); stream.storeFloat(subchunk.geometry.scale.scale.y); stream.storeFloat(subchunk.geometry.scale.scale.z); - stream.storeFloat(subchunk.geometry.scale.rotation.x); stream.storeFloat(subchunk.geometry.scale.rotation.y); stream.storeFloat(subchunk.geometry.scale.rotation.z); stream.storeFloat(subchunk.geometry.scale.rotation.w); - - auto convexMesh = subchunk.geometry.convexMesh; - NVBLASTEXT_CHECK_ERROR(convexMesh != nullptr, "ExtPxAssetImpl::serialize: subchunk convexMesh is nullptr.", return false); - - auto entry = convexReuseMap.find(convexMesh); - if (entry) + if (enabled) { - stream.storeDword(entry->second); + m_bondHealths.resizeUninitialized(0); + m_supportChunkHealths.resizeUninitialized(0); } else { - stream.storeDword(invalidIndex<uint32_t>()); - if (!serializeConvexMesh(*convexMesh, cooking, indicesScratch, hullPolygonsScratch, outputStream)) - { - NVBLASTEXT_LOG_ERROR("ExtPxAssetImpl::serialize: subchunk convexMesh cooking/serialization failed."); - return false; - } - convexReuseMap[convexMesh] = i; + m_bondHealths.resize(m_tkAsset->getBondCount()); + m_supportChunkHealths.resize(m_tkAsset->getGraph().nodeCount); } } - return true; + m_defaultActorDesc.initialBondHealths = enabled ? nullptr : m_bondHealths.begin(); + m_defaultActorDesc.initialSupportChunkHealths = enabled ? nullptr : m_supportChunkHealths.begin(); } @@ -235,81 +237,30 @@ bool ExtPxAssetImpl::serialize(PxFileBuf& stream, PxCooking& cooking) const ExtPxAsset* ExtPxAsset::create(const ExtPxAssetDesc& desc, TkFramework& framework) { - ExtPxAssetImpl* asset = NVBLASTEXT_NEW(ExtPxAssetImpl)(desc, framework); + ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(desc, framework); return asset; } +ExtPxAsset* ExtPxAsset::create(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework) +{ + ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(desc, pxChunks, pxSubchunks, framework); + return asset; +} Nv::Blast::ExtPxAsset* ExtPxAsset::create(TkAsset* tkAsset) { - ExtPxAssetImpl* asset = NVBLASTEXT_NEW(ExtPxAssetImpl)(tkAsset); + ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(tkAsset); // Don't populate the chunks or subchunks! return asset; } -ExtPxAsset* ExtPxAsset::deserialize(PxFileBuf& stream, TkFramework& framework, PxPhysics& physics) +Nv::Blast::ExtPxAsset* ExtPxAsset::create(TkAsset* tkAsset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount) { - ExtPxAssetImpl::DataHeader header; - header.dataType = stream.readDword(); - header.version = stream.readDword(); - NVBLASTEXT_CHECK_ERROR(header.dataType == ExtPxAssetImpl::ClassID, "ExtPxAsset::deserialize: wrong data type in filebuf stream.", return nullptr); - NVBLASTEXT_CHECK_ERROR(header.version == ExtPxAssetImpl::Version::Current, "ExtPxAsset::deserialize: wrong data version in filebuf stream.", return nullptr); - - TkAsset* tkAsset = static_cast<TkAsset*>(framework.deserialize(stream)); - NVBLASTEXT_CHECK_ERROR(tkAsset != nullptr, "ExtPxAsset::deserialize: failed to deserialize TkAsset.", return nullptr); - - ExtPxAssetImpl* asset = NVBLASTEXT_NEW(ExtPxAssetImpl)(tkAsset); - - asset->m_chunks.resize(asset->m_tkAsset->getChunkCount()); - - const uint32_t chunkCount = asset->m_chunks.size(); - for (uint32_t i = 0; i < chunkCount; ++i) - { - ExtPxChunk& chunk = asset->m_chunks[i]; - chunk.firstSubchunkIndex = stream.readDword(); - chunk.subchunkCount = stream.readDword(); - chunk.isStatic = 0 != stream.readDword(); - } - - const uint32_t subchunkCount = stream.readDword(); - asset->m_subchunks.resize(subchunkCount); - - FileBufToPxInputStream inputStream(stream); - for (uint32_t i = 0; i < asset->m_subchunks.size(); ++i) - { - ExtPxSubchunk& subChunk = asset->m_subchunks[i]; - - // Subchunk transform - subChunk.transform.q.x = stream.readFloat(); subChunk.transform.q.y = stream.readFloat(); subChunk.transform.q.z = stream.readFloat(); subChunk.transform.q.w = stream.readFloat(); - subChunk.transform.p.x = stream.readFloat(); subChunk.transform.p.y = stream.readFloat(); subChunk.transform.p.z = stream.readFloat(); - - // Subchunk scale - subChunk.geometry.scale.scale.x = stream.readFloat(); subChunk.geometry.scale.scale.y = stream.readFloat(); subChunk.geometry.scale.scale.z = stream.readFloat(); - subChunk.geometry.scale.rotation.x = stream.readFloat(); subChunk.geometry.scale.rotation.y = stream.readFloat(); subChunk.geometry.scale.rotation.z = stream.readFloat(); subChunk.geometry.scale.rotation.w = stream.readFloat(); - - const uint32_t convexReuseIndex = stream.readDword(); - if (isInvalidIndex(convexReuseIndex)) - { - subChunk.geometry.convexMesh = physics.createConvexMesh(inputStream); - } - else - { - NVBLAST_ASSERT_WITH_MESSAGE(convexReuseIndex < i, "ExtPxAsset::deserialize: wrong convexReuseIndex."); - subChunk.geometry.convexMesh = asset->m_subchunks[convexReuseIndex].geometry.convexMesh; - } - if (!subChunk.geometry.convexMesh) - { - NVBLASTEXT_LOG_ERROR("ExtPxAsset::deserialize: failed to deserialize convex mesh."); - asset->release(); - return nullptr; - } - } - + ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(tkAsset, chunks, chunkCount); return asset; } - } // namespace Blast } // namespace Nv diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h index fd95293..11a36b3 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h @@ -1,19 +1,36 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXASSETIMPL_H #define NVBLASTEXTPXASSETIMPL_H #include "NvBlastExtPxAsset.h" -#include "NvBlastExtArray.h" -#include "NvBlastExtDefs.h" +#include "NvBlastArray.h" namespace Nv @@ -26,6 +43,10 @@ using namespace physx; using namespace general_PxIOStream2; +// Macro to load a uint32_t (or larger) with four characters (move it in some shared header if it's used anywhere else in Ext) +#define NVBLASTEXT_FOURCC(_a, _b, _c, _d) ( (uint32_t)(_a) | (uint32_t)(_b)<<8 | (uint32_t)(_c)<<16 | (uint32_t)(_d)<<24 ) + + class ExtPxAssetImpl final : public ExtPxAsset { NV_NOCOPY(ExtPxAssetImpl) @@ -33,27 +54,12 @@ class ExtPxAssetImpl final : public ExtPxAsset public: friend class ExtPxAsset; - /** - Enum which keeps track of the serialized data format. - */ - enum Version - { - /** Initial version */ - Initial, - - // New formats must come before Count. They should be given descriptive names with more information in comments. - - /** The number of serialized formats. */ - Count, - - /** The current version. This should always be Count-1 */ - Current = Count - 1 - }; - //////// ctor //////// ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework); - ExtPxAssetImpl(TkAsset* tkAsset); + ExtPxAssetImpl(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework); + ExtPxAssetImpl(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount); + ExtPxAssetImpl(TkAsset* asset); ~ExtPxAssetImpl(); @@ -87,36 +93,56 @@ public: return m_subchunks.begin(); } - virtual bool serialize(PxFileBuf& stream, PxCooking& cooking) const override; + virtual NvBlastActorDesc& getDefaultActorDesc() override + { + return m_defaultActorDesc; + } + + virtual const NvBlastActorDesc& getDefaultActorDesc() const override + { + return m_defaultActorDesc; + } + + virtual void setUniformHealth(bool enabled) override; + //////// internal public methods //////// + /* Get the underlying array for the chunks. Used for serialization. */ - ExtArray<ExtPxChunk>::type& getChunksArray() { return m_chunks; } + Array<ExtPxChunk>::type& getChunksArray() { return m_chunks; } /* Get the underlying array for the subchunks. Used for serialization. */ - ExtArray<ExtPxSubchunk>::type& getSubchunksArray() { return m_subchunks; } + Array<ExtPxSubchunk>::type& getSubchunksArray() { return m_subchunks; } -private: - //////// serialization data //////// + /* + Get the underlying array for the bond healths. Used for serialization. + */ + Array<float>::type& getBondHealthsArray() { return m_bondHealths; } - struct DataHeader - { - uint32_t dataType; - uint32_t version; - }; + /* + Get the underlying array for the support chunk healths. Used for serialization. + */ + Array<float>::type& getSupportChunkHealthsArray() { return m_supportChunkHealths; } + +private: - enum { ClassID = NVBLASTEXT_FOURCC('B', 'P', 'X', 'A') }; // Blast PhysX Asset + //////// initialization ///////// + void fillPhysicsChunks(ExtPxChunk* pxChunks, ExtPxSubchunk* pxSuchunk, uint32_t chunkCount); + void fillPhysicsChunks(ExtPxAssetDesc::ChunkDesc* desc, uint32_t count); //////// data //////// - TkAsset* m_tkAsset; - ExtArray<ExtPxChunk>::type m_chunks; - ExtArray<ExtPxSubchunk>::type m_subchunks; + TkAsset* m_tkAsset; + Array<ExtPxChunk>::type m_chunks; + Array<ExtPxSubchunk>::type m_subchunks; + Array<float>::type m_bondHealths; + Array<float>::type m_supportChunkHealths; + NvBlastActorDesc m_defaultActorDesc; }; } // namespace Blast diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp index b2d3a47..530bbe3 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtPxFamilyImpl.h" #include "NvBlastExtPxActorImpl.h" @@ -65,14 +83,14 @@ ExtPxFamilyImpl::~ExtPxFamilyImpl() void ExtPxFamilyImpl::release() { - NVBLASTEXT_DELETE(this, ExtPxFamilyImpl); + NVBLAST_DELETE(this, ExtPxFamilyImpl); } bool ExtPxFamilyImpl::spawn(const physx::PxTransform& pose, const physx::PxVec3& scale, const ExtPxSpawnSettings& settings) { - NVBLASTEXT_CHECK_ERROR(!m_isSpawned, "Family spawn: family already spawned. Was spawn() called twice?", return false); - NVBLASTEXT_CHECK_ERROR(settings.scene != nullptr, "Family creation: desc.scene is nullptr", return false); - NVBLASTEXT_CHECK_ERROR(settings.material != nullptr, "Family creation: desc.material is nullptr", return false); + NVBLAST_CHECK_ERROR(!m_isSpawned, "Family spawn: family already spawned. Was spawn() called twice?", return false); + NVBLAST_CHECK_ERROR(settings.scene != nullptr, "Family creation: desc.scene is nullptr", return false); + NVBLAST_CHECK_ERROR(settings.material != nullptr, "Family creation: desc.material is nullptr", return false); m_initialTransform = pose; m_spawnSettings = settings; @@ -119,7 +137,7 @@ bool ExtPxFamilyImpl::spawn(const physx::PxTransform& pose, const physx::PxVec3& bool ExtPxFamilyImpl::despawn() { - NVBLASTEXT_CHECK_ERROR(m_spawnSettings.scene != nullptr, "Family despawn: desc.scene is nullptr", return false); + NVBLAST_CHECK_ERROR(m_spawnSettings.scene != nullptr, "Family despawn: desc.scene is nullptr", return false); auto& actors = m_actorsBuffer; actors.resize(m_actors.size()); @@ -228,7 +246,7 @@ void ExtPxFamilyImpl::createActors(TkActor** tkActors, const PxActorCreateInfo* auto actorsToAdd = m_physXActorsBuffer.begin(); for (uint32_t i = 0; i < count; ++i) { - ExtPxActorImpl* actor = NVBLASTEXT_NEW(ExtPxActorImpl)(this, tkActors[i], pxActorInfos[i]); + ExtPxActorImpl* actor = NVBLAST_NEW(ExtPxActorImpl)(this, tkActors[i], pxActorInfos[i]); m_actors.insert(actor); actorsToAdd[i] = &actor->getPhysXActor(); dispatchActorCreated(*actor); @@ -237,7 +255,7 @@ void ExtPxFamilyImpl::createActors(TkActor** tkActors, const PxActorCreateInfo* auto e = m_manager.m_incompleteJointMultiMap.find(tkActors[i]); if (e != nullptr) { - ExtArray<TkJoint*>::type joints = e->second; // Copying the array + Array<TkJoint*>::type joints = e->second; // Copying the array m_manager.m_incompleteJointMultiMap.erase(tkActors[i]); for (uint32_t j = 0; j < joints.size(); ++j) { @@ -262,7 +280,7 @@ void ExtPxFamilyImpl::destroyActors(ExtPxActor** actors, uint32_t count) ExtPxActorImpl* actor = (ExtPxActorImpl*)actors[i]; m_actors.erase(actor); dispatchActorDestroyed(*actor); - NVBLASTEXT_DELETE(actor, ExtPxActorImpl); + NVBLAST_DELETE(actor, ExtPxActorImpl); } } diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h index 5c90346..356e2c7 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h @@ -1,19 +1,37 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXFAMILYIMPL_H #define NVBLASTEXTPXFAMILYIMPL_H #include "NvBlastExtPxFamily.h" -#include "NvBlastExtArray.h" -#include "NvBlastExtHashSet.h" +#include "NvBlastArray.h" +#include "NvBlastHashSet.h" #include "PxTransform.h" #include "NvBlastTkEvent.h" @@ -150,15 +168,15 @@ private: bool m_isSpawned; PxTransform m_initialTransform; PxVec3 m_initialScale; - ExtHashSet<ExtPxActor*>::type m_actors; - ExtArray<TkActor*>::type m_culledActors; - ExtInlineArray<ExtPxListener*, 4>::type m_listeners; - ExtArray<PxShape*>::type m_subchunkShapes; - ExtArray<TkActor*>::type m_newActorsBuffer; - ExtArray<PxActorCreateInfo>::type m_newActorCreateInfo; - ExtArray<PxActor*>::type m_physXActorsBuffer; - ExtArray<ExtPxActor*>::type m_actorsBuffer; - ExtArray<uint32_t>::type m_indicesScratch; + HashSet<ExtPxActor*>::type m_actors; + Array<TkActor*>::type m_culledActors; + InlineArray<ExtPxListener*, 4>::type m_listeners; + Array<PxShape*>::type m_subchunkShapes; + Array<TkActor*>::type m_newActorsBuffer; + Array<PxActorCreateInfo>::type m_newActorCreateInfo; + Array<PxActor*>::type m_physXActorsBuffer; + Array<ExtPxActor*>::type m_actorsBuffer; + Array<uint32_t>::type m_indicesScratch; }; } // namespace Blast diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp index 42266ee..bb2c64d 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtPxManagerImpl.h" #include "NvBlastExtPxAssetImpl.h" @@ -32,26 +50,30 @@ namespace Blast ExtPxManager* ExtPxManager::create(PxPhysics& physics, TkFramework& framework, ExtPxCreateJointFunction createFn, bool useUserData) { - return NVBLASTEXT_NEW(ExtPxManagerImpl)(physics, framework, createFn, useUserData); + return NVBLAST_NEW(ExtPxManagerImpl)(physics, framework, createFn, useUserData); } void ExtPxManagerImpl::release() { - NVBLASTEXT_DELETE(this, ExtPxManagerImpl); + NVBLAST_DELETE(this, ExtPxManagerImpl); } ExtPxFamily* ExtPxManagerImpl::createFamily(const ExtPxFamilyDesc& desc) { - NVBLASTEXT_CHECK_ERROR(desc.pxAsset != nullptr, "Family creation: pxAsset is nullptr.", return nullptr); + NVBLAST_CHECK_ERROR(desc.pxAsset != nullptr, "Family creation: pxAsset is nullptr.", return nullptr); - // create tk family + // prepare TkActorDesc (take NvBlastActorDesc from ExtPxFamilyDesc if it's not null, otherwise take from PxAsset) TkActorDesc tkActorDesc; - (&tkActorDesc)->NvBlastActorDesc::operator=(desc.actorDesc); + const NvBlastActorDesc& actorDesc = desc.actorDesc ? *desc.actorDesc : desc.pxAsset->getDefaultActorDesc(); + (&tkActorDesc)->NvBlastActorDesc::operator=(actorDesc); tkActorDesc.asset = &desc.pxAsset->getTkAsset(); + + // create tk actor TkActor* actor = m_framework.createActor(tkActorDesc); - NVBLASTEXT_CHECK_ERROR(actor != nullptr, "Family creation: tk actor creation failed.", return nullptr); + NVBLAST_CHECK_ERROR(actor != nullptr, "Family creation: tk actor creation failed.", return nullptr); - ExtPxFamilyImpl* family = NVBLASTEXT_NEW(ExtPxFamilyImpl)(*this, actor->getFamily(), *desc.pxAsset); + // create px family + ExtPxFamilyImpl* family = NVBLAST_NEW(ExtPxFamilyImpl)(*this, actor->getFamily(), *desc.pxAsset); if (desc.group) { @@ -68,7 +90,17 @@ bool ExtPxManagerImpl::createJoint(TkJoint& joint) const TkJointData data = joint.getData(); ExtPxActorImpl* pxActor0 = data.actors[0] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[0]->userData) : nullptr; ExtPxActorImpl* pxActor1 = data.actors[1] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[1]->userData) : nullptr; - NVBLAST_ASSERT(pxActor0 || pxActor1); + if (!pxActor0 && !pxActor1) + { + for (int i = 0; i < 2; ++i) + { + if (data.actors[i] != nullptr) + { + m_incompleteJointMultiMap[data.actors[i]].pushBack(&joint); + } + } + return false; + } PxTransform lf0(data.attachPositions[0]); PxTransform lf1(data.attachPositions[1]); PxJoint* pxJoint = m_createJointFn(pxActor0, lf0, pxActor1, lf1, m_physics, joint); @@ -83,9 +115,9 @@ bool ExtPxManagerImpl::createJoint(TkJoint& joint) void ExtPxManagerImpl::updateJoint(TkJoint& joint) { + const TkJointData& data = joint.getData(); if (joint.userData) { - const TkJointData& data = joint.getData(); ExtPxActorImpl* pxActors[2]; for (int i = 0; i < 2; ++i) { @@ -94,7 +126,7 @@ void ExtPxManagerImpl::updateJoint(TkJoint& joint) pxActors[i] = reinterpret_cast<ExtPxActorImpl*>(data.actors[i]->userData); if (pxActors[i] == nullptr) { - ExtArray<TkJoint*>::type& joints = m_incompleteJointMultiMap[data.actors[i]]; + Array<TkJoint*>::type& joints = m_incompleteJointMultiMap[data.actors[i]]; NVBLAST_ASSERT(joints.find(&joint) == joints.end()); joints.pushBack(&joint); return; // Wait until the TkActor is received to create this joint @@ -109,6 +141,18 @@ void ExtPxManagerImpl::updateJoint(TkJoint& joint) PxJoint* pxJoint = reinterpret_cast<PxJoint*>(joint.userData); pxJoint->setActors(pxActors[0] ? &pxActors[0]->getPhysXActor() : nullptr, pxActors[1] ? &pxActors[1]->getPhysXActor() : nullptr); } + else + { + ExtPxActorImpl* pxActor0 = data.actors[0] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[0]->userData) : nullptr; + ExtPxActorImpl* pxActor1 = data.actors[1] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[1]->userData) : nullptr; + PxTransform lf0(data.attachPositions[0]); + PxTransform lf1(data.attachPositions[1]); + PxJoint* pxJoint = m_createJointFn(pxActor0, lf0, pxActor1, lf1, m_physics, joint); + if (pxJoint) + { + joint.userData = pxJoint; + } + } } void ExtPxManagerImpl::destroyJoint(TkJoint& joint) diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h index 1f5e510..9c74bdb 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h @@ -1,19 +1,37 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTPXMANAGERIMPL_H #define NVBLASTEXTPXMANAGERIMPL_H #include "NvBlastExtPxManager.h" -#include "NvBlastExtArray.h" -#include "NvBlastExtHashMap.h" +#include "NvBlastArray.h" +#include "NvBlastHashMap.h" #include "NvBlastExtPxListener.h" #include "NvBlastExtPxFamily.h" @@ -188,10 +206,10 @@ private: TkFramework& m_framework; ExtPxCreateJointFunction m_createJointFn; bool m_usePxUserData; - ExtInlineArray<ExtPxListener*, 8>::type m_listeners; - ExtHashMap<const PxRigidDynamic*, ExtPxActor*>::type m_physXActorsMap; - ExtHashMap<TkFamily*, ExtPxFamily*>::type m_tkFamiliesMap; - ExtHashMap<TkActor*, ExtArray<TkJoint*>::type >::type m_incompleteJointMultiMap; + InlineArray<ExtPxListener*, 8>::type m_listeners; + HashMap<const PxRigidDynamic*, ExtPxActor*>::type m_physXActorsMap; + HashMap<TkFamily*, ExtPxFamily*>::type m_tkFamiliesMap; + HashMap<TkActor*, Array<TkJoint*>::type >::type m_incompleteJointMultiMap; uint32_t m_actorCountLimit; }; diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp new file mode 100644 index 0000000..2b331d3 --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp @@ -0,0 +1,229 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtPxStressSolverImpl.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxFamily.h" +#include "NvBlastExtPxActor.h" +#include "NvBlastAssert.h" +#include "NvBlastIndexFns.h" + +#include "NvBlastTkAsset.h" +#include "NvBlastTkActor.h" +#include "NvBlastTkFamily.h" + +#include "PxScene.h" +#include "PxRigidDynamic.h" + +#define USE_PHYSX_NODE_INFO 1 + + +namespace Nv +{ +namespace Blast +{ + +using namespace physx; + + +ExtPxStressSolverImpl::ExtPxStressSolverImpl(ExtPxFamily& family, ExtStressSolverSettings settings) + : m_family(family) +{ + NvBlastFamily* familyLL = const_cast<NvBlastFamily*>(family.getTkFamily().getFamilyLL()); + NVBLAST_ASSERT(familyLL); + m_solver = ExtStressSolver::create(*familyLL, settings); + + const TkAsset* tkAsset = m_family.getTkFamily().getAsset(); + const ExtPxAsset& asset = m_family.getPxAsset(); + const ExtPxChunk* chunks = asset.getChunks(); + const ExtPxSubchunk* subChunks = asset.getSubchunks(); + const NvBlastSupportGraph graph = tkAsset->getGraph(); + const uint32_t chunkCount = tkAsset->getChunkCount(); + + TkActor* tkActor; + m_family.getTkFamily().getActors(&tkActor, 1); + const float* bondHealths = tkActor->getBondHealths(); + +#if USE_PHYSX_NODE_INFO + // traverse graph and fill node info, + // essentially it does the same as m_solver->setAllNodesInfoFromLL() but fills mass, volume, transform from physx + // and it also uses ExtPxChunk isStatic flag in addition to 'world' node in LL + for (uint32_t node0 = 0; node0 < graph.nodeCount; ++node0) + { + uint32_t chunkIndex0 = graph.chunkIndices[node0]; + const ExtPxChunk* chunk0 = chunkIndex0 < chunkCount ? &chunks[chunkIndex0] : nullptr; + bool isChunkStatic = true; + + if (chunk0) + { + isChunkStatic = chunk0->isStatic; + for (uint32_t adjacencyIndex = graph.adjacencyPartition[node0]; adjacencyIndex < graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) + { + uint32_t bondIndex = graph.adjacentBondIndices[adjacencyIndex]; + if (bondHealths[bondIndex] <= 0.0f) + continue; + uint32_t node1 = graph.adjacentNodeIndices[adjacencyIndex]; + uint32_t chunkIndex1 = graph.chunkIndices[node1]; + if (chunkIndex1 < chunkCount) + { + const ExtPxChunk& chunk1 = chunks[chunkIndex1]; + + if (chunk1.subchunkCount == 0 || chunk1.isStatic) + { + isChunkStatic |= chunk1.isStatic; + continue; + } + } + else + { + isChunkStatic = true; + break; + } + } + } + + // fill node info + float mass; + float volume; + PxVec3 localPos; + if (chunk0 && chunk0->subchunkCount > 0) + { + const ExtPxSubchunk& subChunk = subChunks[chunk0->firstSubchunkIndex]; + PxVec3 localCenterOfMass; + PxMat33 intertia; + PxVec3 scale = subChunk.geometry.scale.scale; + subChunk.geometry.convexMesh->getMassInformation(mass, intertia, localCenterOfMass); + mass *= scale.x * scale.y * scale.z; + const PxTransform& chunk0LocalTransform = subChunk.transform; + localPos = chunk0LocalTransform.transform(localCenterOfMass); + volume = mass / 1.0f; // unit density + } + else + { + mass = 0.0f; + volume = 0.0f; + localPos = PxVec3(PxZero); + isChunkStatic = true; + } + m_solver->setNodeInfo(node0, mass, volume, localPos, isChunkStatic); + } +#else + m_solver->setAllNodesInfoFromLL(); +#endif + + // notify initial actor's created + InlineArray<ExtPxActor*, 4>::type actors;; + actors.resize(m_family.getActorCount()); + m_family.getActors(actors.begin(), actors.size()); + for (const auto actor : actors) + { + onActorCreated(m_family, *actor); + } + + m_family.subscribe(*this); +} + +ExtPxStressSolverImpl::~ExtPxStressSolverImpl() +{ + m_family.unsubscribe(*this); + m_solver->release(); +} + +ExtPxStressSolver* ExtPxStressSolver::create(ExtPxFamily& family, ExtStressSolverSettings settings) +{ + return NVBLAST_NEW(ExtPxStressSolverImpl) (family, settings); +} + +void ExtPxStressSolverImpl::release() +{ + NVBLAST_DELETE(this, ExtPxStressSolverImpl); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Update Wrapper +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ExtPxStressSolverImpl::update(bool doDamage) +{ + for (auto it = m_actors.getIterator(); !it.done(); ++it) + { + const ExtPxActor* actor = *it; + + PxRigidDynamic& rigidDynamic = actor->getPhysXActor(); + const bool isStatic = rigidDynamic.getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC; + if (isStatic) + { + PxVec3 gravity = rigidDynamic.getScene()->getGravity(); + PxVec3 localGravity = rigidDynamic.getGlobalPose().rotateInv(gravity); + + m_solver->addGravityForce(*actor->getTkActor().getActorLL(), localGravity); + } + else + { + PxVec3 localCenterMass = rigidDynamic.getCMassLocalPose().p; + PxVec3 localAngularVelocity = rigidDynamic.getGlobalPose().rotateInv(rigidDynamic.getAngularVelocity()); + m_solver->addAngularVelocity(*actor->getTkActor().getActorLL(), localCenterMass, localAngularVelocity); + } + } + + m_solver->update(); + + if (doDamage && m_solver->getOverstressedBondCount() > 0) + { + NvBlastFractureBuffers commands; + m_solver->generateFractureCommands(commands); + if (commands.bondFractureCount > 0) + { + m_family.getTkFamily().applyFracture(&commands); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Actors +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ExtPxStressSolverImpl::onActorCreated(ExtPxFamily& /*family*/, ExtPxActor& actor) +{ + if (m_solver->notifyActorCreated(*actor.getTkActor().getActorLL())) + { + m_actors.insert(&actor); + } +} + +void ExtPxStressSolverImpl::onActorDestroyed(ExtPxFamily& /*family*/, ExtPxActor& actor) +{ + m_solver->notifyActorDestroyed(*actor.getTkActor().getActorLL()); + m_actors.erase(&actor); +} + + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h new file mode 100644 index 0000000..f27fe6c --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h @@ -0,0 +1,86 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTPXSTRESSSOLVERIMPL_H +#define NVBLASTEXTPXSTRESSSOLVERIMPL_H + +#include "NvBlastExtPxStressSolver.h" +#include "NvBlastExtPxListener.h" +#include "NvBlastArray.h" +#include "NvBlastHashSet.h" + +namespace Nv +{ +namespace Blast +{ + + +class ExtPxStressSolverImpl final : public ExtPxStressSolver, ExtPxListener +{ + NV_NOCOPY(ExtPxStressSolverImpl) + +public: + ExtPxStressSolverImpl(ExtPxFamily& family, ExtStressSolverSettings settings); + + + //////// ExtPxStressSolver interface //////// + + virtual void release() override; + + virtual ExtStressSolver& getSolver() const override + { + return *m_solver; + } + + virtual void update(bool doDamage) override; + + + //////// ExtPxListener interface //////// + + virtual void onActorCreated(ExtPxFamily& family, ExtPxActor& actor) final; + + virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) final; + + +private: + ~ExtPxStressSolverImpl(); + + + //////// data //////// + + ExtPxFamily& m_family; + ExtStressSolver* m_solver; + HashSet<ExtPxActor*>::type m_actors; +}; + + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTPXSTRESSSOLVERIMPL_H diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp new file mode 100644 index 0000000..55a6eae --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp @@ -0,0 +1,126 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastGlobals.h" +#include "NvBlastExtPxTaskImpl.h" + +#include "NvBlastTkGroup.h" + +using namespace Nv::Blast; + + +uint32_t ExtGroupTaskManagerImpl::process(uint32_t workerCount) +{ + NVBLAST_CHECK_WARNING(m_group != nullptr, "ExtGroupTaskManager::process cannot process, no group set.", return 0); + NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::process group is already being processed.", return 0); + + // at least one task must start, even when dispatcher has none specified + uint32_t dispatcherThreads = m_taskManager.getCpuDispatcher()->getWorkerCount(); + dispatcherThreads = dispatcherThreads > 0 ? dispatcherThreads : 1; + + // not expecting an arbitrary amount of tasks + uint32_t availableTasks = TASKS_MAX_COUNT; + + // use workerCount tasks, unless dispatcher has less threads or less tasks are available + uint32_t requestedTasks = workerCount > 0 ? workerCount : dispatcherThreads; + requestedTasks = requestedTasks > dispatcherThreads ? dispatcherThreads : requestedTasks; + requestedTasks = requestedTasks > availableTasks ? availableTasks : requestedTasks; + + // ensure the group has enough memory allocated for concurrent processing + m_group->setWorkerCount(requestedTasks); + + // check if there is work to do + uint32_t jobCount = m_group->startProcess(); + + if (jobCount) + { + // don't start more tasks than jobs are available + requestedTasks = requestedTasks > jobCount ? jobCount : requestedTasks; + + // common counter for all tasks + m_counter.reset(jobCount); + + // set to busy state + m_sync.setCount(requestedTasks); + + // set up tasks + for (uint32_t i = 0; i < requestedTasks; i++) + { + m_tasks[i].setup(m_group, &m_counter, &m_sync); + m_tasks[i].setContinuation(m_taskManager, nullptr); + m_tasks[i].removeReference(); + } + + return requestedTasks; + } + + // there was no work to be done + return 0; +} + + +bool ExtGroupTaskManagerImpl::wait(bool block) +{ + if (block && !m_sync.isDone()) + { + m_sync.wait(); + } + if (m_sync.isDone()) + { + return m_group->endProcess(); + } + return false; +} + + +void ExtGroupTaskManagerImpl::setGroup(TkGroup* group) +{ + NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::setGroup trying to change group while processing.", return); + + m_group = group; +} + + +ExtGroupTaskManager* ExtGroupTaskManager::create(physx::PxTaskManager& taskManager) +{ + return NVBLAST_NEW(ExtGroupTaskManagerImpl) (taskManager); +} + + +ExtGroupTaskManager* ExtGroupTaskManager::create(physx::PxTaskManager& taskManager, TkGroup& group) +{ + return NVBLAST_NEW(ExtGroupTaskManagerImpl) (taskManager, group); +} + + +void ExtGroupTaskManagerImpl::release() +{ + NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::release group is still being processed.", return); + + NVBLAST_DELETE(this, ExtGroupTaskManagerImpl); +} diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h new file mode 100644 index 0000000..f705e71 --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h @@ -0,0 +1,212 @@ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTPXTASKIMPL_H +#define NVBLASTEXTPXTASKIMPL_H + +#include "NvBlastExtPxTask.h" +#include "PxTask.h" +#include "NvBlastTkGroup.h" + +#include <atomic> +#include <mutex> +#include <condition_variable> + +namespace Nv +{ +namespace Blast +{ + +/** +Counting synchronization object for waiting on TkWorkers to finish. +*/ +class ExtTaskSync +{ +public: + /** + Initializes with an expected number of notifications. + */ + ExtTaskSync(uint32_t count) : m_count(count) {} + + /** + Blocks until the expected number of notifications happened. + */ + void wait() + { + std::unique_lock<std::mutex> lk(m_mutex); + m_cv.wait(lk, [&] { return m_count == 0; }); + } + + /** + Decrement the wait() count by one. + */ + void notify() + { + //PERF_SCOPE_H("TaskSync::notify"); + std::unique_lock<std::mutex> lk(m_mutex); + if (m_count > 0) + { + m_count--; + } + if (m_count == 0) + { + lk.unlock(); + m_cv.notify_one(); + } + } + + /** + Peek if notifications are pending. + */ + bool isDone() + { + std::unique_lock<std::mutex> lk(m_mutex); + return m_count == 0; + } + + /** + Sets the expected number of notifications for wait() to unblock. + */ + void setCount(uint32_t count) + { + m_count = count; + } + +private: + std::mutex m_mutex; + std::condition_variable m_cv; + uint32_t m_count; +}; + + +/** +Common job counter for all tasks. +*/ +class ExtAtomicCounter +{ +public: + ExtAtomicCounter() : m_current(0), m_maxCount(0) {} + + bool isValid(uint32_t val) + { + return val < m_maxCount; + } + + uint32_t next() + { + return m_current.fetch_add(1); + } + + void reset(uint32_t maxCount) + { + m_maxCount = maxCount; + m_current = 0; + } +private: + std::atomic<uint32_t> m_current; + uint32_t m_maxCount; +}; + + +/** +A task running one group job after the other until done. Synchronizes atomically with its siblings. +*/ +class ExtGroupWorkerTask : public physx::PxLightCpuTask +{ +public: + ExtGroupWorkerTask() : PxLightCpuTask(), m_group(nullptr), m_counter(nullptr), m_sync(nullptr) + { + } + + void setup(TkGroup* group, ExtAtomicCounter* counter, ExtTaskSync* sync) + { + m_group = group; + m_counter = counter; + m_sync = sync; + } + + virtual void run() override + { + Nv::Blast::TkGroupWorker* worker = m_group->acquireWorker(); + uint32_t jobID = m_counter->next(); + while (m_counter->isValid(jobID)) + { + worker->process(jobID); + jobID = m_counter->next(); + } + m_group->returnWorker(worker); + } + + virtual void release() override + { + PxLightCpuTask::release(); + + // release the sync last + m_sync->notify(); + } + + virtual const char* getName() const override { return "BlastGroupWorkerTask"; } + +private: + TkGroup* m_group; + ExtAtomicCounter* m_counter; + ExtTaskSync* m_sync; +}; + + +/** +Implements ExtGroupTaskManager +*/ +class ExtGroupTaskManagerImpl : public ExtGroupTaskManager +{ +public: + ExtGroupTaskManagerImpl(physx::PxTaskManager& taskManager) + : m_taskManager(taskManager), m_sync(0), m_group(nullptr) {} + + ExtGroupTaskManagerImpl(physx::PxTaskManager& taskManager, TkGroup& group) + : m_taskManager(taskManager), m_sync(0), m_group(&group) {} + + // public API + virtual void setGroup(TkGroup*) override; + virtual uint32_t process(uint32_t) override; + virtual void release() override; + virtual bool wait(bool block) override; + +private: + static const uint32_t TASKS_MAX_COUNT = 16; + physx::PxTaskManager& m_taskManager; + ExtAtomicCounter m_counter; + ExtGroupWorkerTask m_tasks[TASKS_MAX_COUNT]; + ExtTaskSync m_sync; + TkGroup* m_group; +}; + +} // namespace Blast +} // namespace Nv + +#endif // NVBLASTEXTPXTASKIMPL_H
\ No newline at end of file diff --git a/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp b/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp index 5f018d9..a74f3e7 100644 --- a/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp +++ b/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp @@ -1,18 +1,34 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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) 2016-2017 NVIDIA Corporation. All rights reserved. #include "NvBlastExtSync.h" #include "NvBlastAssert.h" #include "NvBlast.h" -#include "NvBlastExtDefs.h" #include "NvBlastExtPxManager.h" #include "NvBlastExtPxFamily.h" #include "NvBlastExtPxActor.h" @@ -39,7 +55,7 @@ public: ExtSyncImpl(); - ~ExtSyncImpl(); + virtual ~ExtSyncImpl(); //////// TkEventListener interface //////// @@ -74,7 +90,7 @@ private: void ExtSyncEvent::release() { - NVBLASTEXT_DELETE(this, ExtSyncEvent); + NVBLAST_DELETE(this, ExtSyncEvent); } @@ -84,12 +100,12 @@ void ExtSyncEvent::release() ExtSync* ExtSync::create() { - return NVBLASTEXT_NEW(ExtSyncImpl) (); + return NVBLAST_NEW(ExtSyncImpl) (); } void ExtSyncImpl::release() { - NVBLASTEXT_DELETE(this, ExtSyncImpl); + NVBLAST_DELETE(this, ExtSyncImpl); } ExtSyncImpl::ExtSyncImpl() @@ -109,7 +125,7 @@ void ExtSyncImpl::receive(const TkEvent* events, uint32_t eventCount) if (tkEvent.type == TkEvent::FractureCommand) { const TkFractureCommands* fracEvent = tkEvent.getPayload<TkFractureCommands>(); - ExtSyncEventFracture* e = NVBLASTEXT_NEW(ExtSyncEventFracture) (); + ExtSyncEventFracture* e = NVBLAST_NEW(ExtSyncEventFracture) (); e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); e->familyID = fracEvent->tkActorData.family->getID(); e->bondFractures.resize(fracEvent->buffers.bondFractureCount); @@ -123,11 +139,11 @@ void ExtSyncImpl::receive(const TkEvent* events, uint32_t eventCount) void ExtSyncImpl::syncFamily(const TkFamily& family) { - ExtSyncEventFamilySync* e = NVBLASTEXT_NEW(ExtSyncEventFamilySync) (); + ExtSyncEventFamilySync* e = NVBLAST_NEW(ExtSyncEventFamilySync) (); e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); e->familyID = family.getID(); const NvBlastFamily* familyLL = family.getFamilyLL(); - const uint32_t size = NvBlastFamilyGetSize(familyLL, NvBlastTkFrameworkGet()->getLogFn()); + const uint32_t size = NvBlastFamilyGetSize(familyLL, logLL); e->family = std::vector<char>((char*)familyLL, (char*)familyLL + size); m_syncEvents.push_back(e); } @@ -138,7 +154,7 @@ void ExtSyncImpl::syncFamily(const ExtPxFamily& family) syncFamily(tkFamily); - ExtSyncEventPhysicsSync* e = NVBLASTEXT_NEW(ExtSyncEventPhysicsSync) (); + ExtSyncEventPhysicsSync* e = NVBLAST_NEW(ExtSyncEventPhysicsSync) (); e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); e->familyID = tkFamily.getID(); std::vector<ExtPxActor*> actors(family.getActorCount()); @@ -170,7 +186,7 @@ void ExtSyncImpl::releaseSyncBuffer() { for (uint32_t i = 0; i < m_syncEvents.size(); ++i) { - NVBLASTEXT_DELETE(m_syncEvents[i], ExtSyncEvent); + NVBLAST_DELETE(m_syncEvents[i], ExtSyncEvent); } m_syncEvents.clear(); } |