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 | |
| 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')
276 files changed, 22436 insertions, 10591 deletions
diff --git a/sdk/common/NvBlastArray.h b/sdk/common/NvBlastArray.h new file mode 100644 index 0000000..48048d1 --- /dev/null +++ b/sdk/common/NvBlastArray.h @@ -0,0 +1,67 @@ +// 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 NVBLASTARRAY_H +#define NVBLASTARRAY_H + + +#include "NvBlastAllocator.h" +#include "PsInlineArray.h" + + +namespace Nv +{ +namespace Blast +{ + +/** +Wrapped PxShared Array that uses NvBlastGlobals AllocatorCalllback. +*/ +template <class T> +struct Array +{ + typedef physx::shdfnd::Array<T, Allocator> type; +}; + + +/** +Wrapped PxShared InlineArray that uses NvBlastGlobals AllocatorCalllback. + +InlineArraya is array that pre-allocates for N elements. +*/ +template <class T, uint32_t N> +struct InlineArray +{ + typedef physx::shdfnd::InlineArray<T, N, Allocator> type; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // #ifndef NVBLASTARRAY_H diff --git a/sdk/common/NvBlastAssert.cpp b/sdk/common/NvBlastAssert.cpp index 7731a53..0f2b316 100644 --- a/sdk/common/NvBlastAssert.cpp +++ b/sdk/common/NvBlastAssert.cpp @@ -1,12 +1,29 @@ -/* - * 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 "NvBlastAssert.h" @@ -40,7 +57,7 @@ void NvBlastAssertHandler(const char* expr, const char* file, int line, bool& ig if (ignore) return; __debugbreak(); -#elif (NV_WINDOWS_FAMILY && NV_CHECKED) || NV_CLANG +#elif (NV_WINDOWS_FAMILY && NV_CHECKED) __debugbreak(); #else abort(); diff --git a/sdk/common/NvBlastAssert.h b/sdk/common/NvBlastAssert.h index b1b7ca5..f121acc 100644 --- a/sdk/common/NvBlastAssert.h +++ b/sdk/common/NvBlastAssert.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 NVBLASTASSERT_H #define NVBLASTASSERT_H @@ -17,7 +35,7 @@ #if !NV_ENABLE_ASSERTS #define NVBLAST_ASSERT(exp) ((void)0) -#define NVBLAST_ALWAYS_ASSERT_MESSAGE(exp) ((void)0) +#define NVBLAST_ALWAYS_ASSERT_MESSAGE(message) ((void)0) #define NVBLAST_ASSERT_WITH_MESSAGE(condition, message) ((void)0) #else #if NV_VC @@ -33,12 +51,12 @@ if (!(exp) && !_ignore) NvBlastAssertHandler(#exp, __FILE__, __LINE__, _ignore); \ NVBLAST_CODE_ANALYSIS_ASSUME(exp); \ } ((void)0) -#define NVBLAST_ALWAYS_ASSERT_MESSAGE(exp) \ +#define NVBLAST_ALWAYS_ASSERT_MESSAGE(message) \ { \ static bool _ignore = false; \ if(!_ignore) \ { \ - NvBlastAssertHandler(exp, __FILE__, __LINE__, _ignore); \ + NvBlastAssertHandler(message, __FILE__, __LINE__, _ignore); \ } \ } ((void)0) #define NVBLAST_ASSERT_WITH_MESSAGE(exp, message) \ diff --git a/sdk/common/NvBlastAtomic.cpp b/sdk/common/NvBlastAtomic.cpp index 6b9d94b..4a79fbf 100644 --- a/sdk/common/NvBlastAtomic.cpp +++ b/sdk/common/NvBlastAtomic.cpp @@ -1,12 +1,29 @@ -/* - * 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 "NvBlastAtomic.h" diff --git a/sdk/common/NvBlastAtomic.h b/sdk/common/NvBlastAtomic.h index a3e6755..6eed1c0 100644 --- a/sdk/common/NvBlastAtomic.h +++ b/sdk/common/NvBlastAtomic.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 NVBLASTATOMIC_H #define NVBLASTATOMIC_H diff --git a/sdk/common/NvBlastDLink.h b/sdk/common/NvBlastDLink.h index bfcee24..b7bfaaa 100644 --- a/sdk/common/NvBlastDLink.h +++ b/sdk/common/NvBlastDLink.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 NVBLASTDLINK_H #define NVBLASTDLINK_H diff --git a/sdk/common/NvBlastFixedArray.h b/sdk/common/NvBlastFixedArray.h index 654158b..837b901 100644 --- a/sdk/common/NvBlastFixedArray.h +++ b/sdk/common/NvBlastFixedArray.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 NVBLASTFIXEDARRAY_H #define NVBLASTFIXEDARRAY_H diff --git a/sdk/common/NvBlastFixedBitmap.h b/sdk/common/NvBlastFixedBitmap.h index af835cf..b1743ed 100644 --- a/sdk/common/NvBlastFixedBitmap.h +++ b/sdk/common/NvBlastFixedBitmap.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 NVBLASTFIXEDBITMAP_H #define NVBLASTFIXEDBITMAP_H diff --git a/sdk/common/NvBlastFixedBoolArray.h b/sdk/common/NvBlastFixedBoolArray.h index 253bed6..deb9733 100644 --- a/sdk/common/NvBlastFixedBoolArray.h +++ b/sdk/common/NvBlastFixedBoolArray.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 NVBLASTFIXEDBOOLARRAY_H #define NVBLASTFIXEDBOOLARRAY_H diff --git a/sdk/common/NvBlastFixedPriorityQueue.h b/sdk/common/NvBlastFixedPriorityQueue.h index 5079edb..1855147 100644 --- a/sdk/common/NvBlastFixedPriorityQueue.h +++ b/sdk/common/NvBlastFixedPriorityQueue.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 NVBLASTFIXEDPRIORITYQUEUE_H #define NVBLASTFIXEDPRIORITYQUEUE_H diff --git a/sdk/common/NvBlastGeometry.h b/sdk/common/NvBlastGeometry.h index e83ff95..97220f5 100644 --- a/sdk/common/NvBlastGeometry.h +++ b/sdk/common/NvBlastGeometry.h @@ -1,12 +1,29 @@ -/* -* 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 NVBLASTGEOMETRY_H @@ -14,36 +31,98 @@ #include "NvBlastTypes.h" #include "NvBlastMath.h" +#include "NvBlastAssert.h" -#include<limits> +#include <limits> namespace Nv { namespace Blast{ -NV_FORCE_INLINE uint32_t findNodeByPositionLinked(const float point[4], + +/** +Find the closest node to point in the graph. Uses primarily distance to chunk centroids. +Bond normals are expected to be directed from the lower to higher node index. +Cannot be used for graph actors with only the world chunk in the graph. + +\param[in] point the point to test against +\param[in] firstGraphNodeIndex the entry point for familyGraphNodeIndexLinks +\param[in] familyGraphNodeIndexLinks the list index links of the actor's graph +\param[in] adjacencyPartition the actor's SupportGraph adjacency partition +\param[in] adjacentNodeIndices the actor's SupportGraph adjacent node indices +\param[in] adjacentBondIndices the actor's SupportGraph adjacent bond indices +\param[in] assetBonds the actor's asset bonds +\param[in] bondHealths the actor's bond healths +\param[in] assetChunks the actor's asset chunks +\param[in] supportChunkHealths the actor's graph chunks healths +\param[in] chunkIndices maps node index to chunk index in SupportGraph + +\return the index of the node closest to point +*/ +NV_FORCE_INLINE uint32_t findClosestNode(const float point[4], const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks, const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices, - const NvBlastBond* bonds, const float* bondHealths) + const NvBlastBond* assetBonds, const float* bondHealths, + const NvBlastChunk* assetChunks, const float* supportChunkHealths, const uint32_t* chunkIndices) { + // firstGraphNodeIndex could still be the world chunk, however + // there should be no way a single-node actor that is just the world chunk exists. uint32_t nodeIndex = firstGraphNodeIndex; + // Since there should always be a regular chunk in the graph, it is possible to initialize closestNode + // as world chunk index but it would always evaluate to some meaningful node index eventually. uint32_t closestNode = nodeIndex; float minDist = std::numeric_limits<float>().max(); + // find the closest healthy chunk in the graph by its centroid to point distance while (!Nv::Blast::isInvalidIndex(nodeIndex)) { + if (supportChunkHealths[nodeIndex] > 0.0f) + { + uint32_t chunkIndex = chunkIndices[nodeIndex]; + if (!isInvalidIndex(chunkIndex)) // Invalid if this is the world chunk + { + const NvBlastChunk& chunk = assetChunks[chunkIndex]; + const float* centroid = chunk.centroid; + + float d[3]; VecMath::sub(point, centroid, d); + float dist = VecMath::dot(d, d); + + if (dist < minDist) + { + minDist = dist; + closestNode = nodeIndex; + } + } + } + nodeIndex = familyGraphNodeIndexLinks[nodeIndex]; + } + + // as long as the world chunk is not input as a single-node graph actor + NVBLAST_ASSERT(!isInvalidIndex(chunkIndices[closestNode])); + + bool iterateOnBonds = true; + if (iterateOnBonds) + { + // improve geometric accuracy by looking on which side of the closest bond the point lies + // expects bond normals to point from the smaller to the larger node index + + nodeIndex = closestNode; + minDist = std::numeric_limits<float>().max(); + const uint32_t startIndex = adjacencyPartition[nodeIndex]; const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1]; for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++) { const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex]; - if (nodeIndex < neighbourIndex) + const uint32_t neighbourChunk = chunkIndices[neighbourIndex]; + if (!isInvalidIndex(neighbourChunk)) // Invalid if neighbor is the world chunk { const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; - if (bondHealths[bondIndex] > 0.0f) + // do not follow broken bonds, since it means that neighbor is not actually connected in the graph + if (bondHealths[bondIndex] > 0.0f && supportChunkHealths[neighbourIndex] > 0.0f) { - const NvBlastBond& bond = bonds[bondIndex]; + const NvBlastBond& bond = assetBonds[bondIndex]; const float* centroid = bond.centroid; float d[3]; VecMath::sub(point, centroid, d); @@ -53,39 +132,67 @@ NV_FORCE_INLINE uint32_t findNodeByPositionLinked(const float point[4], { minDist = dist; float s = VecMath::dot(d, bond.normal); - closestNode = s < 0 ? nodeIndex : neighbourIndex; + if (nodeIndex < neighbourIndex) + { + closestNode = s < 0.0f ? nodeIndex : neighbourIndex; + } + else + { + closestNode = s < 0.0f ? neighbourIndex : nodeIndex; + } } } } } - nodeIndex = familyGraphNodeIndexLinks[nodeIndex]; } return closestNode; } -NV_FORCE_INLINE uint32_t findNodeByPosition(const float point[4], - const uint32_t graphNodesCount, const uint32_t* graphNodeIndices, +/** +Find the closest node to point in the graph. Uses primarily distance to bond centroids. +Slower compared to chunk based lookup but may yield better accuracy in some cases. +Bond normals are expected to be directed from the lower to higher node index. +Cannot be used for graph actors with only the world chunk in the graph. + +\param[in] point the point to test against +\param[in] firstGraphNodeIndex the entry point for familyGraphNodeIndexLinks +\param[in] familyGraphNodeIndexLinks the list index links of the actor's graph +\param[in] adjacencyPartition the actor's SupportGraph adjacency partition +\param[in] adjacentNodeIndices the actor's SupportGraph adjacent node indices +\param[in] adjacentBondIndices the actor's SupportGraph adjacent bond indices +\param[in] assetBonds the actor's asset bonds +\param[in] bondHealths the actor's bond healths +\param[in] chunkIndices maps node index to chunk index in SupportGraph + +\return the index of the node closest to point +*/ +NV_FORCE_INLINE uint32_t findClosestNode(const float point[4], + const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks, const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices, - const NvBlastBond* bonds, const float* bondHealths) + const NvBlastBond* bonds, const float* bondHealths, const uint32_t* chunkIndices) { - uint32_t closestNode = graphNodesCount > 2 ? invalidIndex<uint32_t>() : graphNodeIndices[0]; + // firstGraphNodeIndex could still be the world chunk, however + // there should be no way a single-node actor that is just the world chunk exists. + uint32_t nodeIndex = firstGraphNodeIndex; + // Since there should always be a regular chunk in the graph, it is possible to initialize closestNode + // as world chunk index but it would always evaluate to some meaningful node index eventually. + uint32_t closestNode = nodeIndex; float minDist = std::numeric_limits<float>().max(); - for (uint32_t i = 0; i < graphNodesCount; i++) + while (!Nv::Blast::isInvalidIndex(nodeIndex)) { - const uint32_t nodeIndex = graphNodeIndices[i]; const uint32_t startIndex = adjacencyPartition[nodeIndex]; const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1]; for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++) { - const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; - if (bondHealths[bondIndex] > 0.0f) + const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex]; + if (nodeIndex < neighbourIndex) { - const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex]; - if (nodeIndex < neighbourIndex) + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + if (bondHealths[bondIndex] > 0.0f) { const NvBlastBond& bond = bonds[bondIndex]; @@ -96,25 +203,33 @@ NV_FORCE_INLINE uint32_t findNodeByPosition(const float point[4], if (dist < minDist) { minDist = dist; - float s = VecMath::dot(d, bond.normal); - closestNode = s < 0 ? nodeIndex : neighbourIndex; + // if any of the nodes is the world chunk, use the valid one instead + if (isInvalidIndex(chunkIndices[neighbourIndex])) + { + closestNode = nodeIndex; + } + else if (isInvalidIndex(chunkIndices[nodeIndex])) + { + closestNode = neighbourIndex; + } + else + { + float s = VecMath::dot(d, bond.normal); + closestNode = s < 0 ? nodeIndex : neighbourIndex; + } } } } } + nodeIndex = familyGraphNodeIndexLinks[nodeIndex]; } + + // as long as the world chunk is not input as a single-node graph actor + NVBLAST_ASSERT(!isInvalidIndex(chunkIndices[closestNode])); return closestNode; } -NV_FORCE_INLINE uint32_t findNodeByPosition(const float point[4], - const uint32_t graphNodesCount, const uint32_t* graphNodeIndices, - const NvBlastSupportGraph& graph, - const NvBlastBond* bonds, const float* bondHealths) -{ - return findNodeByPosition(point, graphNodesCount, graphNodeIndices, graph.adjacencyPartition, graph.adjacentNodeIndices, graph.adjacentBondIndices, bonds, bondHealths); -} - } // namespace Blast } // namespace Nv diff --git a/sdk/common/NvBlastHashMap.h b/sdk/common/NvBlastHashMap.h new file mode 100644 index 0000000..ddfaa04 --- /dev/null +++ b/sdk/common/NvBlastHashMap.h @@ -0,0 +1,55 @@ +// 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 NVBLASTHASHMAP_H +#define NVBLASTHASHMAP_H + + +#include "NvBlastAllocator.h" +#include "PsHashMap.h" + + +namespace Nv +{ +namespace Blast +{ + +/** +Wrapped PxShared HashMap that uses NvBlastGlobals AllocatorCalllback. +*/ +template <class Key, class Value, class HashFn = physx::shdfnd::Hash<Key>> +struct HashMap +{ + typedef physx::shdfnd::HashMap<Key, Value, HashFn, Allocator> type; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // #ifndef NVBLASTHASHMAP_H diff --git a/sdk/common/NvBlastHashSet.h b/sdk/common/NvBlastHashSet.h new file mode 100644 index 0000000..3f31462 --- /dev/null +++ b/sdk/common/NvBlastHashSet.h @@ -0,0 +1,54 @@ +// 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 NVBLASTHASHSET_H +#define NVBLASTHASHSET_H + + +#include "NvBlastAllocator.h" +#include "PsHashSet.h" + +namespace Nv +{ +namespace Blast +{ + +/** +Wrapped PxShared HashSet that uses NvBlastGlobals AllocatorCalllback. +*/ +template <class Key, class HashFn = physx::shdfnd::Hash<Key>> +struct HashSet +{ + typedef physx::shdfnd::HashSet<Key, HashFn, Allocator> type; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // #ifndef NVBLASTHASHSET_H diff --git a/sdk/common/NvBlastIncludeWindows.h b/sdk/common/NvBlastIncludeWindows.h index 9115fd4..86a5818 100644 --- a/sdk/common/NvBlastIncludeWindows.h +++ b/sdk/common/NvBlastIncludeWindows.h @@ -3,15 +3,28 @@ // // Notice // NVIDIA Corporation and its licensors retain all intellectual property and -/* -* 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. -*/ +// 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 NVBLASTINCLUDEWINDOWS_H #define NVBLASTINCLUDEWINDOWS_H diff --git a/sdk/common/NvBlastIndexFns.h b/sdk/common/NvBlastIndexFns.h index a800a73..b4154ad 100644 --- a/sdk/common/NvBlastIndexFns.h +++ b/sdk/common/NvBlastIndexFns.h @@ -1,12 +1,30 @@ -/* - * Copyright (c) 2008-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) 2008-2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTINDEXFNS_H #define NVBLASTINDEXFNS_H diff --git a/sdk/common/NvBlastIteratorBase.h b/sdk/common/NvBlastIteratorBase.h index 9053f4b..2de8d09 100644 --- a/sdk/common/NvBlastIteratorBase.h +++ b/sdk/common/NvBlastIteratorBase.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 NVBLASTITERATORBASE_H #define NVBLASTITERATORBASE_H diff --git a/sdk/common/NvBlastMath.h b/sdk/common/NvBlastMath.h index 0a29f14..4a4522e 100644 --- a/sdk/common/NvBlastMath.h +++ b/sdk/common/NvBlastMath.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 NVBLASTMATH_H #define NVBLASTMATH_H @@ -60,13 +78,25 @@ NV_INLINE float dot(const float a[3], const float b[3]) return r; } +NV_INLINE float length(const float a[3]) +{ + return sqrtf(dot(a, a)); +} + +NV_INLINE float dist(const float a[3], const float b[3]) +{ + float v[3]; + sub(a, b, v); + return length(v); +} + NV_INLINE float normal(const float a[3], float r[3]) { - float length = sqrtf(dot(a, a)); + float d = length(a); for (int i = 0; i < 3; i++) - r[i] = a[i] / length; + r[i] = a[i] / d; - return length; + return d; } diff --git a/sdk/common/NvBlastMemory.h b/sdk/common/NvBlastMemory.h index 0fb6a06..e21854e 100644 --- a/sdk/common/NvBlastMemory.h +++ b/sdk/common/NvBlastMemory.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 NVBLASTMEMORY_H #define NVBLASTMEMORY_H @@ -104,7 +122,7 @@ align16(_lastOffset + _lastSize) #include <malloc.h> #define NvBlastAlloca(x) _alloca(x) #elif NV_LINUX || NV_ANDROID -#include <malloc.h> +#include <alloca.h> #define NvBlastAlloca(x) alloca(x) #elif NV_APPLE_FAMILY #include <alloca.h> diff --git a/sdk/common/NvBlastPreprocessorInternal.h b/sdk/common/NvBlastPreprocessorInternal.h index 2d3e185..c6ef511 100644 --- a/sdk/common/NvBlastPreprocessorInternal.h +++ b/sdk/common/NvBlastPreprocessorInternal.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 NVBLASTPREPROCESSORINTERNAL_H #define NVBLASTPREPROCESSORINTERNAL_H @@ -15,12 +33,21 @@ #include "NvPreprocessor.h" +/** +Macros for more convenient logging +*/ +#define NVBLASTLL_LOG_ERROR(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Error, _msg, __FILE__, __LINE__); } ((void)0) +#define NVBLASTLL_LOG_WARNING(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Warning, _msg, __FILE__, __LINE__); } ((void)0) +#define NVBLASTLL_LOG_INFO(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Info, _msg, __FILE__, __LINE__); } ((void)0) +#define NVBLASTLL_LOG_DEBUG(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Debug, _msg, __FILE__, __LINE__); } ((void)0) + + /** Blast will check function parameters for debug and checked builds. */ -#define NVBLAST_CHECK_PARAMS (NV_DEBUG || NV_CHECKED) +#define NVBLASTLL_CHECK_PARAMS (NV_DEBUG || NV_CHECKED) -#if NVBLAST_CHECK_PARAMS -#define NVBLAST_CHECK(_expr, _logFn, _msg, _onFail) \ +#if NVBLASTLL_CHECK_PARAMS +#define NVBLASTLL_CHECK(_expr, _logFn, _msg, _onFail) \ { \ if(!(_expr)) \ { \ @@ -29,7 +56,7 @@ } \ } #else -#define NVBLAST_CHECK(_expr, _logFn, _msg, _onFail) NV_UNUSED(_logFn) +#define NVBLASTLL_CHECK(_expr, _logFn, _msg, _onFail) NV_UNUSED(_logFn) #endif diff --git a/sdk/common/NvBlastTime.cpp b/sdk/common/NvBlastTime.cpp index b16e573..035d45e 100644 --- a/sdk/common/NvBlastTime.cpp +++ b/sdk/common/NvBlastTime.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 "NvBlastTime.h" #include "NvBlast.h" diff --git a/sdk/common/NvBlastTime.h b/sdk/common/NvBlastTime.h index 47af36b..3cac5f7 100644 --- a/sdk/common/NvBlastTime.h +++ b/sdk/common/NvBlastTime.h @@ -3,15 +3,28 @@ // // Notice // NVIDIA Corporation and its licensors retain all intellectual property and -/* -* 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. -*/ +// 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 NVBLASTTIME_H #define NVBLASTTIME_H diff --git a/sdk/common/NvBlastTimers.cpp b/sdk/common/NvBlastTimers.cpp index ec93134..4527e1f 100644 --- a/sdk/common/NvBlastTimers.cpp +++ b/sdk/common/NvBlastTimers.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 "NvBlast.h" #include "NvBlastTime.h" diff --git a/sdk/compiler/cmake/NvBlast.cmake b/sdk/compiler/cmake/NvBlast.cmake index 5ac9ce9..576328d 100644 --- a/sdk/compiler/cmake/NvBlast.cmake +++ b/sdk/compiler/cmake/NvBlast.cmake @@ -37,6 +37,7 @@ SET(PUBLIC_FILES ${PUBLIC_INCLUDE_DIR}/NvBlast.h ${PUBLIC_INCLUDE_DIR}/NvBlastPreprocessor.h ${PUBLIC_INCLUDE_DIR}/NvBlastTypes.h + ${PUBLIC_INCLUDE_DIR}/NvCTypes.h ${PUBLIC_INCLUDE_DIR}/NvPreprocessor.h ) @@ -80,10 +81,13 @@ TARGET_COMPILE_DEFINITIONS(NvBlast PRIVATE ${BLAST_COMPILE_DEFS} ) +TARGET_COMPILE_OPTIONS(NvBlast + PRIVATE ${BLAST_PLATFORM_COMPILE_OPTIONS} +) + SET_TARGET_PROPERTIES(NvBlast PROPERTIES PDB_NAME_DEBUG "NvBlast${CMAKE_DEBUG_POSTFIX}" PDB_NAME_CHECKED "NvBlast${CMAKE_CHECKED_POSTFIX}" PDB_NAME_PROFILE "NvBlast${CMAKE_PROFILE_POSTFIX}" PDB_NAME_RELEASE "NvBlast${CMAKE_RELEASE_POSTFIX}" ) - diff --git a/sdk/compiler/cmake/NvBlastExtAuthoring.cmake b/sdk/compiler/cmake/NvBlastExtAuthoring.cmake index dda8056..9ba6173 100644 --- a/sdk/compiler/cmake/NvBlastExtAuthoring.cmake +++ b/sdk/compiler/cmake/NvBlastExtAuthoring.cmake @@ -11,6 +11,8 @@ SET(AUTHORING_EXT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/extensions/authoring/include FIND_PACKAGE(PxSharedSDK $ENV{PM_PxShared_VERSION} REQUIRED) FIND_PACKAGE(PhysXSDK $ENV{PM_PhysX_VERSION} REQUIRED) +FIND_PACKAGE(BoostMultiprecision $ENV{PM_BoostMultiprecision_VERSION} REQUIRED) + # Include here after the directories are defined so that the platform specific file can use the variables. include(${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/NvBlastExtAuthoring.cmake) @@ -28,29 +30,40 @@ SET(PUBLIC_FILES ${AUTHORING_EXT_INCLUDE_DIR}/NvBlastExtAuthoringFractureTool.h ${AUTHORING_EXT_INCLUDE_DIR}/NvBlastExtAuthoringMesh.h ${AUTHORING_EXT_INCLUDE_DIR}/NvBlastExtAuthoringTypes.h + ${AUTHORING_EXT_INCLUDE_DIR}/NvBlastExtAuthoring.h + ${AUTHORING_EXT_INCLUDE_DIR}/NvBlastExtAuthoringMeshCleaner.h ) SET(EXT_AUTHORING_FILES ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringAccelerator.cpp ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringAccelerator.h - ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringBondGenerator.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringBondGeneratorImpl.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringBondGeneratorImpl.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringBooleanTool.cpp ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringBooleanTool.h - ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringCollisionBuilder.cpp - ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMesh.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringCollisionBuilderImpl.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringCollisionBuilderImpl.h + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMeshImpl.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMeshImpl.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringPerlinNoise.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringTriangulator.cpp ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringTriangulator.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringVSA.h - ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringFractureTool.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringFractureToolImpl.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringFractureToolImpl.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtTriangleProcessor.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMeshNoiser.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMeshNoiser.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtTriangleProcessor.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtApexSharedParts.cpp ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtApexSharedParts.h ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringInternalCommon.h + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoring.cpp + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMeshCleanerImpl.h + ${AUTHORING_EXT_SOURCE_DIR}/NvBlastExtAuthoringMeshCleanerImpl.cpp ) -ADD_LIBRARY(NvBlastExtAuthoring STATIC +ADD_LIBRARY(NvBlastExtAuthoring ${BLAST_EXT_SHARED_LIB_TYPE} ${COMMON_FILES} ${PUBLIC_FILES} @@ -70,6 +83,9 @@ TARGET_INCLUDE_DIRECTORIES(NvBlastExtAuthoring PUBLIC ${PROJECT_SOURCE_DIR}/lowlevel/include PUBLIC ${AUTHORING_EXT_INCLUDE_DIR} + PRIVATE ${PROJECT_SOURCE_DIR}/toolkit/include + PRIVATE ${PHYSX_EXT_INCLUDE_DIR} + PRIVATE ${PROJECT_SOURCE_DIR}/common PRIVATE ${COMMON_EXT_SOURCE_DIR} @@ -77,6 +93,8 @@ TARGET_INCLUDE_DIRECTORIES(NvBlastExtAuthoring PRIVATE ${PHYSXSDK_INCLUDE_DIRS} PRIVATE ${PXSHAREDSDK_INCLUDE_DIRS} + + PRIVATE ${BOOSTMULTIPRECISION_INCLUDE_DIRS} ) TARGET_COMPILE_DEFINITIONS(NvBlastExtAuthoring @@ -97,10 +115,6 @@ SET_TARGET_PROPERTIES(NvBlastExtAuthoring PROPERTIES # Do final direct sets after the target has been defined TARGET_LINK_LIBRARIES(NvBlastExtAuthoring - PRIVATE NvBlast + PUBLIC NvBlast NvBlastGlobals PUBLIC ${BLASTEXT_PLATFORM_LINKED_LIBS} - PUBLIC $<$<CONFIG:debug>:${PHYSX3_LIB_DEBUG}> $<$<CONFIG:debug>:${PHYSX3EXTENSIONS_LIB_DEBUG}> $<$<CONFIG:debug>:${PXFOUNDATION_LIB_DEBUG}> - PUBLIC $<$<CONFIG:checked>:${PHYSX3_LIB_CHECKED}> $<$<CONFIG:checked>:${PHYSX3EXTENSIONS_LIB_CHECKED}> $<$<CONFIG:checked>:${PXFOUNDATION_LIB_CHECKED}> - PUBLIC $<$<CONFIG:profile>:${PHYSX3_LIB_PROFILE}> $<$<CONFIG:profile>:${PHYSX3EXTENSIONS_LIB_PROFILE}> $<$<CONFIG:profile>:${PXFOUNDATION_LIB_PROFILE}> - PUBLIC $<$<CONFIG:release>:${PHYSX3_LIB}> $<$<CONFIG:release>:${PHYSX3EXTENSIONS_LIB}> $<$<CONFIG:release>:${PXFOUNDATION_LIB}> ) diff --git a/sdk/compiler/cmake/NvBlastExtConverterLL.cmake b/sdk/compiler/cmake/NvBlastExtConverterLL.cmake deleted file mode 100644 index c84b60d..0000000 --- a/sdk/compiler/cmake/NvBlastExtConverterLL.cmake +++ /dev/null @@ -1,77 +0,0 @@ -# -# Build NvBlastExtConverterLL Common -# - - -SET(COMMON_SOURCE_DIR ${PROJECT_SOURCE_DIR}/common) -SET(CONVERTERLL_EXT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/extensions/converter/source) -SET(CONVERTERLL_EXT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/extensions/converter/include) - - -# Include here after the directories are defined so that the platform specific file can use the variables. -include(${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/NvBlastExtConverterLL.cmake) - -SET(COMMON_FILES - ${BLASTEXT_PLATFORM_COMMON_FILES} - - ${COMMON_SOURCE_DIR}/NvBlastAssert.cpp - ${COMMON_SOURCE_DIR}/NvBlastAssert.h -) - -SET(PUBLIC_FILES - ${CONVERTERLL_EXT_INCLUDE_DIR}/NvBlastExtDataConverter.h -) - -SET(EXT_CONVERSION_FILES - ${CONVERTERLL_EXT_SOURCE_DIR}/conversion/NvBlastExtAssetBlockVersionConverter_v0_v1.h - ${CONVERTERLL_EXT_SOURCE_DIR}/conversion/NvBlastExtBinaryBlockConverter.cpp - ${CONVERTERLL_EXT_SOURCE_DIR}/conversion/NvBlastExtBinaryBlockConverter.h - ${CONVERTERLL_EXT_SOURCE_DIR}/conversion/NvBlastExtDataConverter.cpp -) - -ADD_LIBRARY(NvBlastExtConverterLL STATIC - ${COMMON_FILES} - ${PUBLIC_FILES} - - ${EXT_CONVERSION_FILES} -) - -SOURCE_GROUP("common" FILES ${COMMON_FILES}) -SOURCE_GROUP("public" FILES ${PUBLIC_FILES}) -SOURCE_GROUP("src\\conversion" FILES ${EXT_CONVERSION_FILES}) - - -# Target specific compile options - -TARGET_INCLUDE_DIRECTORIES(NvBlastExtConverterLL - PRIVATE ${BLASTEXT_PLATFORM_INCLUDES} - - PUBLIC ${PROJECT_SOURCE_DIR}/converter/include - PUBLIC ${CONVERTERLL_EXT_INCLUDE_DIR} - - PRIVATE ${CONVERTERLL_EXT_SOURCE_DIR}/conversion - PRIVATE ${PROJECT_SOURCE_DIR}/common -) - -TARGET_COMPILE_DEFINITIONS(NvBlastExtConverterLL - PRIVATE ${BLASTEXT_COMPILE_DEFS} -) - -# Warning disables for Capn Proto -TARGET_COMPILE_OPTIONS(NvBlastExtConverterLL - PRIVATE ${BLASTEXT_PLATFORM_COMPILE_OPTIONS} -) - -SET_TARGET_PROPERTIES(NvBlastExtConverterLL PROPERTIES - PDB_NAME_DEBUG "NvBlastExtConverterLL${CMAKE_DEBUG_POSTFIX}" - PDB_NAME_CHECKED "NvBlastExtConverterLL${CMAKE_CHECKED_POSTFIX}" - PDB_NAME_PROFILE "NvBlastExtConverterLL${CMAKE_PROFILE_POSTFIX}" - PDB_NAME_RELEASE "NvBlastExtConverterLL${CMAKE_RELEASE_POSTFIX}" -) - -# Do final direct sets after the target has been defined -#TARGET_LINK_LIBRARIES(NvBlastExtConverterLL NvBlast ${PHYSXSDK_LIBRARIES} ${APEXSDK_LIBRARIES} ${PXSHAREDSDK_LIBRARIES}) -TARGET_LINK_LIBRARIES(NvBlastExtConverterLL - PUBLIC NvBlast - PUBLIC ${BLASTEXT_PLATFORM_LINKED_LIBS} -) diff --git a/sdk/compiler/cmake/NvBlastExtPhysX.cmake b/sdk/compiler/cmake/NvBlastExtPhysX.cmake index d2d0f0a..ee8dcc5 100644 --- a/sdk/compiler/cmake/NvBlastExtPhysX.cmake +++ b/sdk/compiler/cmake/NvBlastExtPhysX.cmake @@ -21,6 +21,10 @@ SET(COMMON_FILES ${COMMON_SOURCE_DIR}/NvBlastAssert.cpp ${COMMON_SOURCE_DIR}/NvBlastAssert.h + + ${COMMON_SOURCE_DIR}/NvBlastArray.h + ${COMMON_SOURCE_DIR}/NvBlastHashMap.h + ${COMMON_SOURCE_DIR}/NvBlastHashSet.h ) SET(PUBLIC_FILES @@ -31,14 +35,15 @@ SET(PUBLIC_FILES ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtPxFamily.h ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtPxListener.h ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtPxManager.h - ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtStressSolver.h + ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtPxStressSolver.h + ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtPxTask.h ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtSync.h ) SET(EXT_PHYSICS_FILES - ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtImpulseStressSolver.h ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtImpactDamageManager.cpp - ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtImpulseStressSolver.cpp + ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxStressSolverImpl.h + ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxStressSolverImpl.cpp ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxActorImpl.h ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxActorImpl.cpp ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxAssetImpl.h @@ -47,6 +52,13 @@ SET(EXT_PHYSICS_FILES ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxFamilyImpl.cpp ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxManagerImpl.h ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxManagerImpl.cpp + ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxTaskImpl.h + ${PHYSX_EXT_SOURCE_DIR}/physics/NvBlastExtPxTaskImpl.cpp +) + +SET(EXT_CALLBACKS_FILES + ${PHYSX_EXT_INCLUDE_DIR}/NvBlastExtCustomProfiler.h + ${PHYSX_EXT_INCLUDE_DIR}/NvBlastPxCallbacks.h ) SET(EXT_SYNC_FILES @@ -59,12 +71,14 @@ ADD_LIBRARY(NvBlastExtPhysX ${BLASTEXT_PHYSX_LIBTYPE} ${EXT_PHYSICS_FILES} ${EXT_SYNC_FILES} + ${EXT_CALLBACKS_FILES} ) SOURCE_GROUP("common" FILES ${COMMON_FILES}) SOURCE_GROUP("public" FILES ${PUBLIC_FILES}) SOURCE_GROUP("src\\physics" FILES ${EXT_PHYSICS_FILES}) SOURCE_GROUP("src\\sync" FILES ${EXT_SYNC_FILES}) +SOURCE_GROUP("src\\callbacks" FILES ${EXT_CALLBACKS_FILES}) # Target specific compile options @@ -81,6 +95,8 @@ TARGET_INCLUDE_DIRECTORIES(NvBlastExtPhysX PRIVATE ${PHYSX_EXT_SOURCE_DIR}/physics PRIVATE ${PHYSX_EXT_SOURCE_DIR}/sync + PUBLIC ${PROJECT_SOURCE_DIR}/extensions/profiler/include + PUBLIC ${PHYSXSDK_INCLUDE_DIRS} PRIVATE ${PXSHAREDSDK_INCLUDE_DIRS} ) @@ -103,7 +119,7 @@ SET_TARGET_PROPERTIES(NvBlastExtPhysX PROPERTIES # Do final direct sets after the target has been defined TARGET_LINK_LIBRARIES(NvBlastExtPhysX - PUBLIC NvBlast NvBlastExtShaders NvBlastTk + PUBLIC NvBlastTk NvBlastExtShaders NvBlastExtStress PUBLIC $<$<CONFIG:debug>:${PHYSX3_LIB_DEBUG}> $<$<CONFIG:debug>:${PHYSX3COOKING_LIB_DEBUG}> $<$<CONFIG:debug>:${PHYSX3EXTENSIONS_LIB_DEBUG}> $<$<CONFIG:debug>:${PXFOUNDATION_LIB_DEBUG}> PUBLIC $<$<CONFIG:checked>:${PHYSX3_LIB_CHECKED}> $<$<CONFIG:checked>:${PHYSX3COOKING_LIB_CHECKED}> $<$<CONFIG:checked>:${PHYSX3EXTENSIONS_LIB_CHECKED}> $<$<CONFIG:checked>:${PXFOUNDATION_LIB_CHECKED}> PUBLIC $<$<CONFIG:profile>:${PHYSX3_LIB_PROFILE}> $<$<CONFIG:profile>:${PHYSX3COOKING_LIB_PROFILE}> $<$<CONFIG:profile>:${PHYSX3EXTENSIONS_LIB_PROFILE}> $<$<CONFIG:profile>:${PXFOUNDATION_LIB_PROFILE}> diff --git a/sdk/compiler/cmake/NvBlastExtSerialization.cmake b/sdk/compiler/cmake/NvBlastExtSerialization.cmake index 440ad43..e6cd597 100644 --- a/sdk/compiler/cmake/NvBlastExtSerialization.cmake +++ b/sdk/compiler/cmake/NvBlastExtSerialization.cmake @@ -6,11 +6,6 @@ SET(COMMON_SOURCE_DIR ${PROJECT_SOURCE_DIR}/common) SET(SERIAL_EXT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/extensions/serialization/source) SET(SERIAL_EXT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/extensions/serialization/include) -SET(TK_INCLUDE_DIR ${BLAST_ROOT_DIR}/sdk/toolkit/include) -SET(PHYSX_EXT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/extensions/physx/include) -SET(PHYSX_EXT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/extensions/physx/source) -SET(EXT_COMMON_SOURCE_DIR ${PROJECT_SOURCE_DIR}/extensions/common/source) -SET(EXT_COMMON_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/extensions/common/include) SET(DTO_SOURCE_DIR ${SERIAL_EXT_SOURCE_DIR}/DTO) @@ -18,7 +13,6 @@ SET(SOLVER_SOURCE_DIR ${PROJECT_SOURCE_DIR}/lowlevel/source) SET(SERIAL_GENERATED_SOURCE_DIR ${SERIAL_EXT_SOURCE_DIR}/generated) -FIND_PACKAGE(PhysXSDK $ENV{PM_PhysX_VERSION} REQUIRED) FIND_PACKAGE(PxSharedSDK $ENV{PM_PxShared_VERSION} REQUIRED) FIND_PACKAGE(CapnProtoSDK $ENV{PM_CapnProto_VERSION} REQUIRED) @@ -31,7 +25,7 @@ INCLUDE(CapnProtoGenerate) SET(CAPNPC_OUTPUT_DIR ${SERIAL_GENERATED_SOURCE_DIR}) SET(CAPNPC_SRC_PREFIX ${SERIAL_EXT_SOURCE_DIR}) -CAPNP_GENERATE_CPP(CAPNP_SRCS CAPNP_HDRS ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLL.capn ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerialization.capn) +CAPNP_GENERATE_CPP(CAPNP_SRCS CAPNP_HDRS ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtLlSerialization.capn) SET(COMMON_FILES ${BLASTEXTSERIALIZATION_PLATFORM_COMMON_FILES} @@ -46,7 +40,6 @@ SET(COMMON_FILES ${COMMON_SOURCE_DIR}/NvBlastFixedBoolArray.h ${COMMON_SOURCE_DIR}/NvBlastFixedPriorityQueue.h ${COMMON_SOURCE_DIR}/NvBlastGeometry.h -# ${COMMON_SOURCE_DIR}/NvBlastIndexFns.cpp ${COMMON_SOURCE_DIR}/NvBlastIndexFns.h ${COMMON_SOURCE_DIR}/NvBlastIteratorBase.h ${COMMON_SOURCE_DIR}/NvBlastMath.h @@ -59,66 +52,37 @@ SET(COMMON_FILES SET(EXT_SERIALIZATION_FILES - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLL.capn - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerialization.capn + ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtLlSerialization.capn - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerialization.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationImpl.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLLImpl.h + ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerialization.cpp + ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtLlSerialization.cpp - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLLInterface.cpp - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationInterface.cpp + ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationCAPN.h + + ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationInternal.h + ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtLlSerializerCAPN.h ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtOutputStream.h ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtOutputStream.cpp ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtInputStream.h ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtInputStream.cpp - - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxInputStream.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxInputStream.cpp - - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxOutputStream.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxOutputStream.cpp ) SET(DTO_SOURCE_FILES ${DTO_SOURCE_DIR}/DTOMacros.h ${DTO_SOURCE_DIR}/AssetDTO.h ${DTO_SOURCE_DIR}/AssetDTO.cpp - ${DTO_SOURCE_DIR}/TkAssetDTO.h - ${DTO_SOURCE_DIR}/TkAssetDTO.cpp - ${DTO_SOURCE_DIR}/ExtPxAssetDTO.h - ${DTO_SOURCE_DIR}/ExtPxAssetDTO.cpp - ${DTO_SOURCE_DIR}/PxVec3DTO.h - ${DTO_SOURCE_DIR}/PxVec3DTO.cpp ${DTO_SOURCE_DIR}/NvBlastChunkDTO.h ${DTO_SOURCE_DIR}/NvBlastChunkDTO.cpp ${DTO_SOURCE_DIR}/NvBlastBondDTO.h ${DTO_SOURCE_DIR}/NvBlastBondDTO.cpp ${DTO_SOURCE_DIR}/NvBlastIDDTO.h ${DTO_SOURCE_DIR}/NvBlastIDDTO.cpp - ${DTO_SOURCE_DIR}/TkAssetJointDescDTO.h - ${DTO_SOURCE_DIR}/TkAssetJointDescDTO.cpp - ${DTO_SOURCE_DIR}/ExtPxChunkDTO.h - ${DTO_SOURCE_DIR}/ExtPxChunkDTO.cpp - ${DTO_SOURCE_DIR}/ExtPxSubchunkDTO.h - ${DTO_SOURCE_DIR}/ExtPxSubchunkDTO.cpp - ${DTO_SOURCE_DIR}/PxQuatDTO.h - ${DTO_SOURCE_DIR}/PxQuatDTO.cpp - ${DTO_SOURCE_DIR}/PxTransformDTO.h - ${DTO_SOURCE_DIR}/PxTransformDTO.cpp - ${DTO_SOURCE_DIR}/PxMeshScaleDTO.h - ${DTO_SOURCE_DIR}/PxMeshScaleDTO.cpp - ${DTO_SOURCE_DIR}/PxConvexMeshGeometryDTO.h - ${DTO_SOURCE_DIR}/PxConvexMeshGeometryDTO.cpp - - - ) SET(EXT_SERIALIZATION_INCLUDES - ${SERIAL_EXT_INCLUDE_DIR}/NvBlastExtSerializationLLInterface.h - ${SERIAL_EXT_INCLUDE_DIR}/NvBlastExtSerializationInterface.h + ${SERIAL_EXT_INCLUDE_DIR}/NvBlastExtSerialization.h + ${SERIAL_EXT_INCLUDE_DIR}/NvBlastExtLlSerialization.h ) ADD_LIBRARY(NvBlastExtSerialization ${BLASTEXTSERIALIZATION_LIB_TYPE} @@ -133,6 +97,8 @@ ADD_LIBRARY(NvBlastExtSerialization ${BLASTEXTSERIALIZATION_LIB_TYPE} ${CAPNP_HDRS} ${MD5_FILES} + + ${CAPNPROTOSDK_SOURCE_FILES} ) SOURCE_GROUP("common" FILES ${COMMON_FILES}) @@ -141,7 +107,7 @@ SOURCE_GROUP("include" FILES ${EXT_SERIALIZATION_INCLUDES}) SOURCE_GROUP("src\\serialization" FILES ${EXT_SERIALIZATION_FILES}) SOURCE_GROUP("src\\serialization\\DTO" FILES ${DTO_SOURCE_FILES}) SOURCE_GROUP("src\\serialization\\generated" FILES ${CAPNP_SRCS} ${CAPNP_HDRS}) - +SOURCE_GROUP("src\\serialization\\CapnProtoSDK" FILES ${CAPNPROTOSDK_SOURCE_FILES}) # Target specific compile options @@ -158,22 +124,15 @@ TARGET_INCLUDE_DIRECTORIES(NvBlastExtSerialization PUBLIC ${SERIAL_EXT_SOURCE_DIR} PUBLIC ${DTO_SOURCE_DIR} - PRIVATE ${PHYSX_EXT_INCLUDE_DIR} - PRIVATE ${PHYSX_EXT_SOURCE_DIR} - - PRIVATE ${EXT_COMMON_SOURCE_DIR} - PRIVATE ${EXT_COMMON_INCLUDE_DIR} - PUBLIC ${CAPNPROTOSDK_INCLUDE_DIRS} PRIVATE ${COMMON_SOURCE_DIR} - - PUBLIC ${PHYSXSDK_INCLUDE_DIRS} + PRIVATE ${PXSHAREDSDK_INCLUDE_DIRS} ) TARGET_COMPILE_DEFINITIONS(NvBlastExtSerialization - PUBLIC CAPNP_LITE=1 + PUBLIC CAPNP_LITE=1;BLAST_LL_ALLOC=1 PRIVATE ${BLASTEXTSERIALIZATION_COMPILE_DEFS} ) @@ -191,10 +150,5 @@ SET_TARGET_PROPERTIES(NvBlastExtSerialization PROPERTIES # Do final direct sets after the target has been defined TARGET_LINK_LIBRARIES(NvBlastExtSerialization - PRIVATE NvBlast NvBlastExtPhysX NvBlastTk ${CAPNPROTOSDK_LIBRARIES} - PUBLIC $<$<CONFIG:debug>:${PHYSX3_LIB_DEBUG}> $<$<CONFIG:debug>:${PHYSX3COOKING_LIB_DEBUG}> - PUBLIC $<$<CONFIG:checked>:${PHYSX3_LIB_CHECKED}> $<$<CONFIG:checked>:${PHYSX3COOKING_LIB_CHECKED}> - PUBLIC $<$<CONFIG:profile>:${PHYSX3_LIB_PROFILE}> $<$<CONFIG:profile>:${PHYSX3COOKING_LIB_PROFILE}> - PUBLIC $<$<CONFIG:release>:${PHYSX3_LIB}> $<$<CONFIG:release>:${PHYSX3COOKING_LIB}> - + PRIVATE NvBlast NvBlastGlobals ${CAPNPROTOSDK_LIBRARIES} ) diff --git a/sdk/compiler/cmake/NvBlastExtSerializationLL.cmake b/sdk/compiler/cmake/NvBlastExtSerializationLL.cmake deleted file mode 100644 index da1a9d2..0000000 --- a/sdk/compiler/cmake/NvBlastExtSerializationLL.cmake +++ /dev/null @@ -1,151 +0,0 @@ -# -# Build NvBlastExtSerializationLL Common -# - -SET(COMMON_SOURCE_DIR ${PROJECT_SOURCE_DIR}/common) - -SET(SERIAL_EXT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/extensions/serialization/source) -SET(SERIAL_EXT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/extensions/serialization/include) - -SET(DTO_SOURCE_DIR ${SERIAL_EXT_SOURCE_DIR}/DTO) - -SET(SOLVER_SOURCE_DIR ${PROJECT_SOURCE_DIR}/lowlevel/source) - -SET(SERIAL_GENERATED_SOURCE_DIR ${SERIAL_EXT_SOURCE_DIR}/generated) - -FIND_PACKAGE(CapnProtoSDK $ENV{PM_CapnProto_VERSION} REQUIRED) - -# Include here after the directories are defined so that the platform specific file can use the variables. -include(${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/NvBlastExtSerializationLL.cmake) - -# Compile the generated files for serialization - -INCLUDE(CapnProtoGenerate) - -SET(CAPNPC_OUTPUT_DIR ${SERIAL_GENERATED_SOURCE_DIR}) -SET(CAPNPC_SRC_PREFIX ${SERIAL_EXT_SOURCE_DIR}) -CAPNP_GENERATE_CPP(CAPNP_SRCS CAPNP_HDRS ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLL.capn) - -SET(COMMON_FILES - ${BLASTEXTSERIALIZATION_PLATFORM_COMMON_FILES} - - ${COMMON_SOURCE_DIR}/NvBlastAssert.cpp - ${COMMON_SOURCE_DIR}/NvBlastAssert.h - ${COMMON_SOURCE_DIR}/NvBlastAtomic.cpp - ${COMMON_SOURCE_DIR}/NvBlastAtomic.h - ${COMMON_SOURCE_DIR}/NvBlastDLink.h - ${COMMON_SOURCE_DIR}/NvBlastFixedArray.h - ${COMMON_SOURCE_DIR}/NvBlastFixedBitmap.h - ${COMMON_SOURCE_DIR}/NvBlastFixedBoolArray.h - ${COMMON_SOURCE_DIR}/NvBlastFixedPriorityQueue.h - ${COMMON_SOURCE_DIR}/NvBlastGeometry.h - ${COMMON_SOURCE_DIR}/NvBlastIndexFns.h - ${COMMON_SOURCE_DIR}/NvBlastIteratorBase.h - ${COMMON_SOURCE_DIR}/NvBlastMath.h - ${COMMON_SOURCE_DIR}/NvBlastMemory.h - ${COMMON_SOURCE_DIR}/NvBlastPreprocessorInternal.h - ${COMMON_SOURCE_DIR}/NvBlastTime.cpp - ${COMMON_SOURCE_DIR}/NvBlastTime.h - ${COMMON_SOURCE_DIR}/NvBlastTimers.cpp -) - - -SET(EXT_SERIALIZATION_FILES - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLL.capn - - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerialization.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLLImpl.h - - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtSerializationLLInterface.cpp - - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtOutputStream.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtOutputStream.cpp - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtInputStream.h - ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtInputStream.cpp - -# ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxInputStream.h -# ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxInputStream.cpp - -# ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxOutputStream.h -# ${SERIAL_EXT_SOURCE_DIR}/NvBlastExtKJPxOutputStream.cpp -) - -SET(DTO_SOURCE_FILES - ${DTO_SOURCE_DIR}/DTOMacros.h - ${DTO_SOURCE_DIR}/AssetDTO.h - ${DTO_SOURCE_DIR}/AssetDTO.cpp - ${DTO_SOURCE_DIR}/NvBlastChunkDTO.h - ${DTO_SOURCE_DIR}/NvBlastChunkDTO.cpp - ${DTO_SOURCE_DIR}/NvBlastBondDTO.h - ${DTO_SOURCE_DIR}/NvBlastBondDTO.cpp - ${DTO_SOURCE_DIR}/NvBlastIDDTO.h - ${DTO_SOURCE_DIR}/NvBlastIDDTO.cpp -) - -SET(EXT_SERIALIZATION_INCLUDES - ${SERIAL_EXT_INCLUDE_DIR}/NvBlastExtSerializationLLInterface.h -) - -ADD_LIBRARY(NvBlastExtSerializationLL ${BLASTEXTSERIALIZATION_LIB_TYPE} - ${COMMON_FILES} - - ${DTO_SOURCE_FILES} - - ${EXT_SERIALIZATION_INCLUDES} - ${EXT_SERIALIZATION_FILES} - - ${CAPNP_SRCS} - ${CAPNP_HDRS} - - ${MD5_FILES} -) - -SOURCE_GROUP("common" FILES ${COMMON_FILES}) - -SOURCE_GROUP("include" FILES ${EXT_SERIALIZATION_INCLUDES}) -SOURCE_GROUP("src\\serialization" FILES ${EXT_SERIALIZATION_FILES}) -SOURCE_GROUP("src\\serialization\\DTO" FILES ${DTO_SOURCE_FILES}) -SOURCE_GROUP("src\\serialization\\generated" FILES ${CAPNP_SRCS} ${CAPNP_HDRS}) - - -# Target specific compile options - -TARGET_INCLUDE_DIRECTORIES(NvBlastExtSerializationLL - PRIVATE ${BLASTEXTSERIALIZATION_PLATFORM_INCLUDES} - - PRIVATE ${PROJECT_SOURCE_DIR}/common - PRIVATE ${PROJECT_SOURCE_DIR}/lowlevel/include - PRIVATE ${PROJECT_SOURCE_DIR}/lowlevel/source - - PRIVATE ${TK_INCLUDE_DIR} - - PUBLIC ${SERIAL_EXT_INCLUDE_DIR} - PUBLIC ${SERIAL_EXT_SOURCE_DIR} - PUBLIC ${DTO_SOURCE_DIR} - - PUBLIC ${CAPNPROTOSDK_INCLUDE_DIRS} - - PRIVATE ${COMMON_SOURCE_DIR} -) - -TARGET_COMPILE_DEFINITIONS(NvBlastExtSerializationLL - PUBLIC CAPNP_LITE=1;BLAST_LL_ALLOC=1 - PRIVATE ${BLASTEXTSERIALIZATION_COMPILE_DEFS} -) - -# Warning disables for Capn Proto -TARGET_COMPILE_OPTIONS(NvBlastExtSerializationLL - PRIVATE ${BLASTEXTSERIALIZATION_COMPILE_OPTIONS} -) - -SET_TARGET_PROPERTIES(NvBlastExtSerializationLL PROPERTIES - PDB_NAME_DEBUG "NvBlastExtSerializationLL${CMAKE_DEBUG_POSTFIX}" - PDB_NAME_CHECKED "NvBlastExtSerializationLL${CMAKE_CHECKED_POSTFIX}" - PDB_NAME_PROFILE "NvBlastExtSerializationLL${CMAKE_PROFILE_POSTFIX}" - PDB_NAME_RELEASE "NvBlastExtSerializationLL${CMAKE_RELEASE_POSTFIX}" -) - -# Do final direct sets after the target has been defined -TARGET_LINK_LIBRARIES(NvBlastExtSerializationLL - PRIVATE NvBlast ${CAPNPROTOSDK_LIBRARIES} -) diff --git a/sdk/compiler/cmake/NvBlastExtShaders.cmake b/sdk/compiler/cmake/NvBlastExtShaders.cmake index df4a3ad..f918326 100644 --- a/sdk/compiler/cmake/NvBlastExtShaders.cmake +++ b/sdk/compiler/cmake/NvBlastExtShaders.cmake @@ -22,8 +22,7 @@ SET(PUBLIC_FILES ) SET(EXT_SOURCE_FILES - ${SHADERS_EXT_SOURCE_DIR}/NvBlastExtRadialShaders.cpp - ${SHADERS_EXT_SOURCE_DIR}/NvBlastExtShearShaders.cpp + ${SHADERS_EXT_SOURCE_DIR}/NvBlastExtDamageShaders.cpp ) ADD_LIBRARY(NvBlastExtShaders ${BLAST_EXT_SHARED_LIB_TYPE} @@ -69,6 +68,6 @@ SET_TARGET_PROPERTIES(NvBlastExtShaders PROPERTIES # Do final direct sets after the target has been defined #TARGET_LINK_LIBRARIES(NvBlastExtShaders NvBlast ${PHYSXSDK_LIBRARIES} ${APEXSDK_LIBRARIES} ${PXSHAREDSDK_LIBRARIES}) TARGET_LINK_LIBRARIES(NvBlastExtShaders - PUBLIC NvBlast + PUBLIC NvBlast PUBLIC ${BLASTEXT_PLATFORM_LINKED_LIBS} ) diff --git a/sdk/compiler/cmake/NvBlastTk.cmake b/sdk/compiler/cmake/NvBlastTk.cmake index be9e04a..294e303 100644 --- a/sdk/compiler/cmake/NvBlastTk.cmake +++ b/sdk/compiler/cmake/NvBlastTk.cmake @@ -3,7 +3,6 @@ # SET(TOOLKIT_DIR ${PROJECT_SOURCE_DIR}/toolkit) -SET(PROFILER_SOURCE_DIR ${PROJECT_SOURCE_DIR}/profiler) SET(COMMON_SOURCE_DIR ${PROJECT_SOURCE_DIR}/common) FIND_PACKAGE(PxSharedSDK $ENV{PM_PxShared_VERSION} REQUIRED) @@ -33,11 +32,9 @@ SET(COMMON_FILES ${COMMON_SOURCE_DIR}/NvBlastTime.cpp ${COMMON_SOURCE_DIR}/NvBlastTime.h ${COMMON_SOURCE_DIR}/NvBlastTimers.cpp -) - -SET(PROFILER_FILES - ${PROFILER_SOURCE_DIR}/NvBlastProfiler.cpp - ${PROFILER_SOURCE_DIR}/NvBlastProfilerInternal.h + ${COMMON_SOURCE_DIR}/NvBlastArray.h + ${COMMON_SOURCE_DIR}/NvBlastHashMap.h + ${COMMON_SOURCE_DIR}/NvBlastHashSet.h ) SET(PUBLIC_FILES @@ -51,16 +48,12 @@ SET(PUBLIC_FILES ${TOOLKIT_DIR}/include/NvBlastTkIdentifiable.h ${TOOLKIT_DIR}/include/NvBlastTkJoint.h ${TOOLKIT_DIR}/include/NvBlastTkObject.h - ${TOOLKIT_DIR}/include/NvBlastTkSerializable.h ${TOOLKIT_DIR}/include/NvBlastTkType.h ) SET(TOOLKIT_FILES ${TOOLKIT_DIR}/source/NvBlastTkActorImpl.cpp ${TOOLKIT_DIR}/source/NvBlastTkActorImpl.h - ${TOOLKIT_DIR}/source/NvBlastTkAllocator.cpp - ${TOOLKIT_DIR}/source/NvBlastTkAllocator.h - ${TOOLKIT_DIR}/source/NvBlastTkArray.h ${TOOLKIT_DIR}/source/NvBlastTkAssetImpl.cpp ${TOOLKIT_DIR}/source/NvBlastTkAssetImpl.h ${TOOLKIT_DIR}/source/NvBlastTkCommon.h @@ -72,8 +65,6 @@ SET(TOOLKIT_FILES ${TOOLKIT_DIR}/source/NvBlastTkGroupImpl.cpp ${TOOLKIT_DIR}/source/NvBlastTkGroupImpl.h ${TOOLKIT_DIR}/source/NvBlastTkGUID.h - ${TOOLKIT_DIR}/source/NvBlastTkHashMap.h - ${TOOLKIT_DIR}/source/NvBlastTkHashSet.h ${TOOLKIT_DIR}/source/NvBlastTkJointImpl.cpp ${TOOLKIT_DIR}/source/NvBlastTkJointImpl.h ${TOOLKIT_DIR}/source/NvBlastTkTaskImpl.cpp @@ -83,13 +74,11 @@ SET(TOOLKIT_FILES ADD_LIBRARY(NvBlastTk ${BLASTTK_LIBTYPE} ${COMMON_FILES} - ${PROFILER_FILES} ${PUBLIC_FILES} ${TOOLKIT_FILES} ) SOURCE_GROUP("common" FILES ${COMMON_FILES}) -SOURCE_GROUP("profiler" FILES ${PROFILER_FILES}) SOURCE_GROUP("public" FILES ${PUBLIC_FILES}) SOURCE_GROUP("toolkit" FILES ${TOOLKIT_FILES}) @@ -99,7 +88,6 @@ TARGET_INCLUDE_DIRECTORIES(NvBlastTk PRIVATE ${BLASTTK_PLATFORM_INCLUDES} PRIVATE ${PROJECT_SOURCE_DIR}/common - PRIVATE ${PROJECT_SOURCE_DIR}/profiler PUBLIC ${PROJECT_SOURCE_DIR}/lowlevel/include PUBLIC ${PROJECT_SOURCE_DIR}/toolkit/include @@ -110,6 +98,10 @@ TARGET_COMPILE_DEFINITIONS(NvBlastTk PRIVATE ${BLASTTK_COMPILE_DEFS} ) +TARGET_COMPILE_OPTIONS(NvBlastTk + PRIVATE ${BLASTTK_PLATFORM_COMPILE_OPTIONS} +) + SET_TARGET_PROPERTIES(NvBlastTk PROPERTIES PDB_NAME_DEBUG "NvBlastTk${CMAKE_DEBUG_POSTFIX}" PDB_NAME_CHECKED "NvBlastTk${CMAKE_CHECKED_POSTFIX}" @@ -119,7 +111,7 @@ SET_TARGET_PROPERTIES(NvBlastTk PROPERTIES # Do final direct sets after the target has been defined TARGET_LINK_LIBRARIES(NvBlastTk - PRIVATE NvBlast + PUBLIC NvBlast NvBlastGlobals PUBLIC ${BLASTTK_PLATFORM_LINKED_LIBS} ) diff --git a/sdk/compiler/cmake/linux/CMakeLists.txt b/sdk/compiler/cmake/linux/CMakeLists.txt index 440351e..d0cf60a 100644 --- a/sdk/compiler/cmake/linux/CMakeLists.txt +++ b/sdk/compiler/cmake/linux/CMakeLists.txt @@ -1,6 +1,6 @@ #Platform specific compile flags and project includes -SET(CMAKE_CXX_FLAGS "-Wextra -Werror -pedantic -fdiagnostics-show-option -fno-rtti -fno-exceptions -m64 -msse2 -mfpmath=sse -fpic -ffast-math -fno-exceptions -fno-rtti -Wno-invalid-offsetof -Wno-unknown-pragmas -std=c++0x") +SET(CMAKE_CXX_FLAGS "-Wextra -Werror -fdiagnostics-show-option -fno-rtti -fno-exceptions -m64 -msse2 -mfpmath=sse -fPIC -ffast-math -fno-exceptions -fno-rtti -Wno-invalid-offsetof -Wno-unknown-pragmas -std=c++0x") SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -gdwarf-2") SET(CMAKE_CXX_FLAGS_CHECKED "-O3 -g3 -gdwarf-2 -fno-strict-aliasing") @@ -16,12 +16,31 @@ SET(BLAST_SLN_RELEASE_COMPILE_DEFS NDEBUG;) # Include all of the projects INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlast.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastGlobals.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastTk.cmake) -INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtConverterLL.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtShaders.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtStress.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtPhysX.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtAuthoring.cmake) -#INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtImport.cmake) -#INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerialization.cmake) -#INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerializationLL.cmake) +IF(${UE4_LINUX_CROSSCOMPILE}) + #This uses the Windows CapnProto exe so it works + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtAssetUtils.cmake) + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerialization.cmake) + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtTkSerialization.cmake) + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtPxSerialization.cmake) + + #The UE4 Linux cross tools don't include libc++, it's in the UE4 source, however UE4 uses libc++ + #and not libstdc++ so link this statically to avoid a dependency + SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") + SET(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++") +ELSE() + #TODO Update Linux CapnProto build to generate correct version code + + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtAssetUtils.cmake) + + #INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtImport.cmake) + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerialization.cmake) + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtTkSerialization.cmake) + INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtPxSerialization.cmake) +ENDIF() diff --git a/sdk/compiler/cmake/linux/NvBlast.cmake b/sdk/compiler/cmake/linux/NvBlast.cmake index 63ebeea..c1b0363 100644 --- a/sdk/compiler/cmake/linux/NvBlast.cmake +++ b/sdk/compiler/cmake/linux/NvBlast.cmake @@ -18,4 +18,6 @@ SET(BLAST_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLAST_LIB_TYPE STATIC) +SET(BLAST_LIB_TYPE SHARED) + +SET(BLAST_PLATFORM_COMPILE_OPTIONS "-pedantic") diff --git a/sdk/compiler/cmake/linux/NvBlastExtAuthoring.cmake b/sdk/compiler/cmake/linux/NvBlastExtAuthoring.cmake index c99653b..3d7bb78 100644 --- a/sdk/compiler/cmake/linux/NvBlastExtAuthoring.cmake +++ b/sdk/compiler/cmake/linux/NvBlastExtAuthoring.cmake @@ -18,6 +18,12 @@ SET(BLASTEXT_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLAST_EXT_SHARED_LIB_TYPE STATIC) +SET(BLAST_EXT_SHARED_LIB_TYPE SHARED) -SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-maybe-uninitialized") +#Exceptions are needed by boost +#This option doesn't work on Clang +IF (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-maybe-uninitialized" "-fexceptions" "-Wno-unused-parameter") +ELSE () + SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-return-type-c-linkage" "-pedantic" "-fexceptions" "-Wno-unused-parameter") +ENDIF()
\ No newline at end of file diff --git a/sdk/compiler/cmake/linux/NvBlastExtConverterLL.cmake b/sdk/compiler/cmake/linux/NvBlastExtConverterLL.cmake deleted file mode 100644 index d37a1dc..0000000 --- a/sdk/compiler/cmake/linux/NvBlastExtConverterLL.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# -# Build NvBlast Linux -# - -SET(BLASTEXT_PLATFORM_COMMON_FILES -) - -SET(BLASTEXT_PLATFORM_INCLUDES -) - -SET(BLASTEXT_COMPILE_DEFS - # Common to all configurations - ${BLAST_SLN_COMPILE_DEFS}; - - $<$<CONFIG:debug>:${BLAST_SLN_DEBUG_COMPILE_DEFS}> - $<$<CONFIG:checked>:${BLAST_SLN_CHECKED_COMPILE_DEFS}> - $<$<CONFIG:profile>:${BLAST_SLN_PROFILE_COMPILE_DEFS}> - $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> -) - -SET(BLAST_EXT_SHARED_LIB_TYPE STATIC) - -SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas") diff --git a/sdk/compiler/cmake/linux/NvBlastExtImport.cmake b/sdk/compiler/cmake/linux/NvBlastExtImport.cmake index d37a1dc..543887d 100644 --- a/sdk/compiler/cmake/linux/NvBlastExtImport.cmake +++ b/sdk/compiler/cmake/linux/NvBlastExtImport.cmake @@ -18,6 +18,6 @@ SET(BLASTEXT_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLAST_EXT_SHARED_LIB_TYPE STATIC) +SET(BLAST_EXT_SHARED_LIB_TYPE SHARED) SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas") diff --git a/sdk/compiler/cmake/linux/NvBlastExtPhysX.cmake b/sdk/compiler/cmake/linux/NvBlastExtPhysX.cmake index 22fd8ad..9edb58c 100644 --- a/sdk/compiler/cmake/linux/NvBlastExtPhysX.cmake +++ b/sdk/compiler/cmake/linux/NvBlastExtPhysX.cmake @@ -18,6 +18,11 @@ SET(BLASTEXT_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLASTEXT_PHYSX_LIBTYPE STATIC) +SET(BLASTEXT_PHYSX_LIBTYPE SHARED) -SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas" "-Wno-maybe-uninitialized") +#-Wno-maybe-uninitialized doesn't work on Clang +IF (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas" "-Wno-maybe-uninitialized") +ELSE() + SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas" "-Wno-return-type-c-linkage") +ENDIF() diff --git a/sdk/compiler/cmake/linux/NvBlastExtSerialization.cmake b/sdk/compiler/cmake/linux/NvBlastExtSerialization.cmake index a8bc1cf..b6d4d84 100644 --- a/sdk/compiler/cmake/linux/NvBlastExtSerialization.cmake +++ b/sdk/compiler/cmake/linux/NvBlastExtSerialization.cmake @@ -18,4 +18,10 @@ SET(BLASTEXTSERIALIZATION_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "") +SET(BLASTEXTSERIALIZATION_LIB_TYPE SHARED) + +IF (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "-Wno-sign-compare") +ELSE() + SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "-Wno-sign-compare" "-Wno-unused-parameter" "-Wno-return-type-c-linkage") +ENDIF() diff --git a/sdk/compiler/cmake/linux/NvBlastExtSerializationLL.cmake b/sdk/compiler/cmake/linux/NvBlastExtSerializationLL.cmake deleted file mode 100644 index a8bc1cf..0000000 --- a/sdk/compiler/cmake/linux/NvBlastExtSerializationLL.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# -# Build NvBlastExtSerialization Linux -# - -SET(BLASTEXTSERIALIZATION_PLATFORM_COMMON_FILES -) - -SET(BLASTEXTSERIALIZATION_PLATFORM_INCLUDES -) - -SET(BLASTEXTSERIALIZATION_COMPILE_DEFS - # Common to all configurations - ${BLAST_SLN_COMPILE_DEFS}; - - $<$<CONFIG:debug>:${BLAST_SLN_DEBUG_COMPILE_DEFS}> - $<$<CONFIG:checked>:${BLAST_SLN_CHECKED_COMPILE_DEFS}> - $<$<CONFIG:profile>:${BLAST_SLN_PROFILE_COMPILE_DEFS}> - $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> -) - -SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "") diff --git a/sdk/compiler/cmake/linux/NvBlastExtShaders.cmake b/sdk/compiler/cmake/linux/NvBlastExtShaders.cmake index d37a1dc..a5c8c67 100644 --- a/sdk/compiler/cmake/linux/NvBlastExtShaders.cmake +++ b/sdk/compiler/cmake/linux/NvBlastExtShaders.cmake @@ -18,6 +18,6 @@ SET(BLASTEXT_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLAST_EXT_SHARED_LIB_TYPE STATIC) +SET(BLAST_EXT_SHARED_LIB_TYPE SHARED) -SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas") +SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "-Wno-unknown-pragmas" "-pedantic") diff --git a/sdk/compiler/cmake/linux/NvBlastTk.cmake b/sdk/compiler/cmake/linux/NvBlastTk.cmake index 4f70825..5ea3746 100644 --- a/sdk/compiler/cmake/linux/NvBlastTk.cmake +++ b/sdk/compiler/cmake/linux/NvBlastTk.cmake @@ -18,5 +18,11 @@ SET(BLASTTK_COMPILE_DEFS $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> ) -SET(BLASTTK_LIBTYPE "STATIC") +SET(BLASTTK_LIBTYPE SHARED) + +IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + SET(BLASTTK_PLATFORM_COMPILE_OPTIONS "-Wno-return-type-c-linkage" "-pedantic") +ELSE () + SET(BLASTTK_PLATFORM_COMPILE_OPTIONS "-pedantic") +ENDIF() diff --git a/sdk/compiler/cmake/modules/CapnProtoGenerate.cmake b/sdk/compiler/cmake/modules/CapnProtoGenerate.cmake index 3579784..5d57cd0 100644 --- a/sdk/compiler/cmake/modules/CapnProtoGenerate.cmake +++ b/sdk/compiler/cmake/modules/CapnProtoGenerate.cmake @@ -46,10 +46,9 @@ function(CAPNP_GENERATE_CPP SOURCES HEADERS) endif() if(DEFINED CAPNPC_OUTPUT_DIR) - # Prepend a ':' to get the format for the '-o' flag right - set(output_dir ":${CAPNPC_OUTPUT_DIR}") + set(output_dir "${CAPNPC_OUTPUT_DIR}") else() - set(output_dir ":.") + set(output_dir ".") endif() if(NOT DEFINED CAPNPC_SRC_PREFIX) @@ -79,17 +78,18 @@ function(CAPNP_GENERATE_CPP SOURCES HEADERS) set(output_base "${CAPNPC_OUTPUT_DIR}${output_path}") endif() - MESSAGE("Output base: " ${output_base}) - MESSAGE("Output path: " ${output_path}) - MESSAGE("Output dir: " ${output_dir}) - MESSAGE("Src prefix: " ${CAPNPC_SRC_PREFIX}) - + MESSAGE("Output base: " ${output_base}) + MESSAGE("Output path: " ${output_path}) + MESSAGE("Output dir: " ${output_dir}) + MESSAGE("Src prefix: " ${CAPNPC_SRC_PREFIX}) + add_custom_command( OUTPUT "${output_base}.c++" "${output_base}.h" + COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir} COMMAND "${CAPNP_EXECUTABLE}" ARGS compile - -o ${CAPNPC_CXX_EXECUTABLE}${output_dir} - --verbose + -o ${CAPNPC_CXX_EXECUTABLE}:${output_dir} + --verbose --src-prefix ${CAPNPC_SRC_PREFIX} ${include_path} ${CAPNPC_FLAGS} diff --git a/sdk/compiler/cmake/modules/FindCapnProtoSDK.cmake b/sdk/compiler/cmake/modules/FindCapnProtoSDK.cmake index dcf5190..9e2cd60 100644 --- a/sdk/compiler/cmake/modules/FindCapnProtoSDK.cmake +++ b/sdk/compiler/cmake/modules/FindCapnProtoSDK.cmake @@ -1,5 +1,6 @@ # - Try to find CapnProto SDK # - Sets CAPNPROTOSDK_LIBRARIES - list of the libraries found +# - Sets CAPNPROTOSDK_SOURCE_FILES # - Sets CAPNPROTOSDK_INCLUDE_DIRS include(FindPackageHandleStandardArgs) @@ -43,7 +44,11 @@ elseif(TARGET_BUILD_PLATFORM STREQUAL "XboxOne") SET(CMAKE_FIND_LIBRARY_PREFIXES "lib") elseif(TARGET_BUILD_PLATFORM STREQUAL "linux") SET(LIB_PATH ${CAPNPROTOSDK_PATH}/bin/ubuntu64) - SET(EXE_PATH ${CAPNPROTOSDK_PATH}/tools/ubuntu64) + if (UE4_LINUX_CROSSCOMPILE) + SET(EXE_PATH ${CAPNPROTOSDK_PATH}/tools/win32) + else() + SET(EXE_PATH ${CAPNPROTOSDK_PATH}/tools/ubuntu64) + endif() SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") SET(CMAKE_FIND_LIBRARY_PREFIXES "lib") endif() @@ -85,11 +90,11 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(CAPNPROTOSDK CAPNP_EXECUTABLE CAPNPC_CXX_EXECUTABLE - CAPNPROTO_LIB - KJ_LIB + #CAPNPROTO_LIB + #KJ_LIB - CAPNPROTO_LIB_DEBUG - KJ_LIB_DEBUG + #CAPNPROTO_LIB_DEBUG + #KJ_LIB_DEBUG ) if (CAPNPROTOSDK_FOUND) @@ -103,9 +108,30 @@ if (CAPNPROTOSDK_FOUND) ) SET(CAPNPROTOSDK_LIBRARIES "" CACHE STRING "") + SET(CAPNPROTOSDK_SOURCE_FILES "") - LIST(APPEND CAPNPROTOSDK_LIBRARIES - optimized ${CAPNPROTO_LIB} debug ${CAPNPROTO_LIB_DEBUG} - optimized ${KJ_LIB} debug ${KJ_LIB_DEBUG} - ) + IF ((TARGET_BUILD_PLATFORM STREQUAL "PLATFROM_USING_PREBUILT_LIBS")) + LIST(APPEND CAPNPROTOSDK_LIBRARIES + optimized ${CAPNPROTO_LIB} debug ${CAPNPROTO_LIB_DEBUG} + optimized ${KJ_LIB} debug ${KJ_LIB_DEBUG} + ) + ELSE() + #Include source files for the "lite" version only, there aren't too many it avoids needing many permutations of static libs + LIST(APPEND CAPNPROTOSDK_SOURCE_FILES + ${CAPNPROTOSDK_PATH}/src/capnp/arena.c++ + ${CAPNPROTOSDK_PATH}/src/capnp/blob.c++ + ${CAPNPROTOSDK_PATH}/src/capnp/layout.c++ + ${CAPNPROTOSDK_PATH}/src/capnp/message.c++ + ${CAPNPROTOSDK_PATH}/src/capnp/serialize.c++ + + ${CAPNPROTOSDK_PATH}/src/kj/array.c++ + ${CAPNPROTOSDK_PATH}/src/kj/common.c++ + ${CAPNPROTOSDK_PATH}/src/kj/debug.c++ + ${CAPNPROTOSDK_PATH}/src/kj/exception.c++ + ${CAPNPROTOSDK_PATH}/src/kj/io.c++ + ${CAPNPROTOSDK_PATH}/src/kj/mutex.c++ + ${CAPNPROTOSDK_PATH}/src/kj/string.c++ + ${CAPNPROTOSDK_PATH}/src/kj/units.c++ + ) + ENDIF() endif() diff --git a/sdk/compiler/cmake/modules/FindPhysXSDK.cmake b/sdk/compiler/cmake/modules/FindPhysXSDK.cmake index 830e6c5..4b9176f 100644 --- a/sdk/compiler/cmake/modules/FindPhysXSDK.cmake +++ b/sdk/compiler/cmake/modules/FindPhysXSDK.cmake @@ -16,9 +16,9 @@ find_path(PHYSXSDK_PATH Include/PxActor.h if (TARGET_BUILD_PLATFORM STREQUAL "Windows") # If the project pulling in this dependency needs the static crt, then append that to the path. if (STATIC_WINCRT) - SET(PXSHARED_CRT_SUFFIX "-staticcrt") + SET(PHYSX_CRT_SUFFIX "-staticcrt") else() - SET(PXSHARED_CRT_SUFFIX "") + SET(PHYSX_CRT_SUFFIX "") endif() if (CMAKE_CL_64) diff --git a/sdk/compiler/cmake/windows/CMakeLists.txt b/sdk/compiler/cmake/windows/CMakeLists.txt index ac8b186..4c31d6a 100644 --- a/sdk/compiler/cmake/windows/CMakeLists.txt +++ b/sdk/compiler/cmake/windows/CMakeLists.txt @@ -50,18 +50,17 @@ SET(CMAKE_RELEASE_POSTFIX "${CMAKE_RELEASE_POSTFIX}_${LIBPATH_SUFFIX}") # Include all of the projects INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlast.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastGlobals.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastTk.cmake) -INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtConverterLL.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtShaders.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtStress.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtPhysX.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtAuthoring.cmake) INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtImport.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtAssetUtils.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtExporter.cmake) -#Sadly, CapnProto won't compile on anything less than VS2015. -if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.0.0.0) - SET(SERIALIZATION_INCLUDED 1 PARENT_SCOPE) - INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerialization.cmake) - INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerializationLL.cmake) -else() - SET(SERIALIZATION_INCLUDED 0) -endif() +SET(SERIALIZATION_INCLUDED 1 PARENT_SCOPE) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtSerialization.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtTkSerialization.cmake) +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/NvBlastExtPxSerialization.cmake) diff --git a/sdk/compiler/cmake/windows/NvBlastExtConverterLL.cmake b/sdk/compiler/cmake/windows/NvBlastExtConverterLL.cmake deleted file mode 100644 index 7406d74..0000000 --- a/sdk/compiler/cmake/windows/NvBlastExtConverterLL.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# -# Build NvBlastExt Windows -# - -SET(BLASTEXT_PLATFORM_COMMON_FILES - ${COMMON_SOURCE_DIR}/NvBlastIncludeWindows.h -) - -SET(BLASTEXT_PLATFORM_INCLUDES -) - -SET(BLASTEXT_COMPILE_DEFS - # Common to all configurations - ${BLAST_SLN_COMPILE_DEFS};_CONSOLE; - - $<$<CONFIG:debug>:${BLAST_SLN_DEBUG_COMPILE_DEFS}> - $<$<CONFIG:checked>:${BLAST_SLN_CHECKED_COMPILE_DEFS}> - $<$<CONFIG:profile>:${BLAST_SLN_PROFILE_COMPILE_DEFS}> - $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> -) - -SET(BLAST_EXT_SHARED_LIB_TYPE SHARED) - -SET(BLASTEXT_PLATFORM_COMPILE_OPTIONS "/wd4100;/wd4239;/wd4244;/wd4245;/wd4267;/EHsc") diff --git a/sdk/compiler/cmake/windows/NvBlastExtSerialization.cmake b/sdk/compiler/cmake/windows/NvBlastExtSerialization.cmake index 20910be..8b26799 100644 --- a/sdk/compiler/cmake/windows/NvBlastExtSerialization.cmake +++ b/sdk/compiler/cmake/windows/NvBlastExtSerialization.cmake @@ -22,5 +22,5 @@ SET(BLASTEXTSERIALIZATION_COMPILE_DEFS SET(BLASTEXTSERIALIZATION_LIB_TYPE SHARED) -SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "/wd4100;/wd4239;/wd4244;/wd4245;/wd4267;/EHsc") +SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "/wd4100;/wd4239;/wd4244;/wd4245;/wd4267;/wd4702;/wd4800;/wd4541;/wd4189;/wd4714;/wd4018;/wd4456;/wd4091;/wd4127;/EHsc") diff --git a/sdk/compiler/cmake/windows/NvBlastExtSerializationLL.cmake b/sdk/compiler/cmake/windows/NvBlastExtSerializationLL.cmake deleted file mode 100644 index 20910be..0000000 --- a/sdk/compiler/cmake/windows/NvBlastExtSerializationLL.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# -# Build NvBlastExtSerialization Windows -# - -SET(BLASTEXTSERIALIZATION_PLATFORM_COMMON_FILES - ${COMMON_SOURCE_DIR}/NvBlastIncludeWindows.h -) - -SET(BLASTEXTSERIALIZATION_PLATFORM_INCLUDES -) - -SET(BLASTEXTSERIALIZATION_COMPILE_DEFS - # Common to all configurations - ${BLAST_SLN_COMPILE_DEFS};_CONSOLE; - - $<$<CONFIG:debug>:${BLAST_SLN_DEBUG_COMPILE_DEFS}> - $<$<CONFIG:checked>:${BLAST_SLN_CHECKED_COMPILE_DEFS}> - $<$<CONFIG:profile>:${BLAST_SLN_PROFILE_COMPILE_DEFS}> - $<$<CONFIG:release>:${BLAST_SLN_RELEASE_COMPILE_DEFS}> -) - -SET(BLASTEXTSERIALIZATION_LIB_TYPE SHARED) - - -SET(BLASTEXTSERIALIZATION_COMPILE_OPTIONS "/wd4100;/wd4239;/wd4244;/wd4245;/wd4267;/EHsc") - diff --git a/sdk/extensions/assetutils/include/NvBlastExtAssetUtils.h b/sdk/extensions/assetutils/include/NvBlastExtAssetUtils.h new file mode 100644 index 0000000..3d5b3b9 --- /dev/null +++ b/sdk/extensions/assetutils/include/NvBlastExtAssetUtils.h @@ -0,0 +1,125 @@ +// 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 NVBLASTEXTASSETUTILS_H +#define NVBLASTEXTASSETUTILS_H + + +#include "NvBlastTypes.h" +#include "NvCTypes.h" +#include <stdint.h> + + +/** +Reauthor the provided asset to bond the specified support chunks to the world. + +\param[in] asset Pointer to the original asset. Won't be modified. +\param[in] worldBoundChunks Array of support chunk indices which are to be bound to the world. +\param[in] worldBoundChunksCount Size of worldBoundChunks array. +\param[in] bondDirections Array of normals for each bond (size worldBoundChunksCount) +\param[in] bondUserData Array of user data values for the new bonds, of size worldBoundChunksCount. May be NULL. If NULL, bond user data will be set to zero. + +\return a new asset with added bonds if successful, NULL otherwise. +*/ +NVBLAST_API NvBlastAsset* NvBlastExtAssetUtilsAddWorldBonds +( + const NvBlastAsset* asset, + const uint32_t* worldBoundChunks, + uint32_t worldBoundChunkCount, + const NvcVec3* bondDirections, + const uint32_t* bondUserData +); + + +/** +Bond descriptor used to merge assets. + +In addition to the NvBlastBondDesc fields, adds "component" indices to indicate +to which component asset the chunk indices in NvBlastBondDesc refer. Used in the +function NvBlastExtAssetUtilsMergeAssets. +*/ +struct NvBlastExtAssetUtilsBondDesc : public NvBlastBondDesc +{ + uint32_t componentIndices[2]; //!< The asset component for the corresponding chunkIndices[2] value. +}; + + +/** +Creates an asset descriptor which will build an asset that merges several assets. Each asset (or component) +is given a transform, applied to the geometric information in the chunk and bond descriptors. + +New bond descriptors may be given to bond support chunks from different components. + +An NvBlastAsset may appear more than once in the components array. + +NOTE: This function allocates memory using the allocator in NvBlastGlobals, to create the new chunk and bond +descriptor arrays referenced in the returned NvBlastAssetDesc. The user must free this memory after use with +NVBLAST_FREE appied to the pointers in the returned NvBlastAssetDesc. + +\param[in] components An array of assets to merge, of size componentCount. +\param[in] rotations An array of rotations to apply to the geometric data in the chunks and bonds, + stored quaternion format. The quaternions MUST be normalized. If NULL, no rotations are applied. + If not NULL, the array must be of size componentCount. +\param[in] translations An array of transforms to apply to the geometric data in the chunks and bonds. + If NULL, no translations are applied. If not NULL, the array must be of size componentCount. +\param[in] componentCount The size of the components and relativeTransforms arrays. +\param[in] newBondDescs Descriptors of type NvBlastExtAssetUtilsBondDesc for new bonds between components, of size newBondCount. If NULL, newBondCount must be 0. +\param[in] newBondCount The size of the newBondDescs array. + +\return an asset descriptor that will build an asset which merges the components, using NvBlastCreateAsset. +*/ +NVBLAST_API NvBlastAssetDesc NvBlastExtAssetUtilsMergeAssets +( + const NvBlastAsset** components, + const NvcQuat* rotations, + const NvcVec3* translations, + uint32_t componentCount, + const NvBlastExtAssetUtilsBondDesc* newBondDescs, + uint32_t newBondCount +); + + +/** +Transforms asset in place using scale, rotation, transform. +Chunk centroids, chunk bond centroids and bond normals are being transformed. +Chunk volume and bond area are changed accordingly. + +\param[in, out] asset Pointer to the asset to be transformed (modified). +\param[in] scale Pointer to scale to be applied. Can be nullptr. +\param[in] rotation Pointer to rotation to be applied. Can be nullptr. +\param[in] translation Pointer to translation to be applied. Can be nullptr. +*/ +NVBLAST_API void NvBlastExtAssetTransformInPlace +( + NvBlastAsset* asset, + const NvcVec3* scale, + const NvcQuat* rotation, + const NvcVec3* translation +); + +#endif // ifndef NVBLASTEXTASSETUTILS_H diff --git a/sdk/extensions/assetutils/source/NvBlastExtAssetUtils.cpp b/sdk/extensions/assetutils/source/NvBlastExtAssetUtils.cpp new file mode 100644 index 0000000..956764e --- /dev/null +++ b/sdk/extensions/assetutils/source/NvBlastExtAssetUtils.cpp @@ -0,0 +1,416 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtAssetUtils.h" +#include "NvBlast.h" +#include "NvBlastIndexFns.h" +#include "NvBlastMemory.h" +#include "NvBlastGlobals.h" +#include "math.h" + +using namespace Nv::Blast; + + +/** +Fill the chunk and bond descriptors from an asset. + +\param[out] chunkDescsWritten the number of chunk descriptors written to chunkDescs +\param[out] bondDescsWritten the number of bond descriptors written to bondDescs +\param[out] chunkDescs user-supplied buffer of NvBlastChunkDesc. Size must be at least NvBlastAssetGetChunkCount(asset, logFn) +\param[out] bondDescs user-supplied buffer of NvBlastBondDesc. Size must be at least NvBlastAssetGetBondCount(asset, logFn) +\param[in] asset asset from which to extract descriptors +*/ +static void fillChunkAndBondDescriptorsFromAsset +( + uint32_t& chunkDescsWritten, + uint32_t& bondDescsWritten, + NvBlastChunkDesc* chunkDescs, + NvBlastBondDesc* bondDescs, + const NvBlastAsset* asset +) +{ + chunkDescsWritten = 0; + bondDescsWritten = 0; + + // Chunk descs + const uint32_t assetChunkCount = NvBlastAssetGetChunkCount(asset, logLL); + const NvBlastChunk* assetChunk = NvBlastAssetGetChunks(asset, logLL); + for (uint32_t i = 0; i < assetChunkCount; ++i, ++assetChunk) + { + NvBlastChunkDesc& chunkDesc = chunkDescs[chunkDescsWritten++]; + memcpy(chunkDesc.centroid, assetChunk->centroid, sizeof(float) * 3); + chunkDesc.volume = assetChunk->volume; + chunkDesc.parentChunkIndex = assetChunk->parentChunkIndex; + chunkDesc.flags = 0; // To be filled in below + chunkDesc.userData = assetChunk->userData; + } + + // Bond descs + const uint32_t assetBondCount = NvBlastAssetGetBondCount(asset, logLL); + const NvBlastBond* assetBond = NvBlastAssetGetBonds(asset, logLL); + for (uint32_t i = 0; i < assetBondCount; ++i, ++assetBond) + { + NvBlastBondDesc& bondDesc = bondDescs[bondDescsWritten++]; + memcpy(&bondDesc.bond, assetBond, sizeof(NvBlastBond)); + } + + // Walk the graph and restore connection descriptors + const NvBlastSupportGraph graph = NvBlastAssetGetSupportGraph(asset, logLL); + for (uint32_t i = 0; i < graph.nodeCount; ++i) + { + const int32_t currentChunk = graph.chunkIndices[i]; + if (isInvalidIndex(currentChunk)) + { + continue; + } + + chunkDescs[currentChunk].flags |= NvBlastChunkDesc::SupportFlag; // Filling in chunk flags here + + for (uint32_t j = graph.adjacencyPartition[i]; j < graph.adjacencyPartition[i + 1]; ++j) + { + NvBlastBondDesc& bondDesc = bondDescs[graph.adjacentBondIndices[j]]; + bondDesc.chunkIndices[0] = currentChunk; + const uint32_t adjacentChunkIndex = graph.chunkIndices[graph.adjacentNodeIndices[j]]; + bondDesc.chunkIndices[1] = adjacentChunkIndex; + } + } +} + + +/** +Scale a 3-vector v in-place. + +\param[in,out] v The vector to scale. +\param[in] s The scale. Represents the diagonal elements of a diagonal matrix. + +The result will be v <- s*v. +*/ +static inline void scale(NvcVec3& v, const NvcVec3& s) +{ + v.x *= s.x; + v.y *= s.y; + v.z *= s.z; +} + + +/** +Rotate a 3-vector v in-place using a rotation represented by a quaternion q. + +\param[in,out] v The vector to rotate. +\param[in] q The quaternion representation the rotation. + +The format of q is { x, y, z, w } where (x,y,z) is the vector part and w is the scalar part. +The quaternion q MUST be normalized. +*/ +static inline void rotate(NvcVec3& v, const NvcQuat& q) +{ + const float vx = 2.0f * v.x; + const float vy = 2.0f * v.y; + const float vz = 2.0f * v.z; + const float w2 = q.w * q.w - 0.5f; + const float dot2 = (q.x * vx + q.y * vy + q.z * vz); + v.x = vx * w2 + (q.y * vz - q.z * vy) * q.w + q.x * dot2; + v.y = vy * w2 + (q.z * vx - q.x * vz) * q.w + q.y * dot2; + v.z = vz * w2 + (q.x * vy - q.y * vx) * q.w + q.z * dot2; +} + + +/** +Translate a 3-vector v in-place. + +\param[in,out] v The vector to translate. +\param[in] t The translation. + +The result will be v <- v+t. +*/ +static inline void translate(NvcVec3& v, const NvcVec3& t) +{ + v.x += t.x; + v.y += t.y; + v.z += t.z; +} + + +NvBlastAsset* NvBlastExtAssetUtilsAddWorldBonds +( + const NvBlastAsset* asset, + const uint32_t* worldBoundChunks, + uint32_t worldBoundChunkCount, + const NvcVec3* bondDirections, + const uint32_t* bondUserData +) +{ + const uint32_t chunkCount = NvBlastAssetGetChunkCount(asset, logLL); + const uint32_t oldBondCount = NvBlastAssetGetBondCount(asset, logLL); + const uint32_t newBondCount = oldBondCount + worldBoundChunkCount; + + NvBlastChunkDesc* chunkDescs = static_cast<NvBlastChunkDesc*>(NVBLAST_ALLOC(chunkCount * sizeof(NvBlastChunkDesc))); + NvBlastBondDesc* bondDescs = static_cast<NvBlastBondDesc*>(NVBLAST_ALLOC(newBondCount * sizeof(NvBlastBondDesc))); + + // Create chunk descs + uint32_t chunkDescsWritten; + uint32_t bondDescsWritten; + fillChunkAndBondDescriptorsFromAsset(chunkDescsWritten, bondDescsWritten, chunkDescs, bondDescs, asset); + + // Add world bonds + uint32_t bondCount = oldBondCount; + for (uint32_t i = 0; i < worldBoundChunkCount; i++) + { + NvBlastBondDesc& bondDesc = bondDescs[bondCount++]; + const uint32_t chunkIndex = worldBoundChunks[i]; + bondDesc.chunkIndices[0] = chunkIndex; + bondDesc.chunkIndices[1] = invalidIndex<uint32_t>(); + memcpy(&bondDesc.bond.normal, bondDirections + i, sizeof(float) * 3); + bondDesc.bond.area = 1.0f; // Should be set by user + memcpy(&bondDesc.bond.centroid, chunkDescs[chunkIndex].centroid, sizeof(float) * 3); + bondDesc.bond.userData = bondUserData != nullptr ? bondUserData[i] : 0; + } + + // Create new asset + NvBlastAssetDesc assetDesc; + assetDesc.chunkCount = chunkCount; + assetDesc.chunkDescs = chunkDescs; + assetDesc.bondCount = bondCount; + assetDesc.bondDescs = bondDescs; + void* scratch = NVBLAST_ALLOC(NvBlastGetRequiredScratchForCreateAsset(&assetDesc, logLL)); + NvBlastAsset* newAsset = NvBlastCreateAsset(NVBLAST_ALLOC(NvBlastGetAssetMemorySize(&assetDesc, logLL)), &assetDesc, scratch, logLL); + + // Free buffers + NVBLAST_FREE(scratch); + NVBLAST_FREE(bondDescs); + NVBLAST_FREE(chunkDescs); + + return newAsset; +} + + +NvBlastAssetDesc NvBlastExtAssetUtilsMergeAssets +( + const NvBlastAsset** components, + const NvcQuat* rotations, + const NvcVec3* translations, + uint32_t componentCount, + const NvBlastExtAssetUtilsBondDesc* newBondDescs, + uint32_t newBondCount +) +{ + // Count the total number of chunks and bonds in the new asset + uint32_t totalChunkCount = 0; + uint32_t totalBondCount = newBondCount; + for (uint32_t c = 0; c < componentCount; ++c) + { + totalChunkCount += NvBlastAssetGetChunkCount(components[c], logLL); + totalBondCount += NvBlastAssetGetBondCount(components[c], logLL); + } + + // Allocate space for chunk and bond descriptors + NvBlastChunkDesc* chunkDescs = static_cast<NvBlastChunkDesc*>(NVBLAST_ALLOC(totalChunkCount * sizeof(NvBlastChunkDesc))); + NvBlastBondDesc* bondDescs = static_cast<NvBlastBondDesc*>(NVBLAST_ALLOC(totalBondCount * sizeof(NvBlastBondDesc))); + + // Create a list of chunk index offsets per component + uint32_t* chunkIndexOffsets = static_cast<uint32_t*>(NvBlastAlloca(componentCount * sizeof(uint32_t))); + + // Fill the chunk and bond descriptors from the components + uint32_t chunkCount = 0; + uint32_t bondCount = 0; + for (uint32_t c = 0; c < componentCount; ++c) + { + chunkIndexOffsets[c] = chunkCount; + uint32_t componentChunkCount; + uint32_t componentBondCount; + fillChunkAndBondDescriptorsFromAsset(componentChunkCount, componentBondCount, chunkDescs + chunkCount, bondDescs + bondCount, components[c]); + // Fix bonds' chunk indices + for (uint32_t i = 0; i < componentBondCount; ++i) + { + NvBlastBondDesc& bondDesc = bondDescs[bondCount + i]; + for (int j = 0; j < 2; ++j) + { + if (!isInvalidIndex(bondDesc.chunkIndices[j])) + { + bondDesc.chunkIndices[j] += chunkCount; + } + } + } + // Transform geometric data + if (rotations != nullptr) + { + for (uint32_t i = 0; i < componentChunkCount; ++i) + { + rotate(reinterpret_cast<NvcVec3&>(chunkDescs[chunkCount + i].centroid), rotations[c]); + } + for (uint32_t i = 0; i < componentBondCount; ++i) + { + NvBlastBond& bond = bondDescs[bondCount + i].bond; + rotate(reinterpret_cast<NvcVec3&>(bond.normal), rotations[c]); // Normal can be transformed this way since we aren't scaling + rotate(reinterpret_cast<NvcVec3&>(bond.centroid), rotations[c]); + } + } + if (translations != nullptr) + { + for (uint32_t i = 0; i < componentChunkCount; ++i) + { + translate(reinterpret_cast<NvcVec3&>(chunkDescs[chunkCount + i].centroid), translations[c]); + } + for (uint32_t i = 0; i < componentBondCount; ++i) + { + translate(reinterpret_cast<NvcVec3&>(bondDescs[bondCount + i].bond.centroid), translations[c]); + } + } + chunkCount += componentChunkCount; + bondCount += componentBondCount; + } + + // Fill the bond descriptors from the new bond descs + for (uint32_t b = 0; b < newBondCount; ++b) + { + const NvBlastExtAssetUtilsBondDesc& newBondDesc = newBondDescs[b]; + NvBlastBondDesc& bondDesc = bondDescs[bondCount++]; + memcpy(&bondDesc.bond, &newBondDesc.bond, sizeof(NvBlastBond)); + bondDesc.chunkIndices[0] = !isInvalidIndex(newBondDesc.chunkIndices[0]) ? newBondDesc.chunkIndices[0] + chunkIndexOffsets[newBondDesc.componentIndices[0]] : invalidIndex<uint32_t>(); + bondDesc.chunkIndices[1] = !isInvalidIndex(newBondDesc.chunkIndices[1]) ? newBondDesc.chunkIndices[1] + chunkIndexOffsets[newBondDesc.componentIndices[1]] : invalidIndex<uint32_t>(); + } + + // Create new asset desriptor + NvBlastAssetDesc assetDesc; + assetDesc.chunkCount = chunkCount; + assetDesc.chunkDescs = chunkDescs; + assetDesc.bondCount = bondCount; + assetDesc.bondDescs = bondDescs; + + return assetDesc; +} + + +/** +Multiply a 3-vector v in-place by value. + +\param[in,out] v The vector to multiply. +\param[in] m The 3x3 matrix. +*/ +static inline void multiply(NvcVec3& v, float value) +{ + v.x *= value; + v.y *= value; + v.z *= value; +} + + +/** +Get Vec3 length +*/ +static inline float length(const NvcVec3& p) +{ + return sqrtf(p.x * p.x + p.y * p.y + p.z * p.z); +} + + +/** +Transform a point in-place: scale, rotate, then translate + +\param[in,out] p The point to transform. +\param[in] S The diagonal elements of a diagonal scale matrix. +\param[in] R A quaternion representing the rotation. Must be normalized. +\param[in] T The translation vector. +*/ +static inline void transform(NvcVec3& p, const NvcVec3& S, const NvcQuat& R, const NvcVec3& T) +{ + scale(p, S); + rotate(p, R); + translate(p, T); +} + + +/** +Transform a vector in-place: scale, then rotate + +\param[in,out] v The vector to transform. +\param[in] S The diagonal elements of a diagonal scale matrix. +\param[in] R A quaternion representing the rotation. Must be normalized. +*/ +static inline void transform(NvcVec3& v, const NvcVec3& S, const NvcQuat& R) +{ + scale(v, S); + rotate(v, R); +} + + +void NvBlastExtAssetTransformInPlace(NvBlastAsset* asset, const NvcVec3* scaling, const NvcQuat* rotation, const NvcVec3* translation) +{ + // Local copies of scaling (S), rotation (R), and translation (T) + NvcVec3 S = { 1, 1, 1 }; + NvcQuat R = { 0, 0, 0, 1 }; + NvcVec3 T = { 0, 0, 0 }; + NvcVec3 cofS = { 1, 1, 1 }; + float absDetS = 1; + float sgnDetS = 1; + + { + if (rotation) + { + R = *rotation; + } + + if (scaling) + { + S = *scaling; + cofS.x = S.y * S.z; + cofS.y = S.z * S.x; + cofS.z = S.x * S.y; + absDetS = S.x * S.y * S.z; + sgnDetS = absDetS < 0 ? -1 : 1; + absDetS *= sgnDetS; + } + + if (translation) + { + T = *translation; + } + } + + // Chunk descs + const uint32_t assetChunkCount = NvBlastAssetGetChunkCount(asset, logLL); + NvBlastChunk* assetChunk = const_cast<NvBlastChunk*>(NvBlastAssetGetChunks(asset, logLL)); + for (uint32_t i = 0; i < assetChunkCount; ++i, ++assetChunk) + { + transform(reinterpret_cast<NvcVec3&>(assetChunk->centroid), S, R, T); + assetChunk->volume *= absDetS; // Use |detS| to keep the volume positive + } + + // Bond descs + const uint32_t assetBondCount = NvBlastAssetGetBondCount(asset, logLL); + NvBlastBond* assetBond = const_cast<NvBlastBond*>(NvBlastAssetGetBonds(asset, logLL)); + for (uint32_t i = 0; i < assetBondCount; ++i, ++assetBond) + { + transform(reinterpret_cast<NvcVec3&>(assetBond->centroid), S, R, T); + NvcVec3& normal = reinterpret_cast<NvcVec3&>(assetBond->normal); + transform(normal, cofS, R); + const float l = length(normal); + assetBond->area *= l; + multiply(normal, l > 0.f ? sgnDetS / l : 1.f); + } +} diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoring.h b/sdk/extensions/authoring/include/NvBlastExtAuthoring.h new file mode 100644 index 0000000..ce21c65 --- /dev/null +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoring.h @@ -0,0 +1,119 @@ +// 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 NVBLASTAUTHORING_H +#define NVBLASTAUTHORING_H + +#include "NvBlastExtAuthoringTypes.h" + +namespace physx +{ + class PxCooking; + class PxPhysicsInsertionCallback; +} + +namespace Nv +{ + namespace Blast + { + class Mesh; + class VoronoiSitesGenerator; + class FractureTool; + class ConvexMeshBuilder; + class BlastBondGenerator; + class MeshCleaner; + } +} + +/** +Constructs mesh object from array of triangles. +User should call release() after usage. + +\param[in] positions Array for vertex positions, 3 * verticesCount floats will be read +\param[in] normals Array for vertex normals, 3 * verticesCount floats will be read +\param[in] uv Array for vertex uv coordinates, 2 * verticesCount floats will be read +\param[in] verticesCount Number of vertices in mesh +\param[in] indices Array of vertex indices. Indices contain vertex index triplets which form a mesh triangle. +\param[in] indicesCount Indices count (should be equal to numberOfTriangles * 3) + +\return pointer to Nv::Blast::Mesh if it was created succefully otherwise return nullptr +*/ +NVBLAST_API Nv::Blast::Mesh* NvBlastExtAuthoringCreateMesh(const physx::PxVec3* positions, const physx::PxVec3* normals, + const physx::PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount); + +/** +Voronoi sites should not be generated outside of the fractured mesh, so VoronoiSitesGenerator +should be supplied with fracture mesh. +\param[in] mesh Fracture mesh +\param[in] rnd User supplied random value generator. +\return Pointer to VoronoiSitesGenerator. User's code should release it after usage. +*/ +NVBLAST_API Nv::Blast::VoronoiSitesGenerator* NvBlastExtAuthoringCreateVoronoiSitesGenerator(Nv::Blast::Mesh* mesh, + Nv::Blast::RandomGeneratorBase* rng); + +/** +Create FractureTool object. +\return Pointer to create FractureTool. User's code should release it after usage. +*/ +NVBLAST_API Nv::Blast::FractureTool* NvBlastExtAuthoringCreateFractureTool(); + +/** +Create BlastBondGenerator +\return Pointer to created BlastBondGenerator. User's code should release it after usage. +*/ +NVBLAST_API Nv::Blast::BlastBondGenerator* NvBlastExtAuthoringCreateBondGenerator(physx::PxCooking* cooking, + physx::PxPhysicsInsertionCallback* insertionCallback); + +/** +Create ConvexMeshBuilder +\return Pointer to created ConvexMeshBuilder. User's code should release it after usage. +*/ +NVBLAST_API Nv::Blast::ConvexMeshBuilder* NvBlastExtAuthoringCreateConvexMeshBuilder(physx::PxCooking* cooking, + physx::PxPhysicsInsertionCallback* insertionCallback); + +/** +Performs pending fractures and generates fractured asset, render and collision geometry + +\param[in] fTool Fracture tool created by NvBlastExtAuthoringCreateFractureTool +\param[in] bondGenerator Bond generator created by NvBlastExtAuthoringCreateBondGenerator +\param[in] collisionBuilder Collision builder created by NvBlastExtAuthoringCreateConvexMeshBuilder +\param[in] defaultSupportDepth All new chunks will be marked as support if its depth equal to defaultSupportDepth. + By default leaves (chunks without children) marked as support. +\return Authoring result +*/ +NVBLAST_API Nv::Blast::AuthoringResult* NvBlastExtAuthoringProcessFracture(Nv::Blast::FractureTool& fTool, + Nv::Blast::BlastBondGenerator& bondGenerator, Nv::Blast::ConvexMeshBuilder& collisionBuilder, int32_t defaultSupportDepth = -1); + + +/** + Creates MeshCleaner object + \return pointer to Nv::Blast::Mesh if it was created succefully otherwise return nullptr +*/ +NVBLAST_API Nv::Blast::MeshCleaner* NvBlastExtAuthoringCreateMeshCleaner(); + +#endif // ifndef NVBLASTAUTHORING_H diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h index 68767eb..4f5d0e6 100644 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h @@ -1,35 +1,54 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTAUTHORINGBONDGENERATOR_H #define NVBLASTEXTAUTHORINGBONDGENERATOR_H #include "NvBlastExtAuthoringTypes.h" -#include "NvBlastExtAuthoringFractureTool.h" -#include "NvBlastTypes.h" -#include "../cooking/PxCooking.h" -#include <PxPlane.h> -#include <NvBlastExtAuthoringCollisionBuilder.h> + +namespace physx +{ +class PxPlane; +class PxCooking; +class PxPhysicsInsertionCallback; +} + struct NvBlastBondDesc; struct NvBlastChunkDesc; struct NvBlastBond; -using namespace physx; - - namespace Nv { namespace Blast { // Forward declarations +class FractureTool; class TriangleProcessor; struct PlaneChunkIndexer; @@ -61,73 +80,75 @@ struct PlaneChunkIndexer class BlastBondGenerator { public: - - BlastBondGenerator(physx::PxCooking* cooking, physx::PxPhysicsInsertionCallback* insertionCallback) : mPxCooking(cooking), mPxInsertionCallback(insertionCallback){}; + virtual ~BlastBondGenerator() {} + + /** + Release BlastBondGenerator memory + */ + virtual void release() = 0; /** This method based on marking triangles during fracture process, so can be used only with internally fractured meshes. - \param[in] tool FractureTool which contains chunks representation, tool->finalizeFracturing() should be called before. - \param[in] chunkIsSupport Array of flags, if true - chunk is support. Array size should be equal to chunk count in tool. - \param[out] resultBondDescs Array of created bond descriptors. - \param[out] resultChunkDescriptors Array of created chunk descriptors. - \return 0 if success + \note User should call NVBLAST_FREE for resultBondDescs when it not needed anymore + \param[in] tool FractureTool which contains chunks representation, tool->finalizeFracturing() should be called before. + \param[in] chunkIsSupport Pointer to array of flags, if true - chunk is support. Array size should be equal to chunk count in tool. + \param[out] resultBondDescs Pointer to array of created bond descriptors. + \param[out] resultChunkDescriptors Pointer to array of created chunk descriptors. + \return Number of created bonds */ - int32_t buildDescFromInternalFracture(FractureTool* tool, const std::vector<bool>& chunkIsSupport, std::vector<NvBlastBondDesc>& resultBondDescs, std::vector<NvBlastChunkDesc>& resultChunkDescriptors); + virtual int32_t buildDescFromInternalFracture(FractureTool* tool, const bool* chunkIsSupport, + NvBlastBondDesc*& resultBondDescs, NvBlastChunkDesc*& resultChunkDescriptors) = 0; /** Creates bond description between two meshes - \param[in] meshA Array of triangles of mesh A. - \param[in] meshB Array of triangles of mesh B. - \param[out] resultBond Result bond description. - \param[in] conf Bond creation mode. - \return 0 if success + \param[in] meshACount Number of triangles in mesh A + \param[in] meshA Pointer to array of triangles of mesh A. + \param[in] meshBCount Number of triangles in mesh B + \param[in] meshB Pointer to array of triangles of mesh B. + \param[out] resultBond Result bond description. + \param[in] conf Bond creation mode. + \return 0 if success */ - int32_t createBondBetweenMeshes(const std::vector<Triangle>& meshA, const std::vector<Triangle>& meshB, NvBlastBond& resultBond, BondGenerationConfig conf = BondGenerationConfig()); + virtual int32_t createBondBetweenMeshes(uint32_t meshACount, const Triangle* meshA, uint32_t meshBCount, const Triangle* meshB, + NvBlastBond& resultBond, BondGenerationConfig conf = BondGenerationConfig()) = 0; /** Creates bond description between number of meshes - \param[in] geometry Array of arrays of triangles for each chunk. - \param[out] resultBond Array of result bonds. - \param[in] overlaps Array of pairs - indexes of chunks, for which bond should be created. - \param[in] cfg Bond creation mode. - \return 0 if success + \note User should call NVBLAST_FREE for resultBondDescs when it not needed anymore + \param[in] meshCount Number of meshes + \param[in] geometryOffset Pointer to array of triangle offsets for each mesh. + Containts meshCount + 1 element, last one is total number of triangles in geometry + \param[in] geometry Pointer to array of triangles. + Triangles from geometryOffset[i] to geometryOffset[i+1] correspond to i-th mesh. + \param[in] overlapsCount Number of overlaps + \param[in] overlaps Pointer to array of pairs - indexes of chunks, for which bond should be created. + \param[out] resultBond Pointer to array of result bonds. + \param[in] cfg Bond creation mode. + \return Number of created bonds */ - int32_t createBondBetweenMeshes(const std::vector<std::vector<Triangle> >& geometry, std::vector<NvBlastBondDesc>& resultBond, const std::vector<std::pair<uint32_t, uint32_t> >& overlaps, BondGenerationConfig cfg); + virtual int32_t createBondBetweenMeshes(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + uint32_t overlapsCount, const uint32_t* overlapsA, const uint32_t* overlapsB, + NvBlastBondDesc*& resultBond, BondGenerationConfig cfg) = 0; /** Creates bond description for prefractured meshes, when there is no info about which chunks should be connected with bond. - \param[in] geometry Array of arrays of triangles for each chunk. - \param[in] chunkIsSupport Array of flags, if true - chunk is support. Array size should be equal to chunk count in tool. - \param[out] resultBondDescs Array of result bonds. - \param[in] conf Bond creation mode. - \return 0 if success + \note User should call NVBLAST_FREE for resultBondDescs when it not needed anymore + \param[in] meshCount Number of meshes + \param[in] geometryOffset Pointer to array of triangle offsets for each mesh. + Containts meshCount + 1 element, last one is total number of triangles in geometry + \param[in] geometry Pointer to array of triangles. + Triangles from geometryOffset[i] to geometryOffset[i+1] correspond to i-th mesh. + \param[in] chunkIsSupport Pointer to array of flags, if true - chunk is support. Array size should be equal to chunk count in tool. + \param[out] resultBondDescs Pointer to array of result bonds. + \param[in] conf Bond creation mode. + \return Number of created bonds */ - int32_t bondsFromPrefractured(const std::vector<std::vector<Triangle>>& geometry, const std::vector<bool>& chunkIsSupport, std::vector<NvBlastBondDesc>& resultBondDescs, BondGenerationConfig conf = BondGenerationConfig()); + virtual int32_t bondsFromPrefractured(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + const bool*& chunkIsSupport, NvBlastBondDesc*& resultBondDescs, + BondGenerationConfig conf = BondGenerationConfig()) = 0; -private: - float processWithMidplanes(TriangleProcessor* trProcessor, const std::vector<physx::PxVec3>& chunk1Points, const std::vector<physx::PxVec3>& chunk2Points, - const std::vector<physx::PxVec3>& hull1p,const std::vector<physx::PxVec3>& hull2p, physx::PxVec3& normal, physx::PxVec3& centroid); - - int32_t createFullBondListAveraged(const std::vector<std::vector<Triangle>>& chunksGeometry, const std::vector<bool>& supportFlags, std::vector<NvBlastBondDesc>& mResultBondDescs, BondGenerationConfig conf); - int32_t createFullBondListExact(const std::vector<std::vector<Triangle>>& chunksGeometry, const std::vector<bool>& supportFlags, std::vector<NvBlastBondDesc>& mResultBondDescs, BondGenerationConfig conf); - int32_t createFullBondListExactInternal(const std::vector<std::vector<Triangle>>& chunksGeometry, std::vector < PlaneChunkIndexer >& planeTriangleMapping , std::vector<NvBlastBondDesc>& mResultBondDescs); - int32_t createBondForcedInternal(const std::vector<PxVec3>& hull0, const std::vector<PxVec3>& hull1,const CollisionHull& cHull0, const CollisionHull& cHull1,PxBounds3 bound0, PxBounds3 bound1, NvBlastBond& resultBond, float overlapping); - - void buildGeometryCache(const std::vector<std::vector<Triangle> >& geometry); - void resetGeometryCache(); - - physx::PxCooking* mPxCooking; - physx::PxPhysicsInsertionCallback* mPxInsertionCallback; - - - std::vector<std::vector<Triangle> > mGeometryCache; - - std::vector<PlaneChunkIndexer> mPlaneCache; - std::vector<CollisionHull> mCHullCache; - std::vector<std::vector<physx::PxVec3> > mHullsPointsCache; - std::vector<physx::PxBounds3 > mBoundsCache; }; } // namespace Blast diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h index b3e143a..1e851bb 100644 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h @@ -1,26 +1,42 @@ -/* -* 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 NVBLASTEXTAUTHORINGCOLLISIONBUILDER_H #define NVBLASTEXTAUTHORINGCOLLISIONBUILDER_H #include "NvBlastTypes.h" -#include <vector> -#include <PxVec3.h> namespace physx { - class PxCooking; - class PxPhysicsInsertionCallback; - class PxVec3; - class PxConvexMesh; +class PxCooking; +class PxPhysicsInsertionCallback; +class PxVec3; +class PxConvexMesh; } @@ -29,32 +45,7 @@ namespace Nv namespace Blast { -/** - Collision hull geometry format. -*/ -struct CollisionHull -{ - /** - Collision hull polygon format. - */ - struct HullPolygon - { - // Polygon base plane - float mPlane[4]; - // Number vertices in polygon - uint16_t mNbVerts; - // First index in CollisionHull.indices array for this polygon - uint16_t mIndexBase; - }; - ///** - - CollisionHull(){}; - - std::vector<physx::PxVec3> points; - std::vector<uint32_t> indices; - std::vector<HullPolygon> polygonData; -}; - +struct CollisionHull; /** ConvexMeshBuilder provides routine to build collision hulls from array of vertices. @@ -64,35 +55,38 @@ struct CollisionHull class ConvexMeshBuilder { public: + virtual ~ConvexMeshBuilder() {} /** - Constructor should be provided with PxCoocking and PxPhysicsInsertionCallback objects. + Release ConvexMeshBuilder memory */ - ConvexMeshBuilder(physx::PxCooking* cooking, physx::PxPhysicsInsertionCallback* insertionCallback) : mInsertionCallback(insertionCallback), mCooking(cooking) {} + virtual void release() = 0; /** Method creates CollisionHull from provided array of vertices. + \param[in] verticesCount Number of vertices \param[in] vertexData Vertex array of some object, for which collision geometry should be built \param[out] output Reference on CollisionHull object in which generated geometry should be saved */ - void buildCollisionGeometry(const std::vector<physx::PxVec3>& vertexData, CollisionHull& output); + virtual CollisionHull* buildCollisionGeometry(uint32_t verticesCount, const physx::PxVec3* vertexData) = 0; /** Method creates PxConvexMesh from provided array of vertices. - \param[in] vertexData Vertex array of some object, for which collision geometry should be built + \param[in] verticesCount Number of vertices + \param[in] vertexData Vertex array of some object, for which collision geometry should be built \return pointer to the PxConvexMesh object if it was built successfully, 'nullptr' otherwise. */ - physx::PxConvexMesh* buildConvexMesh(std::vector<physx::PxVec3>& vertexData); + virtual physx::PxConvexMesh* buildConvexMesh(uint32_t verticesCount, const physx::PxVec3* vertexData) = 0; /** Method creates PxConvexMesh from provided ConvexHull geometry - \param[in] hull ConvexHull geometry + \param[in] hull ConvexHull geometry \return pointer to the PxConvexMesh object if it was built successfully, 'nullptr' otherwise. */ - physx::PxConvexMesh* buildConvexMesh(CollisionHull& hull); + virtual physx::PxConvexMesh* buildConvexMesh(const CollisionHull& hull) = 0; /** @@ -102,18 +96,13 @@ public: This method trims all intersecting parts of collision geometry. As a drawback, trimming collision geometry can lead to penetrating render meshes during simulation. - - \param[in] in ConvexHull geometry which should be clipped. - \param[in] chunkDepth Array of depth levels of convex hulls corresponding chunks. + \param[in] chunksCount Number of chunks + \param[in,out] in ConvexHull geometry which should be clipped. + \param[in] chunkDepth Array of depth levels of convex hulls corresponding chunks. */ - - void trimCollisionGeometry(std::vector<CollisionHull>& in, const std::vector<uint32_t>& chunkDepth); - + virtual void trimCollisionGeometry(uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth) = 0; -private: - physx::PxPhysicsInsertionCallback* mInsertionCallback; - physx::PxCooking* mCooking; }; } // namespace Blast diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h index 528ffbc..82959ac 100644 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h @@ -1,19 +1,35 @@ -/* -* 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 NVBLASTAUTHORINGFRACTURETOOL_H #define NVBLASTAUTHORINGFRACTURETOOL_H -#include "NvBlastExtAuthoringMesh.h" -#include "NvBlastTypes.h" - +#include "NvBlastExtAuthoringTypes.h" namespace Nv { @@ -21,8 +37,8 @@ namespace Blast { class SpatialAccelerator; -class ChunkPostProcessor; - +class Triangulator; +class Mesh; /* Chunk data, chunk with chunkId == 0 is always source mesh. @@ -38,119 +54,83 @@ struct ChunkInfo /* Slicing fracturing configuration - - - default: - x_slices = 1; - y_slices = 1; - z_slices = 1; - - offset_variations = 0.f; - angle_variations = 0.f; - noiseAmplitude = 0.f; - noiseFrequency = 1.f; - noiseOctaveNumber = 1; - surfaceResolution = 1; */ struct SlicingConfiguration { /** Number of slices in each direction */ - int32_t x_slices, y_slices, z_slices; + int32_t x_slices = 1, y_slices = 1, z_slices = 1; /** Offset variation, value in [0, 1] */ - float offset_variations; + float offset_variations = 0.f; + /** Angle variation, value in [0, 1] */ - float angle_variations; - + float angle_variations = 0.f; /** Noisy slicing configutaion: Amplitude of cutting surface noise. If it is 0 - noise is disabled. */ - float noiseAmplitude; + float noiseAmplitude = 0.f; + /** Frequencey of cutting surface noise. */ - float noiseFrequency; + float noiseFrequency = 1.f; + /** Octave number in slicing surface noise. */ - uint32_t noiseOctaveNumber; - /** - Cutting surface resolution. - */ - int32_t surfaceResolution; - + uint32_t noiseOctaveNumber = 1; - SlicingConfiguration() - { - reset(); - } /** - Set default params. + Cutting surface resolution. */ - void reset() - { - x_slices = 1; - y_slices = 1; - z_slices = 1; - - offset_variations = 0.f; - angle_variations = 0.f; - noiseAmplitude = 0.f; - noiseFrequency = 1.f; - noiseOctaveNumber = 1; - surfaceResolution = 1; - } - + int32_t surfaceResolution = 1; }; - /** Class for voronoi sites generation inside supplied mesh. */ class VoronoiSitesGenerator { public: - - /** - Voronoi sites should not be generated outside of the fractured mesh, so VoronoiSitesGenerator - should be supplied with fracture mesh. - \param[in] mesh Fracture mesh - \param[in] rnd User supplied random value generator. - \return + virtual ~VoronoiSitesGenerator() {} + + /** + Release VoronoiSitesGenerator memory */ - VoronoiSitesGenerator(Mesh* mesh, RandomGeneratorBase* rnd); - ~VoronoiSitesGenerator(); + virtual void release() = 0; /** Set base fracture mesh */ - void setBaseMesh(Mesh* m); + virtual void setBaseMesh(const Mesh* mesh) = 0; /** - Returns reference on vector of generated voronoi sites. + Access to generated voronoi sites. + \param[out] Pointer to generated voronoi sites + \return Count of generated voronoi sites. */ - std::vector<physx::PxVec3>& getVoronoiSites(); + virtual uint32_t getVoronoiSites(const physx::PxVec3*& sites) = 0; /** Add site in particular point \param[in] site Site coordinates */ - void addSite(const physx::PxVec3& site); + virtual void addSite(const physx::PxVec3& site) = 0; /** Uniformly generate sites inside the mesh \param[in] numberOfSites Number of generated sites */ - void uniformlyGenerateSitesInMesh(const uint32_t numberOfSites); + virtual void uniformlyGenerateSitesInMesh(uint32_t numberOfSites) = 0; /** Generate sites in clustered fashion @@ -158,7 +138,7 @@ public: \param[in] sitesPerCluster Number of sites in each cluster \param[in] clusterRadius Voronoi cells cluster radius */ - void clusteredSitesGeneration(const uint32_t numberOfClusters, const uint32_t sitesPerCluster, float clusterRadius); + virtual void clusteredSitesGeneration(uint32_t numberOfClusters, uint32_t sitesPerCluster, float clusterRadius) = 0; /** Radial pattern of sites generation @@ -170,7 +150,7 @@ public: \param[in] angleOffset Angle offset at each radial step \param[in] variability Randomness of sites distribution */ - void radialPattern(const physx::PxVec3& center, const physx::PxVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset = 0.0f, float variability = 0.0f); + virtual void radialPattern(const physx::PxVec3& center, const physx::PxVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset = 0.0f, float variability = 0.0f) = 0; /** Generate sites inside sphere @@ -178,16 +158,16 @@ public: \param[in] radius Radius of sphere \param[in] center Center of sphere */ - void generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center); + virtual void generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center) = 0; /** Set stencil mesh. With stencil mesh sites are generated only inside both of fracture and stencil meshes. \param[in] stencil Stencil mesh. */ - void setStencil(Mesh* stencil); + virtual void setStencil(const Mesh* stencil) = 0; /** Removes stencil mesh */ - void clearStencil(); + virtual void clearStencil() = 0; /** Deletes sites inside supplied sphere @@ -195,18 +175,9 @@ public: \param[in] center Center of sphere \param[in] eraserProbability Probability of removing some particular site */ - void deleteInSphere(const float radius, const physx::PxVec3& center, const float eraserProbability = 1); - -private: - std::vector<physx::PxVec3> mGeneratedSites; - Mesh* mMesh; - Mesh* mStencil; - RandomGeneratorBase* mRnd; - SpatialAccelerator* mAccelerator; + virtual void deleteInSphere(const float radius, const physx::PxVec3& center, const float eraserProbability = 1) = 0; }; - - /** FractureTool class provides methods to fracture provided mesh and generate Blast asset data */ @@ -214,44 +185,34 @@ class FractureTool { public: + virtual ~FractureTool() {} /** - FractureTool can log asset creation info if logCallback is provided. + Release FractureTool memory */ - FractureTool(NvBlastLog logCallback = nullptr) - { - mPlaneIndexerOffset = 1; - mChunkIdCounter = 0; - mRemoveIslands = false; - mLoggingCallback = logCallback; - } - - ~FractureTool() - { - reset(); - } + virtual void release() = 0; /** Reset FractureTool state. */ - void reset(); + virtual void reset() = 0; /** Set input mesh wich will be fractured, FractureTool will be reseted. */ - void setSourceMesh(Mesh* mesh); + virtual void setSourceMesh(const Mesh* mesh) = 0; /** - Get chunk mesh in polygonal representation + Get chunk mesh in polygonal representation. User's code should release it after usage. */ - Mesh getChunkMesh(int32_t chunkId); + virtual Mesh* createChunkMesh(int32_t chunkId) = 0; /** Input mesh is scaled and transformed internally to fit unit cube centered in origin. Method provides offset vector and scale parameter; */ - void getTransformation(physx::PxVec3& offset, float& scale); + virtual void getTransformation(physx::PxVec3& offset, float& scale) = 0; /** @@ -262,7 +223,7 @@ public: Case replaceChunk == true && chunkId == 0 considered as wrong input parameters \return If 0, fracturing is successful. */ - int32_t voronoiFracturing(uint32_t chunkId, const std::vector<physx::PxVec3>& cellPoints, bool replaceChunk); + virtual int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPoints, bool replaceChunk) = 0; /** Fractures specified chunk with voronoi method. Cells can be scaled along x,y,z axes. @@ -274,7 +235,7 @@ public: Case replaceChunk == true && chunkId == 0 considered as wrong input parameters \return If 0, fracturing is successful. */ - int32_t voronoiFracturing(uint32_t chunkId, const std::vector<physx::PxVec3>& cellPoints, const physx::PxVec3& scale, bool replaceChunk); + virtual int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPoints, const physx::PxVec3& scale, bool replaceChunk) = 0; /** @@ -287,37 +248,20 @@ public: \return If 0, fracturing is successful. */ - int32_t slicing(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd); + virtual int32_t slicing(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) = 0; /** Creates resulting fractured mesh geometry from intermediate format */ - void finalizeFracturing(); + virtual void finalizeFracturing() = 0; - /** - Get chunk information - */ - const std::vector<ChunkInfo>& getChunkList(); - + virtual uint32_t getChunkCount() const = 0; /** - Tesselate interior surfaces - \param[in] averageEdgeLength - Average length of edge on internal surface. - */ - void tesselate(float averageEdgeLength); - - /** - Apply noise to interior surfaces. Must be called only after tesselation! - \param[in] amplitude Amplitude of noise - \param[in] frequency Frequency of noise - \param[in] octaves Number of noise octaves - \param[in] falloff - damping of noise around of external surface - \param[in] relaxIterations - number of smoothing iterations before applying noise - \param[in] relaxFactor - amount of smoothing before applying noise. - \param[in] seed Random seed value + Get chunk information */ - void applyNoise(float amplitude, float frequency, int32_t octaves, float falloff, int32_t relaxIterations, float relaxFactor, int32_t seed = 0); + virtual const ChunkInfo& getChunkInfo(int32_t chunkIndex) = 0; /** Get percentage of mesh overlap. @@ -326,110 +270,78 @@ public: \param[in] meshB Mesh B \return mesh overlap percentage */ - static float getMeshOverlap(Mesh& meshA, Mesh& meshB); + virtual float getMeshOverlap(const Mesh& meshA, const Mesh& meshB) = 0; /** Get chunk base mesh \param[in] chunkIndex Chunk index \param[out] output Array of triangles to be filled + \return number of triangles in base mesh */ - void getBaseMesh(int32_t chunkIndex, std::vector<Triangle>& output); - - /** - Get chunk mesh with noise - \param[in] chunkIndex Chunk index - \param[out] output Array of triangles to be filled - */ - void getNoisedMesh(int32_t chunkIndex, std::vector<Triangle>& output); - + virtual uint32_t getBaseMesh(int32_t chunkIndex, Triangle*& output) = 0; /** Return index of chunk with specified chunkId \param[in] chunkId Chunk ID \return Chunk index in internal buffer, if not exist -1 is returned. */ - int32_t getChunkIndex(int32_t chunkId); + virtual int32_t getChunkIndex(int32_t chunkId) = 0; /** Return id of chunk with specified index. \param[in] chunkIndex Chunk index \return Chunk id or -1 if there is no such chunk. */ - int32_t getChunkId(int32_t chunkIndex); + virtual int32_t getChunkId(int32_t chunkIndex) = 0; /** Return depth level of the given chunk \param[in] chunkId Chunk ID \return Chunk depth or -1 if there is no such chunk. */ - int32_t getChunkDepth(int32_t chunkId); + virtual int32_t getChunkDepth(int32_t chunkId) = 0; /** Return array of chunks IDs with given depth. - \param[in] depth Chunk depth - \return Array of chunk IDs + \param[in] depth Chunk depth + \param[out] Pointer to array of chunk IDs + \return Number of chunks in array */ - std::vector<int32_t> getChunksIdAtDepth(uint32_t depth); + virtual uint32_t getChunksIdAtDepth(uint32_t depth, int32_t*& chunkIds) = 0; /** Get result geometry without noise as vertex and index buffers, where index buffers contain series of triplets which represent triangles. \param[out] vertexBuffer Array of vertices to be filled - \param[out] indexBuffer Array of arrays of indices to be filled + \param[out] indexBuffer Array of indices to be filled + \param[out] indexBufferOffsets Array of offsets in indexBuffer for each base mesh. + Contains getChunkCount() + 1 elements. Last one is indexBuffer size + \return Number of vertices in vertexBuffer */ - void getBufferedBaseMeshes(std::vector<Vertex>& vertexBuffer, std::vector<std::vector<uint32_t> >& indexBuffer); - - /** - Get result geometry after tesselation and application of noise as vertex and index buffers, where index buffers contain series of triplets - which represent triangles. - \param[out] vertexBuffer Array of vertices to be filled - \param[out] indexBuffer Array of arrays of indices to be filled - */ - void getBufferedNoiseMeshes(std::vector<Vertex>& vertexBuffer, std::vector<std::vector<uint32_t> >& indexBuffer); + virtual uint32_t getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t*& indexBuffer, uint32_t*& indexBufferOffsets) = 0; /** Set automatic islands removing. May cause instabilities. \param[in] isRemoveIslands Flag whether remove or not islands. */ - void setRemoveIslands(bool isRemoveIslands); + virtual void setRemoveIslands(bool isRemoveIslands) = 0; /** Try find islands and remove them on some specifical chunk. If chunk has childs, island removing can lead to wrong results! Apply it before further chunk splitting. \param[in] chunkId Chunk ID which should be checked for islands \return Number of found islands is returned */ - int32_t islandDetectionAndRemoving(int32_t chunkId); - -private: - void eraseChunk(int32_t chunkId); - bool isAncestorForChunk(int32_t ancestorId, int32_t chunkId); - void deleteAllChildsOfChunk(int32_t chunkId); - int32_t slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd); + virtual int32_t islandDetectionAndRemoving(int32_t chunkId) = 0; -protected: /** - Mesh scaled to unite-cube and translated to the origin + Check if input mesh contains open edges. Open edges can lead to wrong fracturing results. + \return true if mesh contains open edges */ - float mScaleFactor; - physx::PxVec3 mOffset; - - /* Chunk mesh wrappers */ - std::vector<ChunkPostProcessor*> mChunkPostprocessors; - - - - int32_t mPlaneIndexerOffset; - int32_t mChunkIdCounter; - std::vector<ChunkInfo> mChunkData; - - bool mRemoveIslands; - - NvBlastLog mLoggingCallback; + virtual bool isMeshContainOpenEdges(const Mesh* input) = 0; }; } // namespace Blast } // namespace Nv - #endif // ifndef NVBLASTAUTHORINGFRACTURETOOL_H diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringMesh.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringMesh.h index 2b1806a..039da52 100644 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringMesh.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringMesh.h @@ -1,19 +1,35 @@ -/* -* 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 NVBLASTAUTHORINGMESH_H #define NVBLASTAUTHORINGMESH_H #include "NvBlastExtAuthoringTypes.h" -#include <vector> - namespace Nv { @@ -26,147 +42,106 @@ namespace Blast class Mesh { public: + virtual ~Mesh() {} /** - Constructs mesh object from array of triangles. - \param[in] position Array of vertex positions - \param[in] normals Array of vertex normals - \param[in] uv Array of vertex uv coordinates - \param[in] verticesCount Vertices count - \param[in] indices Array of vertex indices. Indices contain vertex index triplets which form a mesh triangle. - \param[in] indicesCount Indices count (should be equal to numberOfTriangles * 3) + Release Mesh memory */ - Mesh(physx::PxVec3* position, physx::PxVec3* normals, physx::PxVec2* uv, uint32_t verticesCount, uint32_t* indices, uint32_t indicesCount); + virtual void release() = 0; /** - Constructs mesh object from array of facets. - \param[in] vertices Array of vertices - \param[in] edges Array of edges - \param[in] facets Array of facets - \param[in] posCount Vertices count - \param[in] edgesCount Edges count - \param[in] facetsCount Facets count + Return true if mesh is valid */ - Mesh(Vertex* vertices, Edge* edges, Facet* facets, uint32_t posCount, uint32_t edgesCount, uint32_t facetsCount); + virtual bool isValid() const = 0; - ~Mesh(); + /** + Return writable pointer on vertices array + */ + virtual Vertex* getVerticesWritable() = 0; /** - Return true if mesh is valid + Return pointer on vertices array + */ + virtual const Vertex* getVertices() const = 0; + + + /** + Return writable pointer on edges array */ - bool isValid(); + virtual Edge* getEdgesWritable() = 0; /** - Return pointer on vertices array + Return pointer on edges array */ - Vertex* getVertices(); + virtual const Edge* getEdges() const = 0; /** - Return pointer on edges array + Return writable pointer on facets array */ - Edge* getEdges(); + virtual Facet* getFacetsBufferWritable() = 0; /** - Return pointer on facets array + Return pointer on facets array */ - Facet* getFacetsBuffer(); + virtual const Facet* getFacetsBuffer() const = 0; /** + Return writable pointer on specified facet + */ + virtual Facet* getFacetWritable(int32_t facet) = 0; + /** Return pointer on specified facet */ - Facet* getFacet(int32_t facet); + virtual const Facet* getFacet(int32_t facet) const = 0; /** Return edges count */ - uint32_t getEdgesCount(); + virtual uint32_t getEdgesCount() const = 0; /** Return vertices count */ - uint32_t getVerticesCount(); + virtual uint32_t getVerticesCount() const = 0; /** Return facet count */ - uint32_t getFacetCount(); + virtual uint32_t getFacetCount() const = 0; /** Return reference on mesh bounding box. */ - physx::PxBounds3& getBoundingBox(); + virtual const physx::PxBounds3& getBoundingBox() const = 0; + + /** + Return writable reference on mesh bounding box. + */ + virtual physx::PxBounds3& getBoundingBoxWritable() = 0; + + + /** + Set per-facet material id. + */ + virtual void setMaterialId(int32_t* materialIds) = 0; + + /** + Set per-facet smoothing group. + */ + virtual void setSmoothingGroup(int32_t* smoothingGroup) = 0; /** Recalculate bounding box */ - void recalculateBoundingBox(); + virtual void recalculateBoundingBox() = 0; /** Compute mesh volume. Can be used only for triangulated meshes. Return mesh volume. If mesh is not triangulated return 0. */ - float getMeshVolume(); - -private: - std::vector<Vertex> mVertices; - std::vector<Edge> mEdges; - std::vector<Facet> mFacets; - physx::PxBounds3 mBounds; + virtual float getMeshVolume() = 0; }; - -/** - Helper functions -*/ - -/** - Set cutting box at some particular position. - \param[in] point Cutting face center - \param[in] normal Cutting face normal - \param[in] mesh Cutting box mesh - \param[in] size Cutting box size - \param[in] id Cutting box ID -*/ -void setCuttingBox(const physx::PxVec3& point, const physx::PxVec3& normal, Mesh* mesh, float size, int32_t id); -/** - Create cutting box at some particular position. - \param[in] point Cutting face center - \param[in] normal Cutting face normal - \param[in] size Cutting box size - \param[in] id Cutting box ID -*/ -Mesh* getCuttingBox(const physx::PxVec3& point, const physx::PxVec3& normal, float size, int32_t id); - -/** - Create box at some particular position. - \param[in] point Cutting face center - \param[in] size Cutting box size -*/ -Mesh* getBigBox(const physx::PxVec3& point, float size); - -/** - Create slicing box with noisy cutting surface. - \param[in] point Cutting face center - \param[in] normal Cutting face normal - \param[in] size Cutting box size - \param[in] jaggedPlaneSize Noisy surface size - \param[in] resolution Noisy surface resolution - \param[in] id Cutting box ID - \param[in] amplitude Noise amplitude - \param[in] frequency Noise frequency - \param[in] octaves Noise octaves - \param[in] seed Random generator seed, used for noise generation. -*/ -Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& normal, float size, float jaggedPlaneSize, uint32_t resolution, int32_t id, float amplitude, float frequency, int32_t octaves, int32_t seed); - - -/** - Inverses normals of cutting box and sets indices. - \param[in] mesh Cutting box mesh - \param[in] id Cutting box ID -*/ -void inverseNormalAndSetIndices(Mesh* mesh, int32_t id); - } // namespace Blast } // namespace Nv diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringMeshCleaner.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringMeshCleaner.h new file mode 100644 index 0000000..b352e80 --- /dev/null +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringMeshCleaner.h @@ -0,0 +1,71 @@ +// 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 NVBLASTEXTAUTHORINGMESHCLEANER_H +#define NVBLASTEXTAUTHORINGMESHCLEANER_H + +#include "NvBlastExtAuthoringTypes.h" + +/** + FractureTool has requirements to input meshes to fracture them successfully: + 1) Mesh should be closed (watertight) + 2) There should not be self-intersections and open-edges. +*/ + +/** + Mesh cleaner input is closed mesh with self-intersections and open-edges (only in the interior). + It tries to track outer hull to make input mesh solid and meet requierements of FractureTool. If mesh contained some internal cavities they will be removed. +*/ + +namespace Nv +{ +namespace Blast +{ + +class Mesh; + +class MeshCleaner +{ +public: + virtual ~MeshCleaner() {} + + /** + Tries to remove self intersections and open edges in interior of mesh. + \param[in] mesh Mesh to be cleaned. + \return Cleaned mesh or nullptr if failed. + */ + virtual Mesh* cleanMesh(const Mesh* mesh) = 0; + + virtual void release() = 0; +}; + + +} // namespace Blast +} // namespace Nv + +#endif // ifndef NVBLASTEXTAUTHORINGMESHCLEANER_H
\ No newline at end of file diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringTypes.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringTypes.h index de28866..13865f7 100644 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringTypes.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringTypes.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 NVBLASTAUTHORINGTYPES_H #define NVBLASTAUTHORINGTYPES_H @@ -14,7 +32,6 @@ #include <PxVec3.h> #include <PxVec2.h> #include <PxBounds3.h> -#include <algorithm> #include "NvBlastTypes.h" #define NOT_VALID_VERTEX INT32_MAX @@ -51,6 +68,13 @@ struct Vertex physx::PxVec2 uv[1]; // UV-coordinates array, currently supported only one UV coordinate. }; + +// Interior material ID +#define MATERIAL_INTERIOR 1000 +#define SMOOTHING_GROUP_INTERIOR 1000 + + + /** Mesh triangle representation */ @@ -59,7 +83,9 @@ struct Triangle Triangle() {}; Triangle(Vertex a, Vertex b, Vertex c) : a(a), b(b), c(c) {}; Vertex a, b, c; - int32_t userInfo; + int32_t userData; + int32_t materialId; + int32_t smoothingGroup; // NOT SUPPORTED ATM. physx::PxVec3 getNormal() { return ((b.p - a.p).cross(c.p - a.p)); @@ -91,10 +117,28 @@ struct TriangleIndexed return (a == ea || a == eb || a == ec) && (b == ea || b == eb || b == ec); } + Triangle convertToTriangle(Vertex* vertices) + { + Triangle tr; + tr.a = vertices[ea]; + tr.b = vertices[eb]; + tr.c = vertices[ec]; + + tr.userData = userData; + tr.materialId = materialId; + tr.smoothingGroup = smoothingGroup; + return tr; + } + uint32_t ea, eb, ec; - int32_t userInfo; + int32_t materialId; + int32_t smoothingGroup; + int32_t userData; }; + + + /** Mesh facet representation */ @@ -103,11 +147,14 @@ struct Facet int32_t firstEdgeNumber; uint32_t edgesCount; int32_t userData; - Facet(int32_t fEdge = 0, uint32_t eCount = 0, int32_t userData = 0) : firstEdgeNumber(fEdge), edgesCount(eCount), userData(userData) {} + int32_t materialId; + int32_t smoothingGroup; + + Facet(int32_t fEdge = 0, uint32_t eCount = 0, int32_t materialId = 0, int32_t userData = 0, int32_t smoothingGroup = 0) : firstEdgeNumber(fEdge), edgesCount(eCount), materialId(materialId), userData(userData), smoothingGroup(smoothingGroup) {} }; /** -Abstract base class for user-defined random value generator. + Abstract base class for user-defined random value generator. */ class RandomGeneratorBase { @@ -119,6 +166,110 @@ public: virtual ~RandomGeneratorBase() {}; }; +/** + Collision hull geometry format. +*/ +struct CollisionHull +{ + /** + Collision hull polygon format. + */ + struct HullPolygon + { + // Polygon base plane + float mPlane[4]; + // Number vertices in polygon + uint16_t mNbVerts; + // First index in CollisionHull.indices array for this polygon + uint16_t mIndexBase; + }; + ///** + + uint32_t pointsCount; + uint32_t indicesCount; + uint32_t polygonDataCount; + physx::PxVec3* points; + uint32_t* indices; + HullPolygon* polygonData; + + virtual ~CollisionHull() {} + + virtual void release() = 0; +}; + +/** + Authoring results. Which contains NvBlastAsset, render and collision meshes +*/ +struct AuthoringResult +{ + uint32_t chunkCount; //Number of chunks in Blast asset + + uint32_t bondCount; //Number of bonds in Blast asset + + NvBlastAsset* asset; //Blast asset + + /** + assetToFractureChunkIdMap used for getting internal FractureChunkId with FractureTool::getChunkId. + FractureChunkId = FractureTool.getChunkId(aResult.assetToFractureChunkIdMap(AssetChunkId); + */ + uint32_t* assetToFractureChunkIdMap; + + /** + Offsets for render mesh geometry. Contains chunkCount + 1 element. + First triangle for i-th chunk: aResult.geometry[aResult.geometryOffset[i]] + aResult.geometryOffset[chunkCount+1] is total number of triangles in geometry + */ + uint32_t* geometryOffset; + + Triangle* geometry; //Raw array of Triangle for all chunks + + NvBlastChunkDesc* chunkDescs; //Array of chunk descriptors. Contains chunkCount elements + + NvBlastBondDesc* bondDescs; //Array of bond descriptors. Contains bondCount elements + + /** + Collision hull offsets. Contains chunkCount + 1 element. + First collision hull for i-th chunk: aResult.collisionHull[aResult.collisionHullOffset[i]] + aResult.collisionHullOffset[chunkCount+1] is total number of collision hulls in collisionHull + */ + uint32_t* collisionHullOffset; + + CollisionHull** collisionHull; //Raw array of pointers to collision hull for all chunks. + + /** + Array of chunk physics parameters. Contains chunkCount elements + */ + struct ExtPxChunk* physicsChunks; + + /** + Array of phisics subchunks (convex mesh) descriptors. + Use collisionHullOffset for accessing elements. + */ + struct ExtPxSubchunk* physicsSubchunks; + + /** + Array of material names. + */ + char** materialNames; + /** + Size of array of material names. + */ + + uint32_t materialCount; + + //// Member functions //// + virtual ~AuthoringResult() {} + + /** + Free collision hulls data + */ + virtual void releaseCollisionHulls() = 0; + + /** + Free all data and AuthoringResult + */ + virtual void release() = 0; +}; } // namespace Blast diff --git a/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp b/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp index 73c59b8..7306b57 100644 --- a/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.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 "NvBlastExtApexSharedParts.h" @@ -906,14 +924,14 @@ static void _arrayVec3ToVec4(const PxVec3* src, const Vec3V& scale, Vec4V* dst, } -bool importerHullsInProximityApexFree(const std::vector<PxVec3>& hull0, PxBounds3& hull0Bounds, const physx::PxTransform& localToWorldRT0In, const physx::PxVec3& scale0In, - const std::vector<PxVec3>& hull1, PxBounds3& hull1Bounds, const physx::PxTransform& localToWorldRT1In, const physx::PxVec3& scale1In, +bool importerHullsInProximityApexFree(uint32_t hull0Count, const PxVec3* hull0, PxBounds3& hull0Bounds, const physx::PxTransform& localToWorldRT0In, const physx::PxVec3& scale0In, + uint32_t hull1Count, const PxVec3* hull1, PxBounds3& hull1Bounds, const physx::PxTransform& localToWorldRT1In, const physx::PxVec3& scale1In, physx::PxF32 maxDistance, Separation* separation) { - const PxU32 numVerts0 = static_cast<PxU32>(hull0.size()); - const PxU32 numVerts1 = static_cast<PxU32>(hull1.size()); + const PxU32 numVerts0 = static_cast<PxU32>(hull0Count); + const PxU32 numVerts1 = static_cast<PxU32>(hull1Count); const PxU32 numAov0 = (numVerts0 + 3) >> 2; const PxU32 numAov1 = (numVerts1 + 3) >> 2; Vec4V* verts0 = (Vec4V*)alloca((numAov0 + numAov1) * sizeof(Vec4V) * 3); @@ -936,8 +954,8 @@ bool importerHullsInProximityApexFree(const std::vector<PxVec3>& hull0, PxBounds vert1[i] = hull1[i]; } - _arrayVec3ToVec4(&vert0[0], scale0, verts0, numVerts0); - _arrayVec3ToVec4(&vert1[0], scale1, verts1, numVerts1); + _arrayVec3ToVec4(vert0.data(), scale0, verts0, numVerts0); + _arrayVec3ToVec4(vert1.data(), scale1, verts1, numVerts1); const PxTransform trans1To0 = localToWorldRT0In.transformInv(localToWorldRT1In); diff --git a/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.h b/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.h index 68e0412..5d1f990 100644 --- a/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.h +++ b/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.h @@ -1,18 +1,35 @@ -/* -* 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 NVBLASTEXTAPEXSHAREDPARTS_H #define NVBLASTEXTAPEXSHAREDPARTS_H #include "NvBlast.h" -#include <vector> #include <PxPlane.h> namespace physx { @@ -40,9 +57,9 @@ struct Separation /** Function to compute midplane between two convex hulls. Is copied from APEX. */ -bool importerHullsInProximityApexFree(const std::vector<physx::PxVec3>& hull0, physx::PxBounds3& hull0Bounds, const physx::PxTransform& localToWorldRT0In, const physx::PxVec3& scale0In, - const std::vector<physx::PxVec3>& hull1, physx::PxBounds3& hull1Bounds, const physx::PxTransform& localToWorldRT1In, const physx::PxVec3& scale1In, - physx::PxF32 maxDistance, Separation* separation); +bool importerHullsInProximityApexFree( uint32_t hull0Count, const physx::PxVec3* hull0, physx::PxBounds3& hull0Bounds, const physx::PxTransform& localToWorldRT0In, const physx::PxVec3& scale0In, + uint32_t hull1Count, const physx::PxVec3* hull1, physx::PxBounds3& hull1Bounds, const physx::PxTransform& localToWorldRT1In, const physx::PxVec3& scale1In, + physx::PxF32 maxDistance, Separation* separation); } // namespace Blast } // namespace Nv diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp new file mode 100644 index 0000000..95a7bee --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp @@ -0,0 +1,262 @@ +/* +* 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 "NvBlastExtAuthoring.h" +#include "NvBlastExtAuthoringMeshImpl.h" +#include "NvBlastExtAuthoringMeshCleanerImpl.h" +#include "NvBlastExtAuthoringFractureToolImpl.h" +#include "NvBlastExtAuthoringCollisionBuilderImpl.h" +#include "NvBlastExtAuthoringBondGeneratorImpl.h" +#include "NvBlastTypes.h" +#include "NvBlastIndexFns.h" +#include "NvBlast.h" +#include "NvBlastGlobals.h" +#include "NvBlastExtPxAsset.h" + +#include <algorithm> +#include <memory> + +using namespace Nv::Blast; +using namespace physx; + +#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? new T[x] : nullptr; +#define SAFE_ARRAY_DELETE(x) if (x != nullptr) {delete[] x; x = nullptr;} + +Mesh* NvBlastExtAuthoringCreateMesh(const PxVec3* position, const PxVec3* normals, const PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount) +{ + return new MeshImpl(position, normals, uv, verticesCount, indices, indicesCount); +} + +MeshCleaner* NvBlastExtAuthoringCreateMeshCleaner() +{ + return new MeshCleanerImpl; +} + +VoronoiSitesGenerator* NvBlastExtAuthoringCreateVoronoiSitesGenerator(Mesh* mesh, RandomGeneratorBase* rng) +{ + return new VoronoiSitesGeneratorImpl(mesh, rng); +} + +FractureTool* NvBlastExtAuthoringCreateFractureTool() +{ + return new FractureToolImpl; +} + +BlastBondGenerator* NvBlastExtAuthoringCreateBondGenerator(PxCooking* cooking, PxPhysicsInsertionCallback* insertionCallback) +{ + return new BlastBondGeneratorImpl(cooking, insertionCallback); +} + +ConvexMeshBuilder* NvBlastExtAuthoringCreateConvexMeshBuilder(PxCooking* cooking, PxPhysicsInsertionCallback* insertionCallback) +{ + return new ConvexMeshBuilderImpl(cooking, insertionCallback); +} + +void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& result) +{ + uint32_t chunkCount = (uint32_t)result.chunkCount; + result.collisionHullOffset = SAFE_ARRAY_NEW(uint32_t, chunkCount + 1); + result.collisionHullOffset[0] = 0; + result.collisionHull = SAFE_ARRAY_NEW(CollisionHull*, chunkCount); + result.physicsSubchunks = SAFE_ARRAY_NEW(ExtPxSubchunk, chunkCount); + result.physicsChunks = SAFE_ARRAY_NEW(ExtPxChunk, chunkCount); + for (uint32_t i = 0; i < chunkCount; ++i) + { + std::vector<physx::PxVec3> vertices; + for (uint32_t p = result.geometryOffset[i]; p < result.geometryOffset[i+1]; ++p) + { + Nv::Blast::Triangle& tri = result.geometry[p]; + vertices.push_back(tri.a.p); + vertices.push_back(tri.b.p); + vertices.push_back(tri.c.p); + } + + result.collisionHullOffset[i + 1] = result.collisionHullOffset[i] + 1; + result.collisionHull[i] = collisionBuilder.buildCollisionGeometry((uint32_t)vertices.size(), vertices.data()); + result.physicsSubchunks[i].transform = physx::PxTransform(physx::PxIdentity); + result.physicsSubchunks[i].geometry = physx::PxConvexMeshGeometry(collisionBuilder.buildConvexMesh(*result.collisionHull[i])); + + result.physicsChunks[i].isStatic = false; + result.physicsChunks[i].subchunkCount = 1; + result.physicsChunks[i].firstSubchunkIndex = i; + //outPhysicsChunks.get()[i].subchunks = &outPhysicsSubchunks[i]; + } +} + + +struct AuthoringResultImpl : public AuthoringResult +{ + void releaseCollisionHulls() override + { + if (collisionHull != nullptr) + { + for (uint32_t ch = 0; ch < collisionHullOffset[chunkCount]; ch++) + { + collisionHull[ch]->release(); + } + SAFE_ARRAY_DELETE(collisionHullOffset); + SAFE_ARRAY_DELETE(collisionHull); + } + } + + void release() override + { + releaseCollisionHulls(); + NVBLAST_FREE(asset); + SAFE_ARRAY_DELETE(assetToFractureChunkIdMap); + SAFE_ARRAY_DELETE(geometryOffset); + SAFE_ARRAY_DELETE(geometry); + SAFE_ARRAY_DELETE(chunkDescs); + SAFE_ARRAY_DELETE(bondDescs); + SAFE_ARRAY_DELETE(physicsChunks); + SAFE_ARRAY_DELETE(physicsSubchunks); + delete this; + } +}; + +AuthoringResult* NvBlastExtAuthoringProcessFracture(FractureTool& fTool, BlastBondGenerator& bondGenerator, ConvexMeshBuilder& collisionBuilder, int32_t defaultSupportDepth) +{ + fTool.finalizeFracturing(); + const uint32_t chunkCount = fTool.getChunkCount(); + if (chunkCount == 0) + { + return nullptr; + } + AuthoringResultImpl* ret = new AuthoringResultImpl; + if (ret == nullptr) + { + return nullptr; + } + AuthoringResult& aResult = *ret; + aResult.chunkCount = chunkCount; + + std::shared_ptr<bool> isSupport(new bool[chunkCount], [](bool* b) {delete[] b; }); + memset(isSupport.get(), 0, sizeof(bool) * chunkCount); + for (uint32_t i = 0; i < fTool.getChunkCount(); ++i) + { + if (defaultSupportDepth < 0 || fTool.getChunkDepth(fTool.getChunkId(i)) < defaultSupportDepth) + { + isSupport.get()[i] = fTool.getChunkInfo(i).isLeaf; + } + else if (fTool.getChunkDepth(fTool.getChunkId(i)) == defaultSupportDepth) + { + isSupport.get()[i] = true; + } + } + + BondGenerationConfig cnf; + cnf.bondMode = BondGenerationConfig::EXACT; + + //NvBlastChunkDesc>& chunkDescs = aResult.chunkDescs; + //std::shared_ptr<NvBlastBondDesc>& bondDescs = aResult.bondDescs; + const uint32_t bondCount = bondGenerator.buildDescFromInternalFracture(&fTool, isSupport.get(), aResult.bondDescs, aResult.chunkDescs); + aResult.bondCount = bondCount; + if (bondCount == 0) + { + aResult.bondDescs = nullptr; + } + + // order chunks, build map + std::vector<uint32_t> chunkReorderInvMap; + { + std::vector<uint32_t> chunkReorderMap(chunkCount); + std::vector<char> scratch(chunkCount * sizeof(NvBlastChunkDesc)); + NvBlastEnsureAssetExactSupportCoverage(aResult.chunkDescs, chunkCount, scratch.data(), logLL); + NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), aResult.chunkDescs, chunkCount, scratch.data(), logLL); + NvBlastApplyAssetDescChunkReorderMapInPlace(aResult.chunkDescs, chunkCount, aResult.bondDescs, bondCount, chunkReorderMap.data(), true, scratch.data(), logLL); + chunkReorderInvMap.resize(chunkReorderMap.size()); + Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(), static_cast<unsigned int>(chunkReorderMap.size())); + } + + // get result geometry + aResult.geometryOffset = SAFE_ARRAY_NEW(uint32_t, chunkCount + 1); + aResult.assetToFractureChunkIdMap = SAFE_ARRAY_NEW(uint32_t, chunkCount + 1); + aResult.geometryOffset[0] = 0; + std::vector<Nv::Blast::Triangle*> chunkGeometry(chunkCount); + for (uint32_t i = 0; i < chunkCount; ++i) + { + uint32_t chunkIndex = chunkReorderInvMap[i]; + aResult.geometryOffset[i+1] = aResult.geometryOffset[i] + fTool.getBaseMesh(chunkIndex, chunkGeometry[i]); + aResult.assetToFractureChunkIdMap[i] = chunkIndex; + } + aResult.geometry = SAFE_ARRAY_NEW(Triangle, aResult.geometryOffset[chunkCount]); + for (uint32_t i = 0; i < chunkCount; ++i) + { + uint32_t trianglesCount = aResult.geometryOffset[i + 1] - aResult.geometryOffset[i]; + memcpy(aResult.geometry + aResult.geometryOffset[i], chunkGeometry[i], trianglesCount * sizeof(Nv::Blast::Triangle)); + } + + float maxX = INT32_MIN; + float maxY = INT32_MIN; + float maxZ = INT32_MIN; + + float minX = INT32_MAX; + float minY = INT32_MAX; + float minZ = INT32_MAX; + + for (uint32_t i = 0; i < bondCount; i++) + { + NvBlastBondDesc& bondDesc = aResult.bondDescs[i]; + + minX = std::min(minX, bondDesc.bond.centroid[0]); + maxX = std::max(maxX, bondDesc.bond.centroid[0]); + + minY = std::min(minY, bondDesc.bond.centroid[1]); + maxY = std::max(maxY, bondDesc.bond.centroid[1]); + + minZ = std::min(minZ, bondDesc.bond.centroid[2]); + maxZ = std::max(maxZ, bondDesc.bond.centroid[2]); + } + + //std::cout << "Bond bounds: " << std::endl; + //std::cout << "MIN: " << minX << ", " << minY << ", " << minZ << std::endl; + //std::cout << "MAX: " << maxX << ", " << maxY << ", " << maxZ << std::endl; + + // prepare physics data (convexes) + buildPhysicsChunks(collisionBuilder, aResult); + + // set NvBlastChunk volume from Px geometry + for (uint32_t i = 0; i < chunkCount; i++) + { + float totalVolume = 0.f; + for (uint32_t k = 0; k < aResult.physicsChunks[i].subchunkCount; k++) + { + const auto& subChunk = aResult.physicsSubchunks[aResult.physicsChunks[i].firstSubchunkIndex + k]; + physx::PxVec3 localCenterOfMass; physx::PxMat33 intertia; float mass; + subChunk.geometry.convexMesh->getMassInformation(mass, intertia, localCenterOfMass); + const physx::PxVec3 scale = subChunk.geometry.scale.scale; + mass *= scale.x * scale.y * scale.z; + totalVolume += mass / 1.0f; // unit density + } + + aResult.chunkDescs[i].volume = totalVolume; + } + + // build and serialize ExtPhysicsAsset + NvBlastAssetDesc descriptor; + descriptor.bondCount = bondCount; + descriptor.bondDescs = aResult.bondDescs; + descriptor.chunkCount = chunkCount; + descriptor.chunkDescs = aResult.chunkDescs; + + std::vector<uint8_t> scratch(static_cast<unsigned int>(NvBlastGetRequiredScratchForCreateAsset(&descriptor, logLL))); + void* mem = NVBLAST_ALLOC(NvBlastGetAssetMemorySize(&descriptor, logLL)); + aResult.asset = NvBlastCreateAsset(mem, &descriptor, scratch.data(), logLL); + + //aResult.asset = std::shared_ptr<NvBlastAsset>(asset, [=](NvBlastAsset* asset) + //{ + // NVBLAST_FREE(asset); + //}); + + //std::cout << "Done" << std::endl; + ret->materialCount = 0; + ret->materialNames = nullptr; + return ret; +}
\ No newline at end of file diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.cpp index 075bce9..40ddec1 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.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 "NvBlastExtAuthoringAccelerator.h" #include "NvBlastExtAuthoringMesh.h" @@ -25,16 +43,16 @@ DummyAccelerator::DummyAccelerator(int32_t count) :count(count) { current = 0; } -void DummyAccelerator::setState(Vertex* pos, Edge* ed, Facet& fc) +void DummyAccelerator::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { current = 0; - (void)pos; - (void)ed; - (void)fc; + NV_UNUSED(pos); + NV_UNUSED(ed); + NV_UNUSED(fc); } void DummyAccelerator::setState(const physx::PxVec3& point) { current = 0; - (void)point; + NV_UNUSED(point); } int32_t DummyAccelerator::getNextFacet() { @@ -49,7 +67,7 @@ int32_t DummyAccelerator::getNextFacet() -BBoxBasedAccelerator::BBoxBasedAccelerator(Mesh* mesh, int32_t resolution) : mResolution(resolution), alreadyGotValue(1) +BBoxBasedAccelerator::BBoxBasedAccelerator(const Mesh* mesh, int32_t resolution) : mResolution(resolution), alreadyGotValue(1) { mBounds = mesh->getBoundingBox(); mSpatialMap.resize(resolution * resolution * resolution); @@ -124,14 +142,14 @@ int32_t BBoxBasedAccelerator::getNextFacet() } return facetId; } -void BBoxBasedAccelerator::setState(Vertex* pos, Edge* ed, Facet& fc) +void BBoxBasedAccelerator::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { alreadyGotValue++; mIteratorCell = -1; mIteratorFacet = -1; cellList.clear(); facetBox.setEmpty(); - Edge* edge = ed + fc.firstEdgeNumber; + const Edge* edge = ed + fc.firstEdgeNumber; uint32_t count = fc.edgesCount; for (uint32_t ec = 0; ec < count; ++ec) { @@ -195,13 +213,13 @@ bool BBoxBasedAccelerator::testCellPolygonIntersection(int32_t cellId, PxBounds3 return false; } -void BBoxBasedAccelerator::buildAccelStructure(Vertex* pos, Edge* edges, Facet* fc, int32_t facetCount) +void BBoxBasedAccelerator::buildAccelStructure(const Vertex* pos, const Edge* edges, const Facet* fc, int32_t facetCount) { for (int32_t facet = 0; facet < facetCount; ++facet) { PxBounds3 bBox; bBox.setEmpty(); - Edge* edge = &edges[0] + fc->firstEdgeNumber; + const Edge* edge = &edges[0] + fc->firstEdgeNumber; int32_t count = fc->edgesCount; for (int32_t ec = 0; ec < count; ++ec) { @@ -349,15 +367,15 @@ enum TrivialFlags -int32_t testFacetUnitCubeIntersection(Vertex* vertices, Edge* edges, Facet& fc, PxBounds3 cube, float fattening) +int32_t testFacetUnitCubeIntersection(const Vertex* vertices, const Edge* edges, const Facet& fc, PxBounds3 cube, float fattening) { - Edge* ed = edges + fc.firstEdgeNumber; + const Edge* ed = edges + fc.firstEdgeNumber; int32_t trivialFlags = ALL_ONE; cube.fattenFast(fattening); for (uint32_t i = 0; i < fc.edgesCount; ++i) { { - PxVec3& p = vertices[ed->s].p; + const PxVec3& p = vertices[ed->s].p; if (cube.contains(p)) return 1; if (p.x < cube.getCenter().x + 0.5) @@ -376,7 +394,7 @@ int32_t testFacetUnitCubeIntersection(Vertex* vertices, Edge* edges, Facet& fc, trivialFlags &= HAS_POINT_ABOVE_LOW_Z; } { - PxVec3& p = vertices[ed->e].p; + const PxVec3& p = vertices[ed->e].p; if (cube.contains(p)) return 1; if (p.x < cube.getCenter().x + 0.5) @@ -411,9 +429,9 @@ int32_t testFacetUnitCubeIntersection(Vertex* vertices, Edge* edges, Facet& fc, /** Compute normal */ - PxVec3& v1 = vertices[ed->s].p; - PxVec3* v2 = nullptr; - PxVec3* v3 = nullptr; + const PxVec3& v1 = vertices[ed->s].p; + const PxVec3* v2 = nullptr; + const PxVec3* v3 = nullptr; for (uint32_t i = 0; i < fc.edgesCount; ++i) { @@ -476,7 +494,7 @@ int32_t testFacetUnitCubeIntersection(Vertex* vertices, Edge* edges, Facet& fc, } -IntersectionTestingAccelerator::IntersectionTestingAccelerator(Mesh* in, int32_t resolution) +IntersectionTestingAccelerator::IntersectionTestingAccelerator(const Mesh* in, int32_t resolution) { @@ -563,7 +581,7 @@ int32_t IntersectionTestingAccelerator::getNextFacet() return facetId; } -void IntersectionTestingAccelerator::setState(Vertex* pos, Edge* ed, Facet& fc) +void IntersectionTestingAccelerator::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { alreadyGotValue++; mIteratorCell = -1; diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.h index 8284cd7..909dc86 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.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 NVBLASTEXTAUTHORINGACCELERATOR_H #define NVBLASTEXTAUTHORINGACCELERATOR_H @@ -36,7 +54,7 @@ public: \param[in] ed Edge buffer \param[in] fc Facet which should be tested. */ - virtual void setState(Vertex* pos, Edge* ed, Facet& fc) = 0; + virtual void setState(const Vertex* pos, const Edge* ed, const Facet& fc) = 0; /** Set state of accelerator to return all facets which possibly can cover given point. Needed for testing whether point is inside mesh. \param[in] point Point which should be tested. @@ -62,7 +80,7 @@ public: \param[in] count Mesh facets count for which accelerator should be built. */ DummyAccelerator(int32_t count); - virtual void setState(Vertex* pos, Edge* ed, Facet& fc); + virtual void setState(const Vertex* pos, const Edge* ed, const Facet& fc); virtual void setState(const physx::PxVec3& point); virtual int32_t getNextFacet(); @@ -83,15 +101,15 @@ public: \param[in] mesh Mesh for which acceleration structure should be built. \param[in] resolution Resolution on 3d grid. */ - BBoxBasedAccelerator(Mesh* mesh, int32_t resolution); + BBoxBasedAccelerator(const Mesh* mesh, int32_t resolution); virtual ~BBoxBasedAccelerator(); int32_t getNextFacet(); - void setState(Vertex* pos, Edge* ed, Facet& fc); + void setState(const Vertex* pos, const Edge* ed, const Facet& fc); void setState(const physx::PxVec3& p); private: bool testCellPolygonIntersection(int32_t cellId, physx::PxBounds3& facetBB); - void buildAccelStructure(Vertex* pos, Edge* edges, Facet* fc, int32_t facetCount); + void buildAccelStructure(const Vertex* pos, const Edge* edges, const Facet* fc, int32_t facetCount); int32_t mResolution; physx::PxBounds3 mBounds; @@ -121,9 +139,9 @@ private: class IntersectionTestingAccelerator : public SpatialAccelerator { public: - IntersectionTestingAccelerator(Mesh* mesh, int32_t resolution); + IntersectionTestingAccelerator(const Mesh* mesh, int32_t resolution); int32_t getNextFacet(); - void setState(Vertex* pos, Edge* ed, Facet& fc); + void setState(const Vertex* pos, const Edge* ed, const Facet& fc); void setState(const physx::PxVec3& p); diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGenerator.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp index b2c3883..a4a2ce7 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGenerator.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + // This warning arises when using some stl containers with older versions of VC // c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1826): warning C4702: unreachable code @@ -15,22 +33,25 @@ #pragma warning(disable : 4702) #endif -#include <NvBlastExtAuthoringBondGenerator.h> -#include <NvBlastTypes.h> +#include <NvBlastExtAuthoringBondGeneratorImpl.h> #include <NvBlast.h> #include "NvBlastExtTriangleProcessor.h" #include "NvBlastExtApexSharedParts.h" -#include "NvBlastExtAuthoringCollisionBuilder.h" +#include "NvBlastExtAuthoringCollisionBuilderImpl.h" #include "NvBlastExtAuthoringInternalCommon.h" +#include "NvBlastExtAuthoringTypes.h" #include <vector> #include <map> #include <PxPlane.h> #include <algorithm> #include <cmath> +#include <memory> using physx::PxVec3; using physx::PxBounds3; +#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? new T[x] : nullptr; + //#define DEBUG_OUTPUT #ifdef DEBUG_OUTPUT @@ -125,8 +146,7 @@ namespace Nv int32_t m_chunkId; }; - - float BlastBondGenerator::processWithMidplanes(TriangleProcessor* trProcessor, const std::vector<PxVec3>& chunk1Points, const std::vector<PxVec3>& chunk2Points, + float BlastBondGeneratorImpl::processWithMidplanes(TriangleProcessor* trProcessor, const std::vector<PxVec3>& chunk1Points, const std::vector<PxVec3>& chunk2Points, const std::vector<PxVec3>& hull1p, const std::vector<PxVec3>& hull2p, PxVec3& normal, PxVec3& centroid) { PxBounds3 bounds; @@ -163,7 +183,7 @@ namespace Nv chunk2Centroid *= (1.0f / chunk2Points.size()); Separation separation; - if (!importerHullsInProximityApexFree(hull1p, aBounds, PxTransform(PxIdentity), PxVec3(1, 1, 1), hull2p, bBounds, PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.000, &separation)) + if (!importerHullsInProximityApexFree(hull1p.size(), hull1p.data(), aBounds, PxTransform(PxIdentity), PxVec3(1, 1, 1), hull2p.size(), hull2p.data(), bBounds, PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.000, &separation)) { return 0.0; } @@ -221,53 +241,39 @@ namespace Nv return area * 0.5f; } - - int32_t BlastBondGenerator::bondsFromPrefractured(const std::vector<std::vector<Triangle>>& geometry, const std::vector<bool>& chunkIsSupport, std::vector<NvBlastBondDesc>& resultBondDescs, BondGenerationConfig conf) - { - int32_t ret_val = 0; - switch (conf.bondMode) - { - case BondGenerationConfig::AVERAGE: - ret_val = createFullBondListAveraged(geometry, chunkIsSupport, resultBondDescs, conf); - break; - case BondGenerationConfig::EXACT: - ret_val = createFullBondListExact(geometry, chunkIsSupport, resultBondDescs, conf); - break; - } - return ret_val; - } - - int32_t BlastBondGenerator::createFullBondListAveraged(const std::vector<std::vector<Triangle>>& chunksGeometry, const std::vector<bool>& supportFlags, std::vector<NvBlastBondDesc>& mResultBondDescs, BondGenerationConfig conf) + int32_t BlastBondGeneratorImpl::createFullBondListAveraged(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + const bool* supportFlags, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf) { NV_UNUSED(conf); - std::vector<std::vector<PxVec3> > chunksPoints(chunksGeometry.size()); + std::vector<std::vector<PxVec3> > chunksPoints(meshCount); - for (uint32_t i = 0; i < chunksGeometry.size(); ++i) + for (uint32_t i = 0; i < meshCount; ++i) { if (!supportFlags[i]) { continue; } - for (uint32_t j = 0; j < chunksGeometry[i].size(); ++j) + uint32_t count = geometryOffset[i + 1] - geometryOffset[i]; + for (uint32_t j = 0; j < count; ++j) { - chunksPoints[i].push_back(chunksGeometry[i][j].a.p); - chunksPoints[i].push_back(chunksGeometry[i][j].b.p); - chunksPoints[i].push_back(chunksGeometry[i][j].c.p); + chunksPoints[i].push_back(geometry[geometryOffset[i] + j].a.p); + chunksPoints[i].push_back(geometry[geometryOffset[i] + j].b.p); + chunksPoints[i].push_back(geometry[geometryOffset[i] + j].c.p); } } - Nv::Blast::ConvexMeshBuilder builder(mPxCooking, mPxInsertionCallback); + Nv::Blast::ConvexMeshBuilderImpl builder(mPxCooking, mPxInsertionCallback); - std::vector<CollisionHull> cHulls(chunksGeometry.size()); + std::vector<CollisionHull*> cHulls(meshCount); - for (uint32_t i = 0; i < chunksGeometry.size(); ++i) + for (uint32_t i = 0; i < meshCount; ++i) { if (!supportFlags[i]) { continue; } - builder.buildCollisionGeometry(chunksPoints[i], cHulls[i]); + cHulls[i] = builder.buildCollisionGeometry(chunksPoints[i].size(), chunksPoints[i].data()); } std::vector<std::vector<PxVec3> > hullPoints(cHulls.size()); @@ -279,24 +285,23 @@ namespace Nv continue; } - hullPoints[chunk].resize(cHulls[chunk].points.size()); - for (uint32_t i = 0; i < cHulls[chunk].points.size(); ++i) + hullPoints[chunk].resize(cHulls[chunk]->pointsCount); + for (uint32_t i = 0; i < cHulls[chunk]->pointsCount; ++i) { - hullPoints[chunk][i].x = cHulls[chunk].points[i].x; - hullPoints[chunk][i].y = cHulls[chunk].points[i].y; - hullPoints[chunk][i].z = cHulls[chunk].points[i].z; + hullPoints[chunk][i] = cHulls[chunk]->points[i]; } + cHulls[chunk]->release(); } TriangleProcessor trProcessor; - - for (uint32_t i = 0; i < chunksGeometry.size(); ++i) + std::vector<NvBlastBondDesc> mResultBondDescs; + for (uint32_t i = 0; i < meshCount; ++i) { if (!supportFlags[i]) { continue; } - for (uint32_t j = i + 1; j < chunksGeometry.size(); ++j) + for (uint32_t j = i + 1; j < meshCount; ++j) { if (!supportFlags[i]) { @@ -327,8 +332,9 @@ namespace Nv } } - - return 0; + resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size()); + memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc)*mResultBondDescs.size()); + return mResultBondDescs.size(); } uint32_t isSamePlane(PxPlane& a, PxPlane& b) @@ -340,39 +346,48 @@ namespace Nv return 1; } - int32_t BlastBondGenerator::createFullBondListExact(const std::vector<std::vector<Triangle>>& chunksGeometry, const std::vector<bool>& supportFlags, std::vector<NvBlastBondDesc>& mResultBondDescs, BondGenerationConfig conf) + int32_t BlastBondGeneratorImpl::createFullBondListExact(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + const bool* supportFlags, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf) { std::vector < PlaneChunkIndexer > planeTriangleMapping; NV_UNUSED(conf); - for (uint32_t i = 0; i < chunksGeometry.size(); ++i) + for (uint32_t i = 0; i < meshCount; ++i) { if (!supportFlags[i]) { continue; } - for (uint32_t j = 0; j < chunksGeometry[i].size(); ++j) + uint32_t count = geometryOffset[i + 1] - geometryOffset[i]; + for (uint32_t j = 0; j < count; ++j) { #ifdef DEBUG_OUTPUT - meshBuffer.push_back(chunksGeometry[i][j].a.p ); - meshBuffer.push_back(chunksGeometry[i][j].b.p); - meshBuffer.push_back(chunksGeometry[i][j].c.p ); + meshBuffer.push_back(geometry[geometryOffset[i] + j].a.p ); + meshBuffer.push_back(geometry[geometryOffset[i] + j].b.p); + meshBuffer.push_back(geometry[geometryOffset[i] + j].c.p ); #endif - PxPlane nPlane = PxPlane(chunksGeometry[i][j].a.p, chunksGeometry[i][j].b.p, chunksGeometry[i][j].c.p); + PxPlane nPlane = PxPlane(geometry[geometryOffset[i] + j].a.p, geometry[geometryOffset[i] + j].b.p, geometry[geometryOffset[i] + j].c.p); planeTriangleMapping.push_back(PlaneChunkIndexer(i, j, nPlane)); } } std::sort(planeTriangleMapping.begin(), planeTriangleMapping.end(), planeComparer); - return createFullBondListExactInternal(chunksGeometry, planeTriangleMapping, mResultBondDescs); + return createFullBondListExactInternal(meshCount, geometryOffset, geometry, planeTriangleMapping, resultBondDescs); } - void BlastBondGenerator::buildGeometryCache(const std::vector<std::vector<Triangle> >& geometry) + void BlastBondGeneratorImpl::buildGeometryCache(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry) { - mGeometryCache = geometry; - mHullsPointsCache.resize(geometry.size()); - mBoundsCache.resize(geometry.size()); - mCHullCache.resize(geometry.size()); + uint32_t geometryCount = geometryOffset[meshCount]; + for (uint32_t i = 0; i < meshCount; i++) + { + mGeometryCache.push_back(std::vector<Triangle>()); + uint32_t count = geometryOffset[i + 1] - geometryOffset[i]; + mGeometryCache.back().resize(count); + memcpy(mGeometryCache.back().data(), geometry + geometryOffset[i], sizeof(Triangle) * count); + } + mHullsPointsCache.resize(geometryCount); + mBoundsCache.resize(geometryCount); + mCHullCache.resize(geometryCount); for (uint32_t i = 0; i < mGeometryCache.size(); ++i) { for (uint32_t j = 0; j < mGeometryCache[i].size(); ++j) @@ -395,36 +410,39 @@ namespace Nv chunksPoints[sp++] = mGeometryCache[ch][i].c.p; } - Nv::Blast::ConvexMeshBuilder builder(mPxCooking, mPxInsertionCallback); - - CollisionHull& cHull = mCHullCache[ch]; + Nv::Blast::ConvexMeshBuilderImpl builder(mPxCooking, mPxInsertionCallback); - builder.buildCollisionGeometry(chunksPoints, cHull); + mCHullCache[ch] = builder.buildCollisionGeometry(chunksPoints.size(), chunksPoints.data()); - mHullsPointsCache[ch].resize(cHull.points.size()); + mHullsPointsCache[ch].resize(mCHullCache[ch]->pointsCount); mBoundsCache[ch].setEmpty(); - for (uint32_t i = 0; i < cHull.points.size(); ++i) + for (uint32_t i = 0; i < mCHullCache[ch]->pointsCount; ++i) { - mHullsPointsCache[ch][i].x = cHull.points[i].x; - mHullsPointsCache[ch][i].y = cHull.points[i].y; - mHullsPointsCache[ch][i].z = cHull.points[i].z; + mHullsPointsCache[ch][i] = mCHullCache[ch]->points[i]; mBoundsCache[ch].include(mHullsPointsCache[ch][i]); } } } - void BlastBondGenerator::resetGeometryCache() + void BlastBondGeneratorImpl::resetGeometryCache() { mGeometryCache.clear(); mPlaneCache.clear(); mHullsPointsCache.clear(); + for (auto h : mCHullCache) + { + h->release(); + } mCHullCache.clear(); mBoundsCache.clear(); } - int32_t BlastBondGenerator::createFullBondListExactInternal(const std::vector<std::vector<Triangle>>& chunksGeometry, std::vector < PlaneChunkIndexer >& planeTriangleMapping, std::vector<NvBlastBondDesc>& mResultBondDescs) + int32_t BlastBondGeneratorImpl::createFullBondListExactInternal(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + std::vector<PlaneChunkIndexer>& planeTriangleMapping, NvBlastBondDesc*& resultBondDescs) { + NV_UNUSED(meshCount); + std::map<std::pair<int32_t, int32_t>, std::pair<NvBlastBondDesc, int32_t> > bonds; TriangleProcessor trPrc; @@ -446,7 +464,7 @@ namespace Nv // uint32_t endIndex = (uint32_t)planeTriangleMapping.size(); PlaneChunkIndexer& mappedTr = planeTriangleMapping[tIndex]; - const Triangle& trl = chunksGeometry[mappedTr.chunkId][mappedTr.trId]; + const Triangle& trl = geometry[geometryOffset[mappedTr.chunkId] + mappedTr.trId]; PxPlane pln = mappedTr.plane; TrPrcTriangle trp(trl.a.p, trl.b.p, trl.c.p); PxVec3 trCentroid = (trl.a.p + trl.b.p + trl.c.p) * (1.0f / 3.0f); @@ -493,8 +511,7 @@ namespace Nv bonds[bondEndPoints].first.bond.normal[1] = pln.n[1]; bonds[bondEndPoints].first.bond.normal[2] = pln.n[2]; } - - const Triangle& trl2 = chunksGeometry[mappedTr2.chunkId][mappedTr2.trId]; + const Triangle& trl2 = geometry[geometryOffset[mappedTr2.chunkId] + mappedTr2.trId]; TrPrcTriangle trp2(trl2.a.p, trl2.b.p, trl2.c.p); @@ -536,6 +553,7 @@ namespace Nv } } + std::vector<NvBlastBondDesc> mResultBondDescs; for (auto it : bonds) { if (it.second.first.bond.area > 0) @@ -553,21 +571,23 @@ namespace Nv saveGeometryToObj(meshBuffer, "Mesh.obj"); saveGeometryToObj(intersectionBuffer, "inter.obj"); #endif - return 0; + resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size()); + memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc)*mResultBondDescs.size()); + return mResultBondDescs.size(); } - int32_t BlastBondGenerator::createBondForcedInternal(const std::vector<PxVec3>& hull0, const std::vector<PxVec3>& hull1, + int32_t BlastBondGeneratorImpl::createBondForcedInternal(const std::vector<PxVec3>& hull0, const std::vector<PxVec3>& hull1, const CollisionHull& cHull0,const CollisionHull& cHull1, PxBounds3 bound0, PxBounds3 bound1, NvBlastBond& resultBond, float overlapping) { TriangleProcessor trProcessor; Separation separation; - importerHullsInProximityApexFree(hull0, bound0, PxTransform(PxIdentity), PxVec3(1, 1, 1), hull1, bound1, PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.000, &separation); + importerHullsInProximityApexFree(hull0.size(), hull0.data(), bound0, PxTransform(PxIdentity), PxVec3(1, 1, 1), hull1.size(), hull1.data(), bound1, PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.000, &separation); if (std::isnan(separation.plane.d)) { - importerHullsInProximityApexFree(hull0, bound0, PxTransform(PxVec3(0.000001f, 0.000001f, 0.000001f)), PxVec3(1, 1, 1), hull1, bound1, PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.000, &separation); + importerHullsInProximityApexFree(hull0.size(), hull0.data(), bound0, PxTransform(PxVec3(0.000001f, 0.000001f, 0.000001f)), PxVec3(1, 1, 1), hull1.size(), hull1.data(), bound1, PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.000, &separation); if (std::isnan(separation.plane.d)) { return 1; @@ -581,9 +601,9 @@ namespace Nv dst[0][0] = 0; dst[0][1] = MAXIMUM_EXTENT; - for (uint32_t p = 0; p < cHull0.points.size(); ++p) + for (uint32_t p = 0; p < cHull0.pointsCount; ++p) { - float d = pl.distance(PxVec3(cHull0.points[p].x, cHull0.points[p].y, cHull0.points[p].z)); + float d = pl.distance(cHull0.points[p]); if (PxAbs(d) > PxAbs(dst[0][0])) { dst[0][0] = d; @@ -596,9 +616,9 @@ namespace Nv dst[1][0] = 0; dst[1][1] = MAXIMUM_EXTENT; - for (uint32_t p = 0; p < cHull1.points.size(); ++p) + for (uint32_t p = 0; p < cHull1.pointsCount; ++p) { - float d = pl.distance(PxVec3(cHull1.points[p].x, cHull1.points[p].y, cHull1.points[p].z)); + float d = pl.distance(cHull0.points[p]); if (PxAbs(d) > PxAbs(dst[1][0])) { dst[1][0] = d; @@ -612,16 +632,16 @@ namespace Nv float cvOffset[2] = { dst[0][1] + (dst[0][0] - dst[0][1]) * overlapping, dst[1][1] + (dst[1][0] - dst[1][1]) * overlapping }; - for (uint32_t i = 0; i < cHull0.polygonData.size(); ++i) + for (uint32_t i = 0; i < cHull0.polygonDataCount; ++i) { - uint32_t offset = cHull0.polygonData[i].mIndexBase; + auto& pd = cHull0.polygonData[i]; PxVec3 result; - for (uint32_t j = 0; j < cHull0.polygonData[i].mNbVerts; ++j) + for (uint32_t j = 0; j < pd.mNbVerts; ++j) { - uint32_t nxj = (j + 1) % cHull0.polygonData[i].mNbVerts; - const uint32_t* ind = &cHull0.indices[0]; - PxVec3 a = hull0[ind[j + offset]] - pl.n * cvOffset[0]; - PxVec3 b = hull0[ind[nxj + offset]] - pl.n * cvOffset[0]; + uint32_t nxj = (j + 1) % pd.mNbVerts; + const uint32_t* ind = cHull0.indices; + PxVec3 a = hull0[ind[j + pd.mIndexBase]] - pl.n * cvOffset[0]; + PxVec3 b = hull0[ind[nxj + pd.mIndexBase]] - pl.n * cvOffset[0]; if (getPlaneSegmentIntersection(pl, a, b, result)) { @@ -630,16 +650,16 @@ namespace Nv } } - for (uint32_t i = 0; i < cHull1.polygonData.size(); ++i) + for (uint32_t i = 0; i < cHull1.polygonDataCount; ++i) { - uint32_t offset = cHull1.polygonData[i].mIndexBase; + auto& pd = cHull1.polygonData[i]; PxVec3 result; - for (uint32_t j = 0; j < cHull1.polygonData[i].mNbVerts; ++j) + for (uint32_t j = 0; j < pd.mNbVerts; ++j) { - uint32_t nxj = (j + 1) % cHull1.polygonData[i].mNbVerts; - const uint32_t* ind = &cHull1.indices[0]; - PxVec3 a = hull1[ind[j + offset]] - pl.n * cvOffset[1]; - PxVec3 b = hull1[ind[nxj + offset]] - pl.n * cvOffset[1]; + uint32_t nxj = (j + 1) % pd.mNbVerts; + const uint32_t* ind = cHull1.indices; + PxVec3 a = hull1[ind[j + pd.mIndexBase]] - pl.n * cvOffset[1]; + PxVec3 b = hull1[ind[nxj + pd.mIndexBase]] - pl.n * cvOffset[1]; if (getPlaneSegmentIntersection(pl, a, b, result)) { @@ -696,56 +716,59 @@ namespace Nv return 0; } - - int32_t BlastBondGenerator::buildDescFromInternalFracture(FractureTool* tool, const std::vector<bool>& chunkIsSupport, std::vector<NvBlastBondDesc>& mResultBondDescs, std::vector<NvBlastChunkDesc>& mResultChunkDescriptors) + int32_t BlastBondGeneratorImpl::buildDescFromInternalFracture(FractureTool* tool, const bool* chunkIsSupport, + NvBlastBondDesc*& resultBondDescs, NvBlastChunkDesc*& resultChunkDescriptors) { - const std::vector<ChunkInfo>& chunkData = tool->getChunkList(); - std::vector<std::vector<Triangle> > trianglesBuffer(chunkData.size()); + uint32_t chunkCount = tool->getChunkCount(); + std::vector<uint32_t> trianglesCount(chunkCount); + std::vector<Triangle*> trianglesBuffer(chunkCount); for (uint32_t i = 0; i < trianglesBuffer.size(); ++i) { - tool->getBaseMesh(i, trianglesBuffer[i]); + trianglesCount[i] = tool->getBaseMesh(i, trianglesBuffer[i]); } - if (chunkData.empty() || trianglesBuffer.empty()) + if (chunkCount == 0) { - return 1; + return 0; } - mResultChunkDescriptors.resize(trianglesBuffer.size()); + resultChunkDescriptors = SAFE_ARRAY_NEW(NvBlastChunkDesc, trianglesBuffer.size()); std::vector<Bond> bondDescriptors; - mResultChunkDescriptors[0].parentChunkIndex = UINT32_MAX; - mResultChunkDescriptors[0].userData = 0; + resultChunkDescriptors[0].parentChunkIndex = UINT32_MAX; + resultChunkDescriptors[0].userData = 0; + resultChunkDescriptors[0].flags = NvBlastChunkDesc::NoFlags; { PxVec3 chunkCentroid(0, 0, 0); - for (uint32_t tr = 0; tr < trianglesBuffer[0].size(); ++tr) + for (uint32_t tr = 0; tr < trianglesCount[0]; ++tr) { chunkCentroid += trianglesBuffer[0][tr].a.p; chunkCentroid += trianglesBuffer[0][tr].b.p; chunkCentroid += trianglesBuffer[0][tr].c.p; } - chunkCentroid *= (1.0f / (3 * trianglesBuffer[0].size())); - mResultChunkDescriptors[0].centroid[0] = chunkCentroid[0]; - mResultChunkDescriptors[0].centroid[1] = chunkCentroid[1]; - mResultChunkDescriptors[0].centroid[2] = chunkCentroid[2]; + chunkCentroid *= (1.0f / (3 * trianglesCount[0])); + resultChunkDescriptors[0].centroid[0] = chunkCentroid[0]; + resultChunkDescriptors[0].centroid[1] = chunkCentroid[1]; + resultChunkDescriptors[0].centroid[2] = chunkCentroid[2]; } - for (uint32_t i = 1; i < chunkData.size(); ++i) + for (uint32_t i = 1; i < chunkCount; ++i) { - - mResultChunkDescriptors[i].userData = i; - mResultChunkDescriptors[i].parentChunkIndex = tool->getChunkIndex(chunkData[i].parent); + NvBlastChunkDesc& desc = resultChunkDescriptors[i]; + desc.userData = i; + desc.parentChunkIndex = tool->getChunkIndex(tool->getChunkInfo(i).parent); + desc.flags = NvBlastChunkDesc::NoFlags; if (chunkIsSupport[i]) - mResultChunkDescriptors[i].flags = NvBlastChunkDesc::SupportFlag; + desc.flags = NvBlastChunkDesc::SupportFlag; PxVec3 chunkCentroid(0, 0, 0); - for (uint32_t tr = 0; tr < trianglesBuffer[i].size(); ++tr) + for (uint32_t tr = 0; tr < trianglesCount[i]; ++tr) { chunkCentroid += trianglesBuffer[i][tr].a.p; chunkCentroid += trianglesBuffer[i][tr].b.p; chunkCentroid += trianglesBuffer[i][tr].c.p; Triangle& trRef = trianglesBuffer[i][tr]; - int32_t id = trRef.userInfo; + int32_t id = trRef.userData; if (id == 0) continue; bondDescriptors.push_back(Bond()); @@ -754,10 +777,10 @@ namespace Nv bond.m_planeIndex = id; bond.triangleIndex = tr; } - chunkCentroid *= (1.0f / (3 * trianglesBuffer[i].size())); - mResultChunkDescriptors[i].centroid[0] = chunkCentroid[0]; - mResultChunkDescriptors[i].centroid[1] = chunkCentroid[1]; - mResultChunkDescriptors[i].centroid[2] = chunkCentroid[2]; + chunkCentroid *= (1.0f / (3 * trianglesCount[i])); + desc.centroid[0] = chunkCentroid[0]; + desc.centroid[1] = chunkCentroid[1]; + desc.centroid[2] = chunkCentroid[2]; } std::sort(bondDescriptors.begin(), bondDescriptors.end()); if (bondDescriptors.empty()) @@ -778,6 +801,7 @@ namespace Nv chunkId = -1; planeId = bondDescriptors[0].m_planeIndex; + std::vector<NvBlastBondDesc> mResultBondDescs; for (uint32_t i = 0; i <= bondDescriptors.size(); ++i) { if (i == bondDescriptors.size() || (chunkId != bondDescriptors[i].m_chunkId || abs(planeId) != abs(bondDescriptors[i].m_planeIndex))) @@ -866,70 +890,81 @@ namespace Nv bb.include(trianglesBuffer[chunkId][tr].c.p); } - return 0; + resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size()); + memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc) * mResultBondDescs.size()); + + return mResultBondDescs.size(); } - int32_t BlastBondGenerator::createBondBetweenMeshes(const std::vector<std::vector<Triangle> >& geometry, std::vector<NvBlastBondDesc>& resultBond,const std::vector<std::pair<uint32_t, uint32_t> >& overlaps, BondGenerationConfig cfg) + int32_t BlastBondGeneratorImpl::createBondBetweenMeshes(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + uint32_t overlapsCount, const uint32_t* overlapsA, const uint32_t* overlapsB, NvBlastBondDesc*& resultBond, BondGenerationConfig cfg) { if (cfg.bondMode == BondGenerationConfig::AVERAGE) { resetGeometryCache(); - buildGeometryCache(geometry); + buildGeometryCache(meshCount, geometryOffset, geometry); } - resultBond.clear(); - resultBond.resize(overlaps.size()); + resultBond = SAFE_ARRAY_NEW(NvBlastBondDesc, overlapsCount); if (cfg.bondMode == BondGenerationConfig::EXACT) { - for (uint32_t i = 0; i < overlaps.size(); ++i) + for (uint32_t i = 0; i < overlapsCount; ++i) { - resultBond[i].chunkIndices[0] = overlaps[i].first; - resultBond[i].chunkIndices[1] = overlaps[i].second; - createBondBetweenMeshes(geometry[overlaps[i].first], geometry[overlaps[i].second], resultBond[i].bond, cfg); + NvBlastBondDesc& desc = resultBond[i]; + desc.chunkIndices[0] = overlapsA[i]; + desc.chunkIndices[1] = overlapsB[i]; + uint32_t meshACount = geometryOffset[overlapsA[i] + 1] - geometryOffset[overlapsA[i]]; + uint32_t meshBCount = geometryOffset[overlapsB[i] + 1] - geometryOffset[overlapsB[i]]; + createBondBetweenMeshes(meshACount, geometry + geometryOffset[overlapsA[i]], + meshBCount, geometry + geometryOffset[overlapsB[i]], desc.bond, cfg); } } else { - for (uint32_t i = 0; i < overlaps.size(); ++i) + for (uint32_t i = 0; i < overlapsCount; ++i) { - resultBond[i].chunkIndices[0] = overlaps[i].first; - resultBond[i].chunkIndices[1] = overlaps[i].second; - createBondForcedInternal(mHullsPointsCache[overlaps[i].first], mHullsPointsCache[overlaps[i].second], mCHullCache[overlaps[i].first], mCHullCache[overlaps[i].second], - mBoundsCache[overlaps[i].first], mBoundsCache[overlaps[i].second], resultBond[i].bond, 0.3f); + NvBlastBondDesc& desc = resultBond[i]; + desc.chunkIndices[0] = overlapsA[i]; + desc.chunkIndices[1] = overlapsB[i]; + createBondForcedInternal(mHullsPointsCache[overlapsA[i]], mHullsPointsCache[overlapsB[i]], *mCHullCache[overlapsA[i]], *mCHullCache[overlapsB[i]], + mBoundsCache[overlapsA[i]], mBoundsCache[overlapsB[i]], desc.bond, 0.3f); } } - return 0; + return overlapsCount; } - - int32_t BlastBondGenerator::createBondBetweenMeshes(const std::vector<Triangle>& meshA, const std::vector<Triangle>& meshB, NvBlastBond& resultBond, BondGenerationConfig conf) + int32_t BlastBondGeneratorImpl::createBondBetweenMeshes(uint32_t meshACount, const Triangle* meshA, uint32_t meshBCount, const Triangle* meshB, + NvBlastBond& resultBond, BondGenerationConfig conf) { float overlapping = 0.3; if (conf.bondMode == BondGenerationConfig::EXACT) { - std::vector<std::vector<Triangle> > chunks; - chunks.push_back(meshA); - chunks.push_back(meshB); - std::vector<bool> isSupport(2, true); - std::vector<NvBlastBondDesc> desc; - createFullBondListExact(chunks, isSupport, desc, conf); - if (desc.size() > 0) + std::vector<uint32_t> chunksOffsets = { 0, meshACount, meshACount + meshBCount }; + std::vector<Triangle> chunks; + chunks.resize(meshACount + meshBCount); + memcpy(chunks.data(), meshA, sizeof(Triangle) * meshACount); + memcpy(chunks.data() + meshACount, meshB, sizeof(Triangle) * meshBCount); + std::shared_ptr<bool> isSupport(new bool[2] {true, true}, [](bool* b) { delete[] b; }); + NvBlastBondDesc* desc; + uint32_t descSize = createFullBondListExact(2, chunksOffsets.data(), chunks.data(), isSupport.get(), desc, conf); + if (descSize > 0) { - resultBond = desc.back().bond; + resultBond = desc->bond; } else { + memset(&resultBond, 0, sizeof(NvBlastBond)); return 1; } return 0; } - std::vector<PxVec3> chunksPoints1(meshA.size() * 3); - std::vector<PxVec3> chunksPoints2(meshB.size() * 3); + std::vector<PxVec3> chunksPoints1(meshACount * 3); + std::vector<PxVec3> chunksPoints2(meshBCount * 3); int32_t sp = 0; - for (uint32_t i = 0; i < meshA.size(); ++i) + for (uint32_t i = 0; i < meshACount; ++i) { chunksPoints1[sp++] = meshA[i].a.p; chunksPoints1[sp++] = meshA[i].b.p; @@ -943,7 +978,7 @@ namespace Nv } sp = 0; - for (uint32_t i = 0; i < meshB.size(); ++i) + for (uint32_t i = 0; i < meshBCount; ++i) { chunksPoints2[sp++] = meshB[i].a.p; chunksPoints2[sp++] = meshB[i].b.p; @@ -956,16 +991,16 @@ namespace Nv } - Nv::Blast::ConvexMeshBuilder builder(mPxCooking, mPxInsertionCallback); + Nv::Blast::ConvexMeshBuilderImpl builder(mPxCooking, mPxInsertionCallback); - CollisionHull cHull[2]; + CollisionHull* cHull[2]; - builder.buildCollisionGeometry(chunksPoints1, cHull[0]); - builder.buildCollisionGeometry(chunksPoints2, cHull[1]); + cHull[0] = builder.buildCollisionGeometry(chunksPoints1.size(), chunksPoints1.data()); + cHull[1] = builder.buildCollisionGeometry(chunksPoints2.size(), chunksPoints2.data()); std::vector<PxVec3> hullPoints[2]; - hullPoints[0].resize(cHull[0].points.size()); - hullPoints[1].resize(cHull[1].points.size()); + hullPoints[0].resize(cHull[0]->pointsCount); + hullPoints[1].resize(cHull[1]->pointsCount); PxBounds3 bb[2]; @@ -974,18 +1009,40 @@ namespace Nv for (uint32_t cv = 0; cv < 2; ++cv) { - for (uint32_t i = 0; i < cHull[cv].points.size(); ++i) + for (uint32_t i = 0; i < cHull[cv]->pointsCount; ++i) { - hullPoints[cv][i].x = cHull[cv].points[i].x; - hullPoints[cv][i].y = cHull[cv].points[i].y; - hullPoints[cv][i].z = cHull[cv].points[i].z; + hullPoints[cv][i] = cHull[cv]->points[i]; bb[cv].include(hullPoints[cv][i]); } } - return createBondForcedInternal(hullPoints[0], hullPoints[1], cHull[0], cHull[1], bb[0], bb[1], resultBond, overlapping); + auto ret = createBondForcedInternal(hullPoints[0], hullPoints[1], *cHull[0], *cHull[1], bb[0], bb[1], resultBond, overlapping); + + cHull[0]->release(); + cHull[1]->release(); + + return ret; } + int32_t BlastBondGeneratorImpl::bondsFromPrefractured(uint32_t meshCount, const uint32_t* geometryCount, const Triangle* geometry, + const bool*& chunkIsSupport, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf) + { + int32_t ret_val = 0; + switch (conf.bondMode) + { + case BondGenerationConfig::AVERAGE: + ret_val = createFullBondListAveraged(meshCount, geometryCount, geometry, chunkIsSupport, resultBondDescs, conf); + break; + case BondGenerationConfig::EXACT: + ret_val = createFullBondListExact(meshCount, geometryCount, geometry, chunkIsSupport, resultBondDescs, conf); + break; + } + return ret_val; + } + void BlastBondGeneratorImpl::release() + { + delete this; + } } } diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h new file mode 100644 index 0000000..35c4b23 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h @@ -0,0 +1,104 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTAUTHORINGBONDGENERATORIMPL_H +#define NVBLASTEXTAUTHORINGBONDGENERATORIMPL_H + +#include "NvBlastExtAuthoringBondGenerator.h" +#include "NvBlastExtAuthoringFractureTool.h" +#include "../cooking/PxCooking.h" +#include <PxPlane.h> +#include <NvBlastExtAuthoringCollisionBuilder.h> +#include <vector> + +namespace Nv +{ +namespace Blast +{ + +/** + Tool for gathering bond information from provided mesh geometry +*/ + +class BlastBondGeneratorImpl : public BlastBondGenerator +{ +public: + + BlastBondGeneratorImpl(physx::PxCooking* cooking, physx::PxPhysicsInsertionCallback* insertionCallback) + : mPxCooking(cooking), mPxInsertionCallback(insertionCallback){}; + + virtual void release() override; + + virtual int32_t buildDescFromInternalFracture(FractureTool* tool, const bool* chunkIsSupport, + NvBlastBondDesc*& resultBondDescs, NvBlastChunkDesc*& resultChunkDescriptors) override; + + virtual int32_t createBondBetweenMeshes(uint32_t meshACount, const Triangle* meshA, uint32_t meshBCount, const Triangle* meshB, + NvBlastBond& resultBond, BondGenerationConfig conf = BondGenerationConfig()) override; + + virtual int32_t createBondBetweenMeshes(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + uint32_t overlapsCount, const uint32_t* overlapsA, const uint32_t* overlapsB, + NvBlastBondDesc*& resultBond, BondGenerationConfig cfg) override; + + virtual int32_t bondsFromPrefractured(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + const bool*& chunkIsSupport, NvBlastBondDesc*& resultBondDescs, + BondGenerationConfig conf = BondGenerationConfig()) override; + +private: + float processWithMidplanes( TriangleProcessor* trProcessor, + const std::vector<physx::PxVec3>& chunk1Points, const std::vector<physx::PxVec3>& chunk2Points, + const std::vector<physx::PxVec3>& hull1p, const std::vector<physx::PxVec3>& hull2p, + physx::PxVec3& normal, physx::PxVec3& centroid); + + int32_t createFullBondListAveraged( uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + const bool* supportFlags, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf); + int32_t createFullBondListExact( uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + const bool* supportFlags, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf); + int32_t createFullBondListExactInternal(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, + std::vector<PlaneChunkIndexer>& planeTriangleMapping , NvBlastBondDesc*& resultBondDescs); + int32_t createBondForcedInternal( const std::vector<physx::PxVec3>& hull0, const std::vector<physx::PxVec3>& hull1,const CollisionHull& cHull0, + const CollisionHull& cHull1, physx::PxBounds3 bound0, physx::PxBounds3 bound1, NvBlastBond& resultBond, float overlapping); + + void buildGeometryCache(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry); + void resetGeometryCache(); + + physx::PxCooking* mPxCooking; + physx::PxPhysicsInsertionCallback* mPxInsertionCallback; + + + std::vector<std::vector<Triangle> > mGeometryCache; + + std::vector<PlaneChunkIndexer> mPlaneCache; + std::vector<CollisionHull*> mCHullCache; + std::vector<std::vector<physx::PxVec3> > mHullsPointsCache; + std::vector<physx::PxBounds3 > mBoundsCache; +}; + +} // namespace Blast +} // namespace Nv + +#endif // NVBLASTEXTAUTHORINGBONDGENERATORIMPL_H
\ No newline at end of file diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp index b5030d7..7705173 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp @@ -1,15 +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 "NvBlastGlobals.h" #include "NvBlastExtAuthoringBooleanTool.h" -#include "NvBlastExtAuthoringMesh.h" +#include "NvBlastExtAuthoringMeshImpl.h" #include "NvBlastExtAuthoringAccelerator.h" #include <math.h> @@ -41,7 +60,6 @@ NV_FORCE_INLINE void vec2Lerp(const PxVec2& a, const PxVec2& b, PxVec2& out, flo out.y = (b.y - a.y) * t + a.y; } - NV_FORCE_INLINE int32_t BooleanEvaluator::addIfNotExist(Vertex& p) { mVerticesAggregate.push_back(p); @@ -187,18 +205,26 @@ int32_t shadowing10(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p) Vertex-facet shadowing functions */ -int32_t vfStatus02(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex& out1, Vertex& out2) +int32_t vfStatus02(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out) { int32_t val = 0; Vertex pnt; bool hasOnEdge = false; + out[0].p.y = -MAXIMUM_EXTENT; + out[1].p.y = MAXIMUM_EXTENT; for (int32_t i = 0; i < edgesCount; ++i) { val -= shadowing01(points[edges->s], points[edges->e], p, pnt, hasOnEdge); if (hasOnEdge != 0) { - out2 = out1; - out1 = pnt; + if (p.y > pnt.p.y && pnt.p.y > out[0].p.y) + { + out[0] = pnt; + } + if (p.y < pnt.p.y && pnt.p.y < out[1].p.y) + { + out[1] = pnt; + } } ++edges; } @@ -208,24 +234,24 @@ int32_t vfStatus02(const PxVec3& p, const Vertex* points, const Edge* edges, int int32_t shadowing02(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint) { - Vertex p1, p2; - int32_t stat = vfStatus02(p, points, edges, edgesCount, p1, p2); + Vertex outp[2]; + int32_t stat = vfStatus02(p, points, edges, edgesCount, outp); float z = 0; hasOnFacetPoint = false; if (stat != 0) { + Vertex& p1 = outp[0]; + Vertex& p2 = outp[1]; PxVec3 vc = p2.p - p1.p; float t = 0; - t = (abs(vc.x) > abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y; - t = (t < 0) ? 0 : t; - t = (t > 1) ? 1 : t; - z = t * vc.z + p1.p.z; + t = (std::abs(vc.x) > std::abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y; + t = PxClamp(t, 0.0f, 1.0f); + z = t * vc.z + p1.p.z; hasOnFacetPoint = true; onFacetPoint.p.x = p.x; onFacetPoint.p.y = p.y; onFacetPoint.p.z = z; - vec2Lerp(p1.uv[0], p2.uv[0], onFacetPoint.uv[0], t); vec3Lerp(p1.n, p2.n, onFacetPoint.n, t); @@ -237,18 +263,27 @@ int32_t shadowing02(const PxVec3& p, const Vertex* points, const Edge* edges, in return 0; } -int32_t vfStatus20(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex& out1, Vertex& out2) +int32_t vfStatus20(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out) { int32_t val = 0; Vertex pnt; bool hasOnEdge = false; + out[0].p.y = -MAXIMUM_EXTENT; + out[1].p.y = MAXIMUM_EXTENT; + for (int32_t i = 0; i < edgesCount; ++i) { val += shadowing10(points[edges->s], points[edges->e], p, pnt, hasOnEdge); if (hasOnEdge != 0) { - out2 = out1; - out1 = pnt; + if (p.y > pnt.p.y && pnt.p.y > out[0].p.y) + { + out[0] = pnt; + } + if (p.y < pnt.p.y && pnt.p.y < out[1].p.y) + { + out[1] = pnt; + } } ++edges; } @@ -257,17 +292,18 @@ int32_t vfStatus20(const PxVec3& p, const Vertex* points, const Edge* edges, int int32_t shadowing20(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint) { - Vertex p1, p2; - int32_t stat = vfStatus20(p, points, edges, edgesCount, p1, p2); + Vertex outp[2]; + int32_t stat = vfStatus20(p, points, edges, edgesCount, outp); hasOnFacetPoint = false; if (stat != 0) { + Vertex& p1 = outp[0]; + Vertex& p2 = outp[1]; PxVec3 vc = p2.p - p1.p; float t = 0; - t = (abs(vc.x) > abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y; - t = (t < 0) ? 0 : t; - t = (t > 1) ? 1 : t; - + t = (std::abs(vc.x) > std::abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y; + t = PxClamp(t, 0.0f, 1.0f); + hasOnFacetPoint = true; onFacetPoint.p.x = p.x; onFacetPoint.p.y = p.y; @@ -291,91 +327,72 @@ NV_FORCE_INLINE int32_t edgesCrossCheck(const PxVec3& eAs, const PxVec3& eAe, co return shadowing01(eBs, eBe, eAe) - shadowing01(eBs, eBe, eAs) + shadowing10(eAs, eAe, eBe) - shadowing10(eAs, eAe, eBs); } + + int32_t edgesIntersection(const Vertex& eAs, const Vertex& eAe, const Vertex& eBs, const Vertex& eBe, Vertex& intersectionA, Vertex& intersectionB, bool& hasPoints) { int32_t status = edgesCrossCheck(eAs.p, eAe.p, eBs.p, eBe.p); hasPoints = false; if (status == 0) + { return 0; - Vertex tempPoint; + } + Vertex tempPoint; Vertex bShadowingPair[2]; Vertex aShadowingPair[2]; bool hasOnEdge = false; - int32_t shadowingType = shadowing10(eAs, eAe, eBs.p, tempPoint, hasOnEdge); - bool aShadowing = false; - bool bShadowing = false; + bool bShadowing = false; + /** + Search for two pairs where parts of A shadows B, and where B shadows are. + Needed for search intersection point. + */ - if (shadowingType == 0 && hasOnEdge) - { - aShadowing = true; - aShadowingPair[0] = eBs; - aShadowingPair[1] = tempPoint; - } - else + for (auto p : { &eBs, &eBe }) { - if (shadowingType == 1 || shadowingType == -1) + int32_t shadowingType = shadowing10(eAs, eAe, p->p, tempPoint, hasOnEdge); + if (shadowingType == 0 && !aShadowing && hasOnEdge) { - bShadowing = true; - bShadowingPair[0] = eBs; - bShadowingPair[1] = tempPoint; + aShadowing = true; + aShadowingPair[0] = *p; + aShadowingPair[1] = tempPoint; } - } - - shadowingType = shadowing10(eAs, eAe, eBe.p, tempPoint, hasOnEdge); - - if (shadowingType == 0 && !aShadowing && hasOnEdge) - { - aShadowing = true; - aShadowingPair[0] = eBe; - aShadowingPair[1] = tempPoint; - } - else - { - if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + else { - bShadowing = true; - bShadowingPair[0] = eBe; - bShadowingPair[1] = tempPoint; + if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + { + bShadowing = true; + bShadowingPair[0] = *p; + bShadowingPair[1] = tempPoint; + } } } - shadowingType = shadowing01(eBs, eBe, eAe.p, tempPoint, hasOnEdge); - - if (shadowingType == 0 && !aShadowing && hasOnEdge) + if (!aShadowing || !bShadowing) { - aShadowing = true; - aShadowingPair[1] = eAe; - aShadowingPair[0] = tempPoint; - } - else - { - if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + for (auto p : { &eAs, &eAe }) { - bShadowing = true; - bShadowingPair[1] = eAe; - bShadowingPair[0] = tempPoint; - } - } + int32_t shadowingType = shadowing01(eBs, eBe, p->p, tempPoint, hasOnEdge); - shadowingType = shadowing01(eBs, eBe, eAs.p, tempPoint, hasOnEdge); - - if (shadowingType == 0 && !aShadowing && hasOnEdge) - { - aShadowing = true; - aShadowingPair[1] = eAs; - aShadowingPair[0] = tempPoint; - } - else - { - if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) - { - bShadowing = true; - bShadowingPair[1] = eAs; - bShadowingPair[0] = tempPoint; + if (shadowingType == 0 && !aShadowing && hasOnEdge) + { + aShadowing = true; + aShadowingPair[1] = *p; + aShadowingPair[0] = tempPoint; + } + else + { + if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + { + bShadowing = true; + bShadowingPair[1] = *p; + bShadowingPair[0] = tempPoint; + } + } } } + float deltaPlus = bShadowingPair[0].p.y - bShadowingPair[1].p.y; float deltaMinus = aShadowingPair[0].p.y - aShadowingPair[1].p.y; float div = 0; @@ -413,43 +430,30 @@ int32_t edgeFacetIntersection12(const Vertex& edSt, const Vertex& edEnd, const V Vertex bShadowingPair[2]; Vertex aShadowingPair[2]; bool hasPoint = false; - int32_t shadowingType = shadowing02(edEnd.p, points, edges, edgesCount, hasPoint, p1); - status -= shadowingType; bool aShadowing = false; bool bShadowing = false; - - if (shadowingType == 0 && hasPoint) + int32_t mlt = -1; + int32_t shadowingType; + for (auto p : { &edEnd, &edSt }) { - aShadowing = true; - aShadowingPair[0] = p1; - aShadowingPair[1] = edEnd; - } - else - { - if (shadowingType == 1 || shadowingType == -1) + shadowingType = shadowing02(p->p, points, edges, edgesCount, hasPoint, p1); + status += mlt * shadowingType; + if (shadowingType == 0 && !aShadowing && hasPoint) { - bShadowing = true; - bShadowingPair[0] = p1; - bShadowingPair[1] = edEnd; + aShadowing = true; + aShadowingPair[0] = p1; + aShadowingPair[1] = *p; } - } - - shadowingType = shadowing02(edSt.p, points, edges, edgesCount, hasPoint, p1); - status += shadowingType; - if (shadowingType == 0 && !aShadowing && hasPoint) - { - aShadowing = true; - aShadowingPair[0] = p1; - aShadowingPair[1] = edSt; - } - else - { - if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + else { - bShadowing = true; - bShadowingPair[0] = p1; - bShadowingPair[1] = edSt; + if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + { + bShadowing = true; + bShadowingPair[0] = p1; + bShadowingPair[1] = *p; + } } + mlt = 1; } for (int32_t ed = 0; ed < edgesCount; ++ed) @@ -472,14 +476,11 @@ int32_t edgeFacetIntersection12(const Vertex& edSt, const Vertex& edEnd, const V } } } - if (status == 0) - { - return 0; - } - if (!bShadowing || !aShadowing) + if (!status || !bShadowing || !aShadowing) { return 0; } + float deltaPlus = bShadowingPair[0].p.z - bShadowingPair[1].p.z; float div = 0; if (deltaPlus != 0) @@ -508,42 +509,32 @@ int32_t edgeFacetIntersection21(const Vertex& edSt, const Vertex& edEnd, const V Vertex bShadowingPair[2]; Vertex aShadowingPair[2]; bool hasPoint = false; - int32_t shadowingType = shadowing20(edEnd.p, points, edges, edgesCount, hasPoint, p1); - status = shadowingType; bool aShadowing = false; bool bShadowing = false; - if (shadowingType == 0 && hasPoint) - { - aShadowing = true; - aShadowingPair[0] = edEnd; - aShadowingPair[1] = p1; - } - else + + int32_t shadowingType; + int32_t mlt = 1; + for (auto p : { &edEnd, &edSt }) { - if (shadowingType == 1 || shadowingType == -1) + shadowingType = shadowing20(p->p, points, edges, edgesCount, hasPoint, p1); + status += mlt * shadowingType; + + if (shadowingType == 0 && !aShadowing && hasPoint) { - bShadowing = true; - bShadowingPair[0] = edEnd; - bShadowingPair[1] = p1; + aShadowing = true; + aShadowingPair[0] = *p; + aShadowingPair[1] = p1; } - } - - shadowingType = shadowing20(edSt.p, points, edges, edgesCount, hasPoint, p1); - status -= shadowingType; - if (shadowingType == 0 && !aShadowing && hasPoint) - { - aShadowing = true; - aShadowingPair[0] = edSt; - aShadowingPair[1] = p1; - } - else - { - if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + else { - bShadowing = true; - bShadowingPair[0] = edSt; - bShadowingPair[1] = p1; + if ((shadowingType == 1 || shadowingType == -1) && !bShadowing) + { + bShadowing = true; + bShadowingPair[0] = *p; + bShadowingPair[1] = p1; + } } + mlt = -1; } for (int32_t ed = 0; ed < edgesCount; ++ed) @@ -569,11 +560,7 @@ int32_t edgeFacetIntersection21(const Vertex& edSt, const Vertex& edEnd, const V } } } - if (status == 0) - { - return 0; - } - if (!bShadowing || !aShadowing) + if (!status || !bShadowing || !aShadowing) { return 0; } @@ -595,7 +582,7 @@ int32_t edgeFacetIntersection21(const Vertex& edSt, const Vertex& edEnd, const V return status; } -int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, Mesh* mesh) +int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, const Mesh* mesh) { int32_t status = 0; Vertex pnt; @@ -604,7 +591,7 @@ int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, Mesh* mesh) int32_t facet = mAcceleratorB->getNextFacet(); while (facet != -1) { - Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber; + const Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber; status += shadowing02(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoint, pnt); facet = mAcceleratorB->getNextFacet(); } @@ -618,7 +605,7 @@ int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, Mesh* mesh) return status; } -int32_t BooleanEvaluator::vertexMeshStatus30(const PxVec3& p, Mesh* mesh) +int32_t BooleanEvaluator::vertexMeshStatus30(const PxVec3& p, const Mesh* mesh) { int32_t status = 0; bool hasPoints = false; @@ -627,7 +614,7 @@ int32_t BooleanEvaluator::vertexMeshStatus30(const PxVec3& p, Mesh* mesh) int32_t facet = mAcceleratorA->getNextFacet(); while ( facet != -1) { - Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber; + const Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber; status -= shadowing20(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoints, point); facet = mAcceleratorA->getNextFacet(); } @@ -675,7 +662,7 @@ struct VertexPairComparator } }; -int32_t BooleanEvaluator::isPointContainedInMesh(Mesh* msh, const PxVec3& point) +int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, const PxVec3& point) { if (msh == nullptr) { @@ -687,7 +674,7 @@ int32_t BooleanEvaluator::isPointContainedInMesh(Mesh* msh, const PxVec3& point) } -int32_t BooleanEvaluator::isPointContainedInMesh(Mesh* msh, SpatialAccelerator* spAccel, const PxVec3& point) +int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, SpatialAccelerator* spAccel, const PxVec3& point) { if (msh == nullptr) { @@ -724,8 +711,8 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) Vertex newPointA; Vertex newPointB; - Vertex* meshAPoints = mMeshA->getVertices(); - Vertex* meshBPoints = mMeshB->getVertices(); + const Vertex* meshAPoints = mMeshA->getVertices(); + const Vertex* meshBPoints = mMeshB->getVertices(); EdgeWithParent newEdge; mEdgeFacetIntersectionData12.clear(); mEdgeFacetIntersectionData21.clear(); @@ -739,10 +726,10 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) int32_t facetA = mAcceleratorA->getNextFacet(); while (facetA != -1) { - Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber; - Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber; - Edge* fbe = facetBEdges; - Edge* fae = facetAEdges; + const Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber; + const Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber; + const Edge* fbe = facetBEdges; + const Edge* fae = facetAEdges; retainedStarts.clear(); retainedEnds.clear(); PxVec3 compositeEndPoint(0, 0, 0); @@ -814,7 +801,7 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) } if (retainedStarts.size() != retainedEnds.size()) { - NVBLAST_LOG_ERROR(mLoggingCallback, "Not equal number of starting and ending vertices! Probably input mesh has open edges."); + NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges."); return; } if (retainedStarts.size() > 1) @@ -856,7 +843,7 @@ void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode) Vertex newPointA; Vertex newPointB; - Vertex* meshAPoints = mMeshA->getVertices(); + const Vertex* meshAPoints = mMeshA->getVertices(); EdgeWithParent newEdge; mEdgeFacetIntersectionData12.clear(); @@ -867,10 +854,10 @@ void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode) for (uint32_t facetA = 0; facetA < mMeshA->getFacetCount(); ++facetA) { - Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber; + const Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber; int32_t facetB = 0; - Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber; - Edge* fae = facetAEdges; + const Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber; + const Edge* fae = facetAEdges; retainedStarts.clear(); retainedEnds.clear(); PxVec3 compositeEndPoint(0, 0, 0); @@ -911,7 +898,7 @@ void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode) } if (retainedStarts.size() != retainedEnds.size()) { - NVBLAST_LOG_ERROR(mLoggingCallback, "Not equal number of starting and ending vertices! Probably input mesh has open edges."); + NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges."); return; } if (retainedStarts.size() > 1) @@ -942,11 +929,11 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) int32_t statusValue = 0; int32_t inclusionValue = 0; - Vertex* vertices = mMeshA->getVertices(); + const Vertex* vertices = mMeshA->getVertices(); Vertex newPoint; VertexComparator comp; - PxBounds3& bMeshBoudning = mMeshB->getBoundingBox(); - Edge* facetEdges = mMeshA->getEdges(); + const PxBounds3& bMeshBoudning = mMeshB->getBoundingBox(); + const Edge* facetEdges = mMeshA->getEdges(); std::vector<Vertex> retainedStartVertices; std::vector<Vertex> retainedEndVertices; retainedStartVertices.reserve(255); @@ -1053,7 +1040,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) facetEdges++; if (retainedStartVertices.size() != retainedEndVertices.size()) { - NVBLAST_LOG_ERROR(mLoggingCallback, "Not equal number of starting and ending vertices! Probably input mesh has open edges."); + NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges."); return; } if (retainedEndVertices.size() > 1) @@ -1082,11 +1069,11 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) { int32_t statusValue = 0; int32_t inclusionValue = 0; - Vertex* vertices = mMeshB->getVertices(); + const Vertex* vertices = mMeshB->getVertices(); Vertex newPoint; VertexComparator comp; - PxBounds3& aMeshBoudning = mMeshA->getBoundingBox(); - Edge* facetEdges = mMeshB->getEdges(); + const PxBounds3& aMeshBoudning = mMeshA->getBoundingBox(); + const Edge* facetEdges = mMeshB->getEdges(); std::vector<Vertex> retainedStartVertices; std::vector<Vertex> retainedEndVertices; retainedStartVertices.reserve(255); @@ -1194,7 +1181,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) facetEdges++; if (retainedStartVertices.size() != retainedEndVertices.size()) { - NVBLAST_LOG_ERROR(mLoggingCallback, "Not equal number of starting and ending vertices! Probably input mesh has open edges."); + NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges."); return; } if (retainedEndVertices.size() - lastPos > 1) @@ -1222,7 +1209,7 @@ bool EdgeWithParentSortComp(const EdgeWithParent& a, const EdgeWithParent& b) } -void BooleanEvaluator::performBoolean(Mesh* meshA, Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode) +void BooleanEvaluator::performBoolean(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode) { reset(); mMeshA = meshA; @@ -1236,7 +1223,7 @@ void BooleanEvaluator::performBoolean(Mesh* meshA, Mesh* meshB, SpatialAccelerat mAcceleratorB = nullptr; } -void BooleanEvaluator::performBoolean(Mesh* meshA, Mesh* meshB, BooleanConf mode) +void BooleanEvaluator::performBoolean(const Mesh* meshA, const Mesh* meshB, BooleanConf mode) { reset(); mMeshA = meshA; @@ -1247,7 +1234,7 @@ void BooleanEvaluator::performBoolean(Mesh* meshA, Mesh* meshB, BooleanConf mode } -void BooleanEvaluator::performFastCutting(Mesh* meshA, Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode) +void BooleanEvaluator::performFastCutting(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode) { reset(); mMeshA = meshA; @@ -1260,7 +1247,7 @@ void BooleanEvaluator::performFastCutting(Mesh* meshA, Mesh* meshB, SpatialAccel mAcceleratorB = nullptr; } -void BooleanEvaluator::performFastCutting(Mesh* meshA, Mesh* meshB, BooleanConf mode) +void BooleanEvaluator::performFastCutting(const Mesh* meshA, const Mesh* meshB, BooleanConf mode) { reset(); mMeshA = meshA; @@ -1273,13 +1260,12 @@ void BooleanEvaluator::performFastCutting(Mesh* meshA, Mesh* meshB, BooleanConf -BooleanEvaluator::BooleanEvaluator(NvBlastLog loggingCallback) +BooleanEvaluator::BooleanEvaluator() { mMeshA = nullptr; mMeshB = nullptr; mAcceleratorA = nullptr; mAcceleratorB = nullptr; - mLoggingCallback = loggingCallback; } BooleanEvaluator::~BooleanEvaluator() { @@ -1301,6 +1287,7 @@ Mesh* BooleanEvaluator::createNewMesh() int32_t lastParent = mEdgeAggregate[0].parent; uint32_t collected = 0; int32_t userData = 0; + int32_t materialId = 0; for (uint32_t i = 0; i < mEdgeAggregate.size(); ++i) { if (mEdgeAggregate[i].parent != lastParent) @@ -1308,12 +1295,14 @@ Mesh* BooleanEvaluator::createNewMesh() if (lastParent < (int32_t)mMeshA->getFacetCount()) { userData = mMeshA->getFacet(lastParent)->userData; + materialId = mMeshA->getFacet(lastParent)->materialId; } else { userData = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->userData; + materialId = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->materialId; } - newFacets.push_back(Facet(lastPos, collected, userData)); + newFacets.push_back(Facet(lastPos, collected, materialId, userData)); lastPos = i; lastParent = mEdgeAggregate[i].parent; collected = 0; @@ -1326,13 +1315,16 @@ Mesh* BooleanEvaluator::createNewMesh() if (lastParent < (int32_t)mMeshA->getFacetCount()) { userData = mMeshA->getFacet(lastParent)->userData; + materialId = mMeshA->getFacet(lastParent)->materialId; + } else { userData = mMeshB->getFacet(pr)->userData; + materialId = mMeshB->getFacet(pr)->materialId; } - newFacets.push_back(Facet(lastPos, collected, userData)); - return new Mesh(&mVerticesAggregate[0], &newEdges[0], &newFacets[0], static_cast<uint32_t>(mVerticesAggregate.size()), static_cast<uint32_t>(mEdgeAggregate.size()), static_cast<uint32_t>(newFacets.size())); + newFacets.push_back(Facet(lastPos, collected, materialId, userData)); + return new MeshImpl(mVerticesAggregate.data(), newEdges.data(), newFacets.data(), static_cast<uint32_t>(mVerticesAggregate.size()), static_cast<uint32_t>(mEdgeAggregate.size()), static_cast<uint32_t>(newFacets.size())); } void BooleanEvaluator::reset() diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h index 0b0b73a..f362495 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.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 NVBLASTEXTAUTHORINGBOOLEANTOOL_H #define NVBLASTEXTAUTHORINGBOOLEANTOOL_H @@ -92,7 +110,7 @@ class BooleanEvaluator { public: - BooleanEvaluator(NvBlastLog logCallback = nullptr); + BooleanEvaluator(); ~BooleanEvaluator(); /** @@ -103,7 +121,7 @@ public: \param[in] spAccelB Acceleration structure for mesh B \param[in] mode Boolean operation type */ - void performBoolean(Mesh* meshA, Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode); + void performBoolean(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode); /** Perform boolean operation on two polygonal meshes (A and B). @@ -111,7 +129,7 @@ public: \param[in] meshB Mesh B \param[in] mode Boolean operation type */ - void performBoolean(Mesh* meshA, Mesh* meshB, BooleanConf mode); + void performBoolean(const Mesh* meshA, const Mesh* meshB, BooleanConf mode); /** Perform cutting of mesh with some large box, which represents cutting plane. This method skips part of intersetion computations, so @@ -122,7 +140,7 @@ public: \param[in] spAccelB Acceleration structure for cutting box \param[in] mode Boolean operation type */ - void performFastCutting(Mesh* meshA, Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode); + void performFastCutting(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode); /** Perform cutting of mesh with some large box, which represents cutting plane. This method skips part of intersetion computations, so @@ -131,7 +149,7 @@ public: \param[in] meshB Cutting box \param[in] mode Boolean operation type */ - void performFastCutting(Mesh* meshA, Mesh* meshB, BooleanConf mode); + void performFastCutting(const Mesh* meshA, const Mesh* meshB, BooleanConf mode); /** Test whether point contained in mesh. @@ -139,7 +157,7 @@ public: \param[in] point Point which should be tested \return not 0 if point is inside of mesh */ - int32_t isPointContainedInMesh(Mesh* mesh, const physx::PxVec3& point); + int32_t isPointContainedInMesh(const Mesh* mesh, const physx::PxVec3& point); /** Test whether point contained in mesh. \param[in] mesh Mesh geometry @@ -147,7 +165,7 @@ public: \param[in] point Point which should be tested \return not 0 if point is inside of mesh */ - int32_t isPointContainedInMesh(Mesh* mesh, SpatialAccelerator* spAccel, const physx::PxVec3& point); + int32_t isPointContainedInMesh(const Mesh* mesh, SpatialAccelerator* spAccel, const physx::PxVec3& point); /** @@ -172,11 +190,11 @@ private: void addEdgeIfValid(EdgeWithParent& ed); private: - int32_t vertexMeshStatus03(const physx::PxVec3& p, Mesh* mesh); - int32_t vertexMeshStatus30(const physx::PxVec3& p, Mesh* mesh); + int32_t vertexMeshStatus03(const physx::PxVec3& p, const Mesh* mesh); + int32_t vertexMeshStatus30(const physx::PxVec3& p, const Mesh* mesh); - Mesh* mMeshA; - Mesh* mMeshB; + const Mesh* mMeshA; + const Mesh* mMeshB; SpatialAccelerator* mAcceleratorA; SpatialAccelerator* mAcceleratorB; @@ -186,8 +204,6 @@ private: std::vector<std::vector<EdgeFacetIntersectionData> > mEdgeFacetIntersectionData12; std::vector<std::vector<EdgeFacetIntersectionData> > mEdgeFacetIntersectionData21; - - NvBlastLog mLoggingCallback; }; } // namespace Blast diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilder.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp index becdce9..39c7586 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilder.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp @@ -1,14 +1,32 @@ -/* -* 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 "NvBlastExtAuthoringCollisionBuilder.h" + +#include "NvBlastExtAuthoringCollisionBuilderImpl.h" #include <PxConvexMesh.h> #include <PxVec3.h> #include <PxBounds3.h> @@ -18,18 +36,31 @@ #include <NvBlastExtAuthoringInternalCommon.h> #include <NvBlastExtAuthoringBooleanTool.h> -#include <NvBlastExtAuthoringMesh.h> +#include <NvBlastExtAuthoringMeshImpl.h> using namespace physx; +#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? new T[x] : nullptr; +#define SAFE_ARRAY_DELETE(x) if (x != nullptr) {delete[] x; x = nullptr;} + namespace Nv { namespace Blast { -void ConvexMeshBuilder::buildCollisionGeometry(const std::vector<PxVec3>& vData, CollisionHull& output) +void CollisionHullImpl::release() +{ + SAFE_ARRAY_DELETE(points); + SAFE_ARRAY_DELETE(indices); + SAFE_ARRAY_DELETE(polygonData); + delete this; +} + +CollisionHull* ConvexMeshBuilderImpl::buildCollisionGeometry(uint32_t verticesCount, const physx::PxVec3* vData) { - std::vector<physx::PxVec3> vertexData = vData; + CollisionHull* output = new CollisionHullImpl(); + std::vector<physx::PxVec3> vertexData(verticesCount); + memcpy(vertexData.data(), vData, sizeof(physx::PxVec3) * verticesCount); PxConvexMeshDesc convexMeshDescr; PxConvexMesh* resultConvexMesh; @@ -72,13 +103,16 @@ void ConvexMeshBuilder::buildCollisionGeometry(const std::vector<PxVec3>& vData, convexMeshDescr.points.count = (uint32_t)vertexData.size(); resultConvexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback); } - output.polygonData.resize(resultConvexMesh->getNbPolygons()); - output.points.resize(resultConvexMesh->getNbVertices()); + output->polygonDataCount = resultConvexMesh->getNbPolygons(); + if (output->polygonDataCount) + output->polygonData = SAFE_ARRAY_NEW(CollisionHull::HullPolygon, output->polygonDataCount); + output->pointsCount = resultConvexMesh->getNbVertices(); + output->points = SAFE_ARRAY_NEW(PxVec3, output->pointsCount); int32_t indicesCount = 0; PxHullPolygon hPoly; for (uint32_t i = 0; i < resultConvexMesh->getNbPolygons(); ++i) { - CollisionHull::HullPolygon& pd = output.polygonData[i]; + CollisionHull::HullPolygon& pd = output->polygonData[i]; resultConvexMesh->getPolygonData(i, hPoly); pd.mIndexBase = hPoly.mIndexBase; pd.mNbVerts = hPoly.mNbVerts; @@ -98,47 +132,49 @@ void ConvexMeshBuilder::buildCollisionGeometry(const std::vector<PxVec3>& vData, pd.mPlane[3] /= length; indicesCount = PxMax(indicesCount, pd.mIndexBase + pd.mNbVerts); } - output.indices.resize(indicesCount); + output->indicesCount = indicesCount; + output->indices = SAFE_ARRAY_NEW(uint32_t, indicesCount); for (uint32_t i = 0; i < resultConvexMesh->getNbVertices(); ++i) { PxVec3 p = resultConvexMesh->getVertices()[i] * scale + bbCenter; - output.points[i] = p; + output->points[i] = p; } for (int32_t i = 0; i < indicesCount; ++i) { - output.indices[i] = resultConvexMesh->getIndexBuffer()[i]; + output->indices[i] = resultConvexMesh->getIndexBuffer()[i]; } resultConvexMesh->release(); + return output; } -void ConvexMeshBuilder::trimCollisionGeometry(std::vector<CollisionHull>& in, const std::vector<uint32_t>& chunkDepth) +void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth) { - std::vector<std::vector<PxPlane> > chunkMidplanes(in.size()); - std::vector<PxVec3> centers(in.size()); - std::vector<PxBounds3> hullsBounds(in.size()); - for (uint32_t i = 0; i < in.size(); ++i) + std::vector<std::vector<PxPlane> > chunkMidplanes(chunksCount); + std::vector<PxVec3> centers(chunksCount); + std::vector<PxBounds3> hullsBounds(chunksCount); + for (uint32_t i = 0; i < chunksCount; ++i) { hullsBounds[i].setEmpty(); centers[i] = PxVec3(0, 0, 0); - for (uint32_t p = 0; p < in[i].points.size(); ++p) + for (uint32_t p = 0; p < in[i]->pointsCount; ++p) { - centers[i] += in[i].points[p]; - hullsBounds[i].include(in[i].points[p]); + centers[i] += in[i]->points[p]; + hullsBounds[i].include(in[i]->points[p]); } centers[i] = hullsBounds[i].getCenter(); } Separation params; - for (uint32_t hull = 0; hull < in.size(); ++hull) + for (uint32_t hull = 0; hull < chunksCount; ++hull) { - for (uint32_t hull2 = hull + 1; hull2 < in.size(); ++hull2) + for (uint32_t hull2 = hull + 1; hull2 < chunksCount; ++hull2) { if (chunkDepth[hull] != chunkDepth[hull2]) { continue; } - if (importerHullsInProximityApexFree(in[hull].points, hullsBounds[hull], PxTransform(PxIdentity), PxVec3(1, 1, 1), - in[hull2].points, hullsBounds[hull2], PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.0, ¶ms) == false) + if (importerHullsInProximityApexFree(in[hull]->pointsCount, in[hull]->points, hullsBounds[hull], PxTransform(PxIdentity), PxVec3(1, 1, 1), + in[hull2]->pointsCount, in[hull2]->points, hullsBounds[hull2], PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.0, ¶ms) == false) { continue; } @@ -147,22 +183,22 @@ void ConvexMeshBuilder::trimCollisionGeometry(std::vector<CollisionHull>& in, co float d = FLT_MAX; PxVec3 n1; PxVec3 n2; - for (uint32_t p = 0; p < in[hull].points.size(); ++p) + for (uint32_t p = 0; p < in[hull]->pointsCount; ++p) { - float ld = (in[hull].points[p] - c2).magnitude(); + float ld = (in[hull]->points[p] - c2).magnitude(); if (ld < d) { - n1 = in[hull].points[p]; + n1 = in[hull]->points[p]; d = ld; } } d = FLT_MAX; - for (uint32_t p = 0; p < in[hull2].points.size(); ++p) + for (uint32_t p = 0; p < in[hull2]->pointsCount; ++p) { - float ld = (in[hull2].points[p] - c1).magnitude(); + float ld = (in[hull2]->points[p] - c1).magnitude(); if (ld < d) { - n2 = in[hull2].points[p]; + n2 = in[hull2]->points[p]; d = ld; } } @@ -176,31 +212,32 @@ void ConvexMeshBuilder::trimCollisionGeometry(std::vector<CollisionHull>& in, co } } std::vector<PxVec3> hPoints; - for (uint32_t i = 0; i < in.size(); ++i) + for (uint32_t i = 0; i < chunksCount; ++i) { std::vector<Facet> facets; std::vector<Vertex> vertices; std::vector<Edge> edges; - for (uint32_t fc = 0; fc < in[i].polygonData.size(); ++fc) + for (uint32_t fc = 0; fc < in[i]->polygonDataCount; ++fc) { Facet nFc; nFc.firstEdgeNumber = edges.size(); - uint32_t n = in[i].polygonData[fc].mNbVerts; + auto& pd = in[i]->polygonData[fc]; + uint32_t n = pd.mNbVerts; for (uint32_t ed = 0; ed < n; ++ed) { - uint32_t vr1 = in[i].indices[(ed) + in[i].polygonData[fc].mIndexBase]; - uint32_t vr2 = in[i].indices[(ed + 1) % n + in[i].polygonData[fc].mIndexBase]; + uint32_t vr1 = in[i]->indices[(ed) + pd.mIndexBase]; + uint32_t vr2 = in[i]->indices[(ed + 1) % n + pd.mIndexBase]; edges.push_back(Edge(vr1, vr2)); } nFc.edgesCount = n; facets.push_back(nFc); } - vertices.resize(in[i].points.size()); - for (uint32_t vr = 0; vr < in[i].points.size(); ++vr) + vertices.resize(in[i]->pointsCount); + for (uint32_t vr = 0; vr < in[i]->pointsCount; ++vr) { - vertices[vr].p = in[i].points[vr]; + vertices[vr].p = in[i]->points[vr]; } - Mesh* hullMesh = new Mesh(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size()); + Mesh* hullMesh = new MeshImpl(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size()); BooleanEvaluator evl; Mesh* cuttingMesh = getCuttingBox(PxVec3(0, 0, 0), PxVec3(0, 0, 1), 40, 0); for (uint32_t p = 0; p < chunkMidplanes[i].size(); ++p) @@ -228,52 +265,60 @@ void ConvexMeshBuilder::trimCollisionGeometry(std::vector<CollisionHull>& in, co hPoints[v] = hullMesh->getVertices()[v].p; } delete hullMesh; - buildCollisionGeometry(hPoints, in[i]); + if (in[i] != nullptr) + { + in[i]->release(); + } + in[i] = buildCollisionGeometry(hPoints.size(), hPoints.data()); } } -PxConvexMesh* ConvexMeshBuilder::buildConvexMesh(std::vector<PxVec3>& vertexData) +PxConvexMesh* ConvexMeshBuilderImpl::buildConvexMesh(uint32_t verticesCount, const physx::PxVec3* vertexData) { - CollisionHull hull; - buildCollisionGeometry(vertexData, hull); + CollisionHull* hull = buildCollisionGeometry(verticesCount, vertexData); PxConvexMeshDesc convexMeshDescr; - convexMeshDescr.indices.data = hull.indices.data(); - convexMeshDescr.indices.count = (uint32_t)hull.indices.size(); + convexMeshDescr.indices.data = hull->indices; + convexMeshDescr.indices.count = (uint32_t)hull->indicesCount; convexMeshDescr.indices.stride = sizeof(uint32_t); - convexMeshDescr.points.data = hull.points.data(); - convexMeshDescr.points.count = (uint32_t)hull.points.size(); + convexMeshDescr.points.data = hull->points; + convexMeshDescr.points.count = (uint32_t)hull->pointsCount; convexMeshDescr.points.stride = sizeof(PxVec3); - convexMeshDescr.polygons.data = hull.polygonData.data(); - convexMeshDescr.polygons.count = (uint32_t)hull.polygonData.size(); + convexMeshDescr.polygons.data = hull->polygonData; + convexMeshDescr.polygons.count = (uint32_t)hull->polygonDataCount; convexMeshDescr.polygons.stride = sizeof(PxHullPolygon); PxConvexMesh* convexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback); + hull->release(); return convexMesh; } -PxConvexMesh* ConvexMeshBuilder::buildConvexMesh(CollisionHull& hull) +PxConvexMesh* ConvexMeshBuilderImpl::buildConvexMesh(const CollisionHull& hull) { PxConvexMeshDesc convexMeshDescr; - convexMeshDescr.indices.data = hull.indices.data(); - convexMeshDescr.indices.count = (uint32_t)hull.indices.size(); + convexMeshDescr.indices.data = hull.indices; + convexMeshDescr.indices.count = (uint32_t)hull.indicesCount; convexMeshDescr.indices.stride = sizeof(uint32_t); - convexMeshDescr.points.data = hull.points.data(); - convexMeshDescr.points.count = (uint32_t)hull.points.size(); + convexMeshDescr.points.data = hull.points; + convexMeshDescr.points.count = (uint32_t)hull.pointsCount; convexMeshDescr.points.stride = sizeof(PxVec3); - convexMeshDescr.polygons.data = hull.polygonData.data(); - convexMeshDescr.polygons.count = (uint32_t)hull.polygonData.size(); + convexMeshDescr.polygons.data = hull.polygonData; + convexMeshDescr.polygons.count = (uint32_t)hull.polygonDataCount; convexMeshDescr.polygons.stride = sizeof(PxHullPolygon); PxConvexMesh* convexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback); return convexMesh; } +void ConvexMeshBuilderImpl::release() +{ + delete this; +} } // namespace Blast } // namespace Nv diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h new file mode 100644 index 0000000..709c880 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.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 NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H +#define NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H + +#include "NvBlastExtAuthoringCollisionBuilder.h" +#include "NvBlastExtAuthoringTypes.h" + +namespace Nv +{ +namespace Blast +{ + +struct CollisionHullImpl : public CollisionHull +{ + void release() override; +}; + +class ConvexMeshBuilderImpl : public ConvexMeshBuilder +{ +public: + + /** + Constructor should be provided with PxCoocking and PxPhysicsInsertionCallback objects. + */ + ConvexMeshBuilderImpl(physx::PxCooking* cooking, physx::PxPhysicsInsertionCallback* insertionCallback) : mInsertionCallback(insertionCallback), mCooking(cooking) {} + + virtual void release() override; + + virtual CollisionHull* buildCollisionGeometry(uint32_t verticesCount, const physx::PxVec3* vertexData) override; + + virtual physx::PxConvexMesh* buildConvexMesh(uint32_t verticesCount, const physx::PxVec3* vertexData) override; + + virtual physx::PxConvexMesh* buildConvexMesh(const CollisionHull& hull) override; + + virtual void trimCollisionGeometry(uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth) override; + +private: + physx::PxPhysicsInsertionCallback* mInsertionCallback; + physx::PxCooking* mCooking; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp index 48830fe..91c81bc 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp @@ -8,7 +8,9 @@ * license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "NvBlastExtAuthoringFractureTool.h" +#include "NvBlastExtAuthoringFractureToolImpl.h" +#include "NvBlastExtAuthoringMeshImpl.h" + // This warning arises when using some stl containers with older versions of VC // c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1826): warning C4702: unreachable code #if NV_VC && NV_VC < 14 @@ -22,6 +24,7 @@ #include "NvBlastExtAuthoringBooleanTool.h" #include "NvBlastExtAuthoringAccelerator.h" #include "NvBlast.h" +#include "NvBlastGlobals.h" #include "NvBlastExtAuthoringPerlinNoise.h" #include <NvBlastAssert.h> using namespace physx; @@ -133,7 +136,7 @@ bool blastBondComparator(const NvBlastBondDesc& a, const NvBlastBondDesc& b) #define MAX_VORONOI_ATTEMPT_NUMBER 450 -VoronoiSitesGenerator::VoronoiSitesGenerator(Mesh* mesh, RandomGeneratorBase* rnd) +VoronoiSitesGeneratorImpl::VoronoiSitesGeneratorImpl(const Mesh* mesh, RandomGeneratorBase* rnd) { mMesh = mesh; mRnd = rnd; @@ -141,7 +144,7 @@ VoronoiSitesGenerator::VoronoiSitesGenerator(Mesh* mesh, RandomGeneratorBase* rn mStencil = nullptr; } -void VoronoiSitesGenerator::setBaseMesh(Mesh* m) +void VoronoiSitesGeneratorImpl::setBaseMesh(const Mesh* m) { mGeneratedSites.clear(); delete mAccelerator; @@ -149,28 +152,32 @@ void VoronoiSitesGenerator::setBaseMesh(Mesh* m) mAccelerator = new BBoxBasedAccelerator(mMesh, DEFAULT_BB_ACCELARATOR_RES); } -VoronoiSitesGenerator::~VoronoiSitesGenerator() +VoronoiSitesGeneratorImpl::~VoronoiSitesGeneratorImpl() { delete mAccelerator; mAccelerator = nullptr; } +void VoronoiSitesGeneratorImpl::release() +{ + delete this; +} -void VoronoiSitesGenerator::setStencil(Mesh* stencil) +void VoronoiSitesGeneratorImpl::setStencil(const Mesh* stencil) { mStencil = stencil; } -void VoronoiSitesGenerator::clearStencil() +void VoronoiSitesGeneratorImpl::clearStencil() { mStencil = nullptr; } -void VoronoiSitesGenerator::uniformlyGenerateSitesInMesh(const uint32_t sitesCount) +void VoronoiSitesGeneratorImpl::uniformlyGenerateSitesInMesh(const uint32_t sitesCount) { - BooleanEvaluator voronoiMeshEval(nullptr); + BooleanEvaluator voronoiMeshEval; PxVec3 mn = mMesh->getBoundingBox().minimum; PxVec3 mx = mMesh->getBoundingBox().maximum; PxVec3 vc = mx - mn; @@ -198,9 +205,9 @@ void VoronoiSitesGenerator::uniformlyGenerateSitesInMesh(const uint32_t sitesCou } -void VoronoiSitesGenerator::clusteredSitesGeneration(const uint32_t numberOfClusters, const uint32_t sitesPerCluster, float clusterRadius) +void VoronoiSitesGeneratorImpl::clusteredSitesGeneration(const uint32_t numberOfClusters, const uint32_t sitesPerCluster, float clusterRadius) { - BooleanEvaluator voronoiMeshEval(nullptr); + BooleanEvaluator voronoiMeshEval; PxVec3 mn = mMesh->getBoundingBox().minimum; PxVec3 mx = mMesh->getBoundingBox().maximum; PxVec3 middle = (mx + mn) * 0.5; @@ -260,15 +267,15 @@ void VoronoiSitesGenerator::clusteredSitesGeneration(const uint32_t numberOfClus #define IN_SPHERE_ATTEMPT_NUMBER 20 -void VoronoiSitesGenerator::addSite(const physx::PxVec3& site) +void VoronoiSitesGeneratorImpl::addSite(const physx::PxVec3& site) { mGeneratedSites.push_back(site); } -void VoronoiSitesGenerator::generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center) +void VoronoiSitesGeneratorImpl::generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center) { - BooleanEvaluator voronoiMeshEval(nullptr); + BooleanEvaluator voronoiMeshEval; uint32_t attemptNumber = 0; uint32_t generatedSites = 0; std::vector<PxVec3> tempPoints; @@ -295,7 +302,7 @@ void VoronoiSitesGenerator::generateInSphere(const uint32_t count, const float r } -void VoronoiSitesGenerator::deleteInSphere(const float radius, const physx::PxVec3& center, float deleteProbability) +void VoronoiSitesGeneratorImpl::deleteInSphere(const float radius, const physx::PxVec3& center, float deleteProbability) { float r2 = radius * radius; for (uint32_t i = 0; i < mGeneratedSites.size(); ++i) @@ -310,11 +317,11 @@ void VoronoiSitesGenerator::deleteInSphere(const float radius, const physx::PxVe } -void VoronoiSitesGenerator::radialPattern(const physx::PxVec3& center, const physx::PxVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset, float variability) +void VoronoiSitesGeneratorImpl::radialPattern(const physx::PxVec3& center, const physx::PxVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset, float variability) { // mGeneratedSites.push_back(center); physx::PxVec3 t1, t2; - if (abs(normal.z) < 0.9) + if (std::abs(normal.z) < 0.9) { t1 = normal.cross(PxVec3(0, 0, 1)); } @@ -346,14 +353,16 @@ void VoronoiSitesGenerator::radialPattern(const physx::PxVec3& center, const phy } } - -std::vector<PxVec3>& VoronoiSitesGenerator::getVoronoiSites() +uint32_t VoronoiSitesGeneratorImpl::getVoronoiSites(const physx::PxVec3*& sites) { - return mGeneratedSites; + if (mGeneratedSites.size()) + { + sites = &mGeneratedSites[0]; + } + return (uint32_t)mGeneratedSites.size(); } - -int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<physx::PxVec3>& cellPointsIn, bool replaceChunk) +int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPointsIn, bool replaceChunk) { if (chunkId == 0 && replaceChunk) { @@ -361,7 +370,7 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys } int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1 || cellPointsIn.size() < 2) + if (chunkIndex == -1 || cellCount < 2) { return 1; } @@ -373,8 +382,8 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys Mesh* mesh = mChunkData[chunkIndex].meshData; - std::vector<PxVec3> cellPoints(cellPointsIn.size()); - for (uint32_t i = 0; i < cellPointsIn.size(); ++i) + std::vector<PxVec3> cellPoints(cellCount); + for (uint32_t i = 0; i < cellCount; ++i) { cellPoints[i] = (cellPointsIn[i] - mOffset) * (1.0f / mScaleFactor); } @@ -382,8 +391,8 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys /** Prebuild accelerator structure */ - BooleanEvaluator eval(mLoggingCallback); - BooleanEvaluator voronoiMeshEval(mLoggingCallback); + BooleanEvaluator eval; + BooleanEvaluator voronoiMeshEval; BBoxBasedAccelerator spAccel = BBoxBasedAccelerator(mesh, DEFAULT_BB_ACCELARATOR_RES); @@ -436,20 +445,86 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys return 0; } -Mesh FractureTool::getChunkMesh(int32_t chunkId) +Mesh* FractureToolImpl::createChunkMesh(int32_t chunkId) { - Mesh temp = *mChunkData[getChunkIndex(chunkId)].meshData; - for (uint32_t i = 0; i < temp.getVerticesCount(); ++i) + int32_t chunkIndex = getChunkIndex(chunkId); + if (chunkIndex < 0 || static_cast<size_t>(chunkIndex) >= mChunkData.size()) { - temp.getVertices()[i].p = temp.getVertices()[i].p * mScaleFactor + mOffset; + return nullptr; } - temp.recalculateBoundingBox(); + + auto temp = new MeshImpl(*reinterpret_cast<MeshImpl*>(mChunkData[chunkIndex].meshData)); + for (uint32_t i = 0; i < temp->getVerticesCount(); ++i) + { + temp->getVerticesWritable()[i].p = temp->getVertices()[i].p * mScaleFactor + mOffset; + } + temp->recalculateBoundingBox(); return temp; } +bool FractureToolImpl::isMeshContainOpenEdges(const Mesh* input) +{ + std::map<PxVec3, int32_t, VrtPositionComparator> vertexMapping; + std::vector<int32_t> vertexRemappingArray(input->getVerticesCount()); + std::vector<Edge> remappedEdges(input->getEdgesCount()); + /** + Remap vertices + */ + + const Vertex* vrx = input->getVertices(); + for (uint32_t i = 0; i < input->getVerticesCount(); ++i) + { + auto it = vertexMapping.find(vrx->p); + if (it == vertexMapping.end()) + { + vertexMapping[vrx->p] = i; + vertexRemappingArray[i] = i; + } + else + { + vertexRemappingArray[i] = it->second; + } + ++vrx; + } + + const Edge* ed = input->getEdges(); + for (uint32_t i = 0; i < input->getEdgesCount(); ++i) + { + remappedEdges[i].s = vertexRemappingArray[ed->s]; + remappedEdges[i].e = vertexRemappingArray[ed->e]; + if (remappedEdges[i].e < remappedEdges[i].s) + { + std::swap(remappedEdges[i].s, remappedEdges[i].e); + } + ++ed; + } + + std::sort(remappedEdges.begin(), remappedEdges.end()); + + int32_t collected = 1; + for (uint32_t i = 1; i < remappedEdges.size(); ++i) + { + if (remappedEdges[i - 1].s == remappedEdges[i].s && remappedEdges[i - 1].e == remappedEdges[i].e) + { + collected++; + } + else + { + if (collected & 1) + { + return true; + } + else + { + collected = 1; + } + } + } + return collected & 1; +} -int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<physx::PxVec3>& cellPointsIn, const physx::PxVec3& scale, bool replaceChunk) +int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPointsIn, const physx::PxVec3& scale, bool replaceChunk) { if (chunkId == 0 && replaceChunk) { @@ -457,7 +532,7 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys } int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1 || cellPointsIn.size() < 2) + if (chunkIndex == -1 || cellCount < 2) { return 1; } @@ -469,8 +544,8 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys Mesh* mesh = mChunkData[chunkIndex].meshData; - std::vector<PxVec3> cellPoints(cellPointsIn.size()); - for (uint32_t i = 0; i < cellPointsIn.size(); ++i) + std::vector<PxVec3> cellPoints(cellCount); + for (uint32_t i = 0; i < cellCount; ++i) { cellPoints[i] = (cellPointsIn[i] - mOffset) * (1.0f / mScaleFactor); @@ -482,8 +557,8 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys /** Prebuild accelerator structure */ - BooleanEvaluator eval(mLoggingCallback); - BooleanEvaluator voronoiMeshEval(mLoggingCallback); + BooleanEvaluator eval; + BooleanEvaluator voronoiMeshEval; BBoxBasedAccelerator spAccel = BBoxBasedAccelerator(mesh, DEFAULT_BB_ACCELARATOR_RES); @@ -507,9 +582,9 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys for (uint32_t v = 0; v < cell->getVerticesCount(); ++v) { - cell->getVertices()[v].p.x *= scale.x; - cell->getVertices()[v].p.y *= scale.y; - cell->getVertices()[v].p.z *= scale.z; + cell->getVerticesWritable()[v].p.x *= scale.x; + cell->getVerticesWritable()[v].p.y *= scale.y; + cell->getVerticesWritable()[v].p.z *= scale.z; } cell->recalculateBoundingBox(); DummyAccelerator dmAccel(cell->getFacetCount()); @@ -546,7 +621,7 @@ int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<phys } -int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) +int32_t FractureToolImpl::slicing(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) { if (conf.noiseAmplitude != 0) { @@ -570,9 +645,9 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool chunkIndex = getChunkIndex(chunkId); - Mesh* mesh = new Mesh(*mChunkData[chunkIndex].meshData); + Mesh* mesh = new MeshImpl(*reinterpret_cast <MeshImpl*>(mChunkData[chunkIndex].meshData)); - BooleanEvaluator bTool(mLoggingCallback); + BooleanEvaluator bTool; int32_t x_slices = conf.x_slices; int32_t y_slices = conf.y_slices; @@ -607,8 +682,8 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1); PxVec3 lDir = dir + randVect * conf.angle_variations; - setCuttingBox(center, lDir, slBox, 20, mPlaneIndexerOffset); - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); + setCuttingBox(center, -lDir, slBox, 20, mPlaneIndexerOffset); + bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); ch.meshData = bTool.createNewMesh(); if (ch.meshData != 0) @@ -617,7 +692,7 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool } inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); ++mPlaneIndexerOffset; - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); + bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); Mesh* result = bTool.createNewMesh(); delete mesh; mesh = result; @@ -647,8 +722,8 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool PxVec3 lDir = dir + randVect * conf.angle_variations; - setCuttingBox(center, lDir, slBox, 20, mPlaneIndexerOffset); - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); + setCuttingBox(center, -lDir, slBox, 20, mPlaneIndexerOffset); + bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); ch.meshData = bTool.createNewMesh(); if (ch.meshData != 0) { @@ -656,7 +731,7 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool } inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); ++mPlaneIndexerOffset; - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); + bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); Mesh* result = bTool.createNewMesh(); delete mesh; mesh = result; @@ -685,8 +760,8 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool { PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1); PxVec3 lDir = dir + randVect * conf.angle_variations; - setCuttingBox(center, lDir, slBox, 20, mPlaneIndexerOffset); - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); + setCuttingBox(center, -lDir, slBox, 20, mPlaneIndexerOffset); + bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); ch.meshData = bTool.createNewMesh(); if (ch.meshData != 0) { @@ -696,7 +771,7 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool } inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); ++mPlaneIndexerOffset; - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); + bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); Mesh* result = bTool.createNewMesh(); delete mesh; mesh = result; @@ -735,7 +810,7 @@ int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool return 0; } -int32_t FractureTool::slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) +int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) { if (replaceChunk && chunkId == 0) { @@ -754,9 +829,9 @@ int32_t FractureTool::slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, chunkIndex = getChunkIndex(chunkId); - Mesh* mesh = new Mesh(*mChunkData[chunkIndex].meshData); + Mesh* mesh = new MeshImpl(*reinterpret_cast <MeshImpl*>(mChunkData[chunkIndex].meshData)); - BooleanEvaluator bTool(mLoggingCallback); + BooleanEvaluator bTool; int32_t x_slices = conf.x_slices; int32_t y_slices = conf.y_slices; @@ -784,7 +859,7 @@ int32_t FractureTool::slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, std::vector<ChunkInfo> ySlicedChunks; std::vector<uint32_t> newlyCreatedChunksIds; float noisyPartSize = 1.8f; - int32_t acceleratorRes = 5; + int32_t acceleratorRes = 8; /** Slice along x direction */ @@ -930,7 +1005,7 @@ int32_t FractureTool::slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, -int32_t FractureTool::getChunkIndex(int32_t chunkId) +int32_t FractureToolImpl::getChunkIndex(int32_t chunkId) { for (uint32_t i = 0; i < mChunkData.size(); ++i) { @@ -942,7 +1017,7 @@ int32_t FractureTool::getChunkIndex(int32_t chunkId) return -1; } -int32_t FractureTool::getChunkDepth(int32_t chunkId) +int32_t FractureToolImpl::getChunkDepth(int32_t chunkId) { int32_t chunkIndex = getChunkIndex(chunkId); if (chunkIndex == -1) @@ -960,41 +1035,50 @@ int32_t FractureTool::getChunkDepth(int32_t chunkId) return depth; } -std::vector<int32_t> FractureTool::getChunksIdAtDepth(uint32_t depth) +uint32_t FractureToolImpl::getChunksIdAtDepth(uint32_t depth, int32_t*& chunkIds) { - std::vector<int32_t> chunkIds; + std::vector<int32_t> _chunkIds; for (uint32_t i = 0; i < mChunkData.size(); ++i) { if (getChunkDepth(mChunkData[i].chunkId) == (int32_t)depth) { - chunkIds.push_back(mChunkData[i].chunkId); + _chunkIds.push_back(mChunkData[i].chunkId); } } - return chunkIds; + chunkIds = new int32_t[_chunkIds.size()]; + memcpy(chunkIds, _chunkIds.data(), _chunkIds.size() * sizeof(int32_t)); + + return (uint32_t)_chunkIds.size(); } -void FractureTool::getTransformation(PxVec3& offset, float& scale) +void FractureToolImpl::getTransformation(PxVec3& offset, float& scale) { offset = mOffset; scale = mScaleFactor; } -void FractureTool::setSourceMesh(Mesh* mesh) +void FractureToolImpl::setSourceMesh(const Mesh* meshInput) { - if (mesh == nullptr) + if (meshInput == nullptr) { return; } reset(); + if (isMeshContainOpenEdges(meshInput)) + { + NVBLAST_LOG_WARNING("WARNING! Input mesh contains open edges, it may lead to wrong fractruing results!. \n"); + } + + mChunkData.resize(1); - mChunkData[0].meshData = new Mesh(*mesh); + mChunkData[0].meshData = new MeshImpl(*reinterpret_cast <const MeshImpl*>(meshInput)); mChunkData[0].parent = -1; mChunkData[0].isLeaf = true; mChunkData[0].chunkId = mChunkIdCounter++; - mesh = mChunkData[0].meshData; + Mesh* mesh = mChunkData[0].meshData; /** Move to origin and scale to unit cube @@ -1005,24 +1089,30 @@ void FractureTool::setSourceMesh(Mesh* mesh) mScaleFactor = std::max(bbSizes.x, std::max(bbSizes.y, bbSizes.z)); - Vertex* verticesBuffer = mesh->getVertices(); + Vertex* verticesBuffer = mesh->getVerticesWritable(); for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) { verticesBuffer[i].p = (verticesBuffer[i].p - mOffset) * (1.0f / mScaleFactor); } - mesh->getBoundingBox().minimum = (mesh->getBoundingBox().minimum - mOffset) * (1.0f / mScaleFactor); - mesh->getBoundingBox().maximum = (mesh->getBoundingBox().maximum - mOffset) * (1.0f / mScaleFactor); + mesh->getBoundingBoxWritable().minimum = (mesh->getBoundingBox().minimum - mOffset) * (1.0f / mScaleFactor); + mesh->getBoundingBoxWritable().maximum = (mesh->getBoundingBox().maximum - mOffset) * (1.0f / mScaleFactor); for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) { - mesh->getFacet(i)->userData = 0; // Mark facet as initial boundary facet + mesh->getFacetWritable(i)->userData = 0; // Mark facet as initial boundary facet } } -void FractureTool::reset() +void FractureToolImpl::release() +{ + delete this; +} + + +void FractureToolImpl::reset() { mChunkPostprocessors.clear(); for (uint32_t i = 0; i < mChunkData.size(); ++i) @@ -1035,9 +1125,7 @@ void FractureTool::reset() } - - -bool FractureTool::isAncestorForChunk(int32_t ancestorId, int32_t chunkId) +bool FractureToolImpl::isAncestorForChunk(int32_t ancestorId, int32_t chunkId) { if (ancestorId == chunkId) { @@ -1059,7 +1147,7 @@ bool FractureTool::isAncestorForChunk(int32_t ancestorId, int32_t chunkId) return false; } -void FractureTool::eraseChunk(int32_t chunkId) +void FractureToolImpl::eraseChunk(int32_t chunkId) { deleteAllChildsOfChunk(chunkId); int32_t index = getChunkIndex(chunkId); @@ -1072,7 +1160,7 @@ void FractureTool::eraseChunk(int32_t chunkId) } -void FractureTool::deleteAllChildsOfChunk(int32_t chunkId) +void FractureToolImpl::deleteAllChildsOfChunk(int32_t chunkId) { std::vector<int32_t> chunkToDelete; for (uint32_t i = 0; i < mChunkData.size(); ++i) @@ -1091,7 +1179,7 @@ void FractureTool::deleteAllChildsOfChunk(int32_t chunkId) } } -void FractureTool::finalizeFracturing() +void FractureToolImpl::finalizeFracturing() { for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) { @@ -1100,7 +1188,7 @@ void FractureTool::finalizeFracturing() mChunkPostprocessors.resize(mChunkData.size()); for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) { - mChunkPostprocessors[i] = new ChunkPostProcessor(); + mChunkPostprocessors[i] = new Triangulator(); } for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) @@ -1131,89 +1219,38 @@ void FractureTool::finalizeFracturing() } -const std::vector<ChunkInfo>& FractureTool::getChunkList() +uint32_t FractureToolImpl::getChunkCount() const { - return mChunkData; + return (uint32_t)mChunkData.size(); } -void FractureTool::getBaseMesh(int32_t chunkIndex, std::vector<Triangle>& output) +const ChunkInfo& FractureToolImpl::getChunkInfo(int32_t chunkId) { - NVBLAST_ASSERT(mChunkPostprocessors.size() > 0); - if (mChunkPostprocessors.size() == 0) - { - return; // finalizeFracturing() should be called before getting mesh! - } - output = mChunkPostprocessors[chunkIndex]->getBaseMesh(); - - /* Scale mesh back */ - - for (uint32_t i = 0; i < output.size(); ++i) - { - output[i].a.p = output[i].a.p * mScaleFactor + mOffset; - output[i].b.p = output[i].b.p * mScaleFactor + mOffset; - output[i].c.p = output[i].c.p * mScaleFactor + mOffset; - } + return mChunkData[chunkId]; } -void FractureTool::getNoisedMesh(int32_t chunkIndex, std::vector<Triangle>& output) +uint32_t FractureToolImpl::getBaseMesh(int32_t chunkIndex, Triangle*& output) { NVBLAST_ASSERT(mChunkPostprocessors.size() > 0); if (mChunkPostprocessors.size() == 0) - { - return; // finalizeFracturing() should be called before getting mesh! - } - - if (mChunkData[chunkIndex].chunkId == 0) - { - output = mChunkPostprocessors[chunkIndex]->getBaseMesh(); - } - else - { - output = mChunkPostprocessors[chunkIndex]->getNoisyMesh(); + { + return 0; // finalizeFracturing() should be called before getting mesh! } + auto baseMesh = mChunkPostprocessors[chunkIndex]->getBaseMesh(); + output = new Triangle[baseMesh.size()]; + memcpy(output, baseMesh.data(), baseMesh.size() * sizeof(Triangle)); - for (uint32_t i = 0; i < output.size(); ++i) - { - output[i].a.p = output[i].a.p * mScaleFactor + mOffset; - output[i].b.p = output[i].b.p * mScaleFactor + mOffset; - output[i].c.p = output[i].c.p * mScaleFactor + mOffset; - } -} + /* Scale mesh back */ -void FractureTool::tesselate(float averateEdgeLength) -{ - NVBLAST_ASSERT(mChunkPostprocessors.size() > 0); - if (mChunkPostprocessors.size() == 0) + for (uint32_t i = 0; i < baseMesh.size(); ++i) { - return; // finalizeFracturing() should be called before tesselation! + Triangle& triangle = output[i]; + triangle.a.p = triangle.a.p * mScaleFactor + mOffset; + triangle.b.p = triangle.b.p * mScaleFactor + mOffset; + triangle.c.p = triangle.c.p * mScaleFactor + mOffset; } - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - if (mChunkData[i].chunkId == 0) // skip source mesh - { - continue; - } - mChunkPostprocessors[i]->tesselateInternalSurface(averateEdgeLength / mScaleFactor); - } -} - -void FractureTool::applyNoise(float amplitude, float frequency, int32_t octaves, float falloff, int32_t relaxIterations, float relaxFactor, int32_t seed) -{ - octaves = octaves <= 0 ? 1 : octaves; - if (mChunkPostprocessors.empty()) - { - return; - } - SimplexNoise noise(amplitude / mScaleFactor, frequency * mScaleFactor, octaves, seed); - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - if (mChunkData[i].chunkId == 0) // skip source mesh - { - continue; - } - mChunkPostprocessors[i]->applyNoise(noise, falloff, relaxIterations, relaxFactor); - } + return baseMesh.size(); } float getVolume(std::vector<Triangle>& triangles) @@ -1230,7 +1267,7 @@ float getVolume(std::vector<Triangle>& triangles) return (1.0f / 6.0f) * PxAbs(volume); } -float FractureTool::getMeshOverlap(Mesh& meshA, Mesh& meshB) +float FractureToolImpl::getMeshOverlap(const Mesh& meshA, const Mesh& meshB) { BooleanEvaluator bTool; bTool.performBoolean(&meshA, &meshB, BooleanConfigurations::BOOLEAN_INTERSECION()); @@ -1240,7 +1277,7 @@ float FractureTool::getMeshOverlap(Mesh& meshA, Mesh& meshB) return 0.0f; } - ChunkPostProcessor postProcessor; + Triangulator postProcessor; postProcessor.triangulate(&meshA); float baseVolume = getVolume(postProcessor.getBaseMesh()); @@ -1297,19 +1334,19 @@ void weldVertices(std::map<Vertex, uint32_t, VrtComp>& vertexMapping, std::vecto } -void FractureTool::setRemoveIslands(bool isRemoveIslands) +void FractureToolImpl::setRemoveIslands(bool isRemoveIslands) { mRemoveIslands = isRemoveIslands; } -int32_t FractureTool::islandDetectionAndRemoving(int32_t chunkId) +int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId) { if (chunkId == 0) { return 0; } int32_t chunkIndex = getChunkIndex(chunkId); - ChunkPostProcessor prc; + Triangulator prc; prc.triangulate(mChunkData[chunkIndex].meshData); Mesh* chunk = mChunkData[chunkIndex].meshData; @@ -1403,7 +1440,7 @@ int32_t FractureTool::islandDetectionAndRemoving(int32_t chunkId) std::vector<uint32_t> compVertexMapping(chunk->getVerticesCount(), 0); - Vertex* vrts = chunk->getVertices(); + const Vertex* vrts = chunk->getVertices(); for (uint32_t v = 0; v < chunk->getVerticesCount(); ++v) { int32_t vComp = comps[mapping[v]]; @@ -1411,8 +1448,8 @@ int32_t FractureTool::islandDetectionAndRemoving(int32_t chunkId) compVertices[vComp].push_back(vrts[v]); } - Facet* fcb = chunk->getFacetsBuffer(); - Edge* edb = chunk->getEdges(); + const Facet* fcb = chunk->getFacetsBuffer(); + const Edge* edb = chunk->getEdges(); for (uint32_t fc = 0; fc < chunk->getFacetCount(); ++fc) { @@ -1436,13 +1473,13 @@ int32_t FractureTool::islandDetectionAndRemoving(int32_t chunkId) } delete mChunkData[chunkIndex].meshData; - mChunkData[chunkIndex].meshData = new Mesh(compVertices[0].data(), compEdges[0].data(), compFacets[0].data(), static_cast<uint32_t>(compVertices[0].size()), + mChunkData[chunkIndex].meshData = new MeshImpl(compVertices[0].data(), compEdges[0].data(), compFacets[0].data(), static_cast<uint32_t>(compVertices[0].size()), static_cast<uint32_t>(compEdges[0].size()), static_cast<uint32_t>(compFacets[0].size()));; for (int32_t i = 1; i < cComp; ++i) { mChunkData.push_back(ChunkInfo(mChunkData[chunkIndex])); mChunkData.back().chunkId = mChunkIdCounter++; - mChunkData.back().meshData = new Mesh(compVertices[i].data(), compEdges[i].data(), compFacets[i].data(), static_cast<uint32_t>(compVertices[i].size()), + mChunkData.back().meshData = new MeshImpl(compVertices[i].data(), compEdges[i].data(), compFacets[i].data(), static_cast<uint32_t>(compVertices[i].size()), static_cast<uint32_t>(compEdges[i].size()), static_cast<uint32_t>(compFacets[i].size())); } @@ -1451,60 +1488,52 @@ int32_t FractureTool::islandDetectionAndRemoving(int32_t chunkId) return 0; } -void FractureTool::getBufferedBaseMeshes(std::vector<Vertex>& vertexBuffer, std::vector<std::vector<uint32_t> >& indexBuffer) +uint32_t FractureToolImpl::getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t*& indexBuffer, + uint32_t*& indexBufferOffsets) { std::map<Vertex, uint32_t, VrtComp> vertexMapping; - vertexBuffer.clear(); - indexBuffer.clear(); - indexBuffer.resize(mChunkPostprocessors.size()); + std::vector<Vertex> _vertexBuffer; + std::vector<std::vector<uint32_t>> _indexBuffer(mChunkPostprocessors.size()); + + indexBufferOffsets = new uint32_t[mChunkPostprocessors.size() + 1]; + uint32_t totalIndices = 0; for (uint32_t ch = 0; ch < mChunkPostprocessors.size(); ++ch) { std::vector<Triangle>& trb = mChunkPostprocessors[ch]->getBaseMesh(); - weldVertices(vertexMapping, vertexBuffer, indexBuffer[ch], trb); + + weldVertices(vertexMapping, _vertexBuffer, _indexBuffer[ch], trb); + + indexBufferOffsets[ch] = totalIndices; + totalIndices += _indexBuffer[ch].size(); } - for (uint32_t i = 0; i < vertexBuffer.size(); ++i) + indexBufferOffsets[mChunkPostprocessors.size()] = totalIndices; + + for (uint32_t i = 0; i < _vertexBuffer.size(); ++i) { - vertexBuffer[i].p = vertexBuffer[i].p * mScaleFactor + mOffset; + _vertexBuffer[i].p = _vertexBuffer[i].p * mScaleFactor + mOffset; } -} -int32_t FractureTool::getChunkId(int32_t chunkIndex) -{ - if (chunkIndex < 0 || static_cast<uint32_t>(chunkIndex) >= mChunkData.size()) + vertexBuffer = new Vertex[_vertexBuffer.size()]; + indexBuffer = new uint32_t[totalIndices]; + + memcpy(vertexBuffer, _vertexBuffer.data(), _vertexBuffer.size() * sizeof(Vertex)); + for (uint32_t ch = 0; ch < _indexBuffer.size(); ++ch) { - return -1; + memcpy(indexBuffer + indexBufferOffsets[ch], _indexBuffer[ch].data(), _indexBuffer[ch].size() * sizeof(uint32_t)); } - return mChunkData[chunkIndex].chunkId; + + return _vertexBuffer.size(); } -void FractureTool::getBufferedNoiseMeshes(std::vector<Vertex>& vertexBuffer, std::vector<std::vector<uint32_t> >& indexBuffer) +int32_t FractureToolImpl::getChunkId(int32_t chunkIndex) { - std::map<Vertex, uint32_t, VrtComp> vertexMapping; - vertexBuffer.clear(); - indexBuffer.clear(); - indexBuffer.resize(mChunkPostprocessors.size()); - - for (uint32_t ch = 0; ch < mChunkPostprocessors.size(); ++ch) - { - if (ch == 0) - { - std::vector<Triangle>& trb = mChunkPostprocessors[ch]->getBaseMesh(); - weldVertices(vertexMapping, vertexBuffer, indexBuffer[ch], trb); - } - else - { - std::vector<Triangle>& trb = mChunkPostprocessors[ch]->getNoisyMesh(); - weldVertices(vertexMapping, vertexBuffer, indexBuffer[ch], trb); - } - } - for (uint32_t i = 0; i < vertexBuffer.size(); ++i) + if (chunkIndex < 0 || static_cast<uint32_t>(chunkIndex) >= mChunkData.size()) { - vertexBuffer[i].p = vertexBuffer[i].p * mScaleFactor + mOffset; + return -1; } + return mChunkData[chunkIndex].chunkId; } - } // namespace Blast } // namespace Nv - diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h new file mode 100644 index 0000000..9b656e3 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h @@ -0,0 +1,330 @@ +/* +* 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 NVBLASTAUTHORINGFRACTURETOOLIMPL_H +#define NVBLASTAUTHORINGFRACTURETOOLIMPL_H + +#include "NvBlastExtAuthoringFractureTool.h" +#include "NvBlastExtAuthoringMesh.h" +#include <vector> + +namespace Nv +{ +namespace Blast +{ + +class SpatialAccelerator; +class Triangulator; + + +/** + Class for voronoi sites generation inside supplied mesh. +*/ +class VoronoiSitesGeneratorImpl : public VoronoiSitesGenerator +{ +public: + + /** + Voronoi sites should not be generated outside of the fractured mesh, so VoronoiSitesGenerator + should be supplied with fracture mesh. + \param[in] mesh Fracture mesh + \param[in] rnd User supplied random value generator. + \return + */ + VoronoiSitesGeneratorImpl(const Mesh* mesh, RandomGeneratorBase* rnd); + ~VoronoiSitesGeneratorImpl(); + + void release() override; + + /** + Set base fracture mesh + */ + void setBaseMesh(const Mesh* m) override; + + /** + Access to generated voronoi sites. + \note User should call NVBLAST_FREE for hulls and hullsOffset when it not needed anymore + \param[out] Pointer to generated voronoi sites + \return Count of generated voronoi sites. + */ + uint32_t getVoronoiSites(const physx::PxVec3*& sites) override; + + /** + Add site in particular point + \param[in] site Site coordinates + */ + void addSite(const physx::PxVec3& site) override; + /** + Uniformly generate sites inside the mesh + \param[in] numberOfSites Number of generated sites + */ + void uniformlyGenerateSitesInMesh(uint32_t numberOfSites) override; + + /** + Generate sites in clustered fashion + \param[in] numberOfClusters Number of generated clusters + \param[in] sitesPerCluster Number of sites in each cluster + \param[in] clusterRadius Voronoi cells cluster radius + */ + void clusteredSitesGeneration(uint32_t numberOfClusters, uint32_t sitesPerCluster, float clusterRadius) override; + + /** + Radial pattern of sites generation + \param[in] center Center of generated pattern + \param[in] normal Normal to plane in which sites are generated + \param[in] radius Pattern radius + \param[in] angularSteps Number of angular steps + \param[in] radialSteps Number of radial steps + \param[in] angleOffset Angle offset at each radial step + \param[in] variability Randomness of sites distribution + */ + void radialPattern(const physx::PxVec3& center, const physx::PxVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset = 0.0f, float variability = 0.0f) override; + + /** + Generate sites inside sphere + \param[in] count Count of generated sites + \param[in] radius Radius of sphere + \param[in] center Center of sphere + */ + void generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center) override; + /** + Set stencil mesh. With stencil mesh sites are generated only inside both of fracture and stencil meshes. + \param[in] stencil Stencil mesh. + */ + void setStencil(const Mesh* stencil) override; + /** + Removes stencil mesh + */ + void clearStencil() override; + + /** + Deletes sites inside supplied sphere + \param[in] radius Radius of sphere + \param[in] center Center of sphere + \param[in] eraserProbability Probability of removing some particular site + */ + void deleteInSphere(const float radius, const physx::PxVec3& center, const float eraserProbability = 1) override; + +private: + std::vector <physx::PxVec3> mGeneratedSites; + const Mesh* mMesh; + const Mesh* mStencil; + RandomGeneratorBase* mRnd; + SpatialAccelerator* mAccelerator; +}; + + + +/** + FractureTool class provides methods to fracture provided mesh and generate Blast asset data +*/ +class FractureToolImpl : public FractureTool +{ + +public: + + /** + FractureTool can log asset creation info if logCallback is provided. + */ + FractureToolImpl() + { + mPlaneIndexerOffset = 1; + mChunkIdCounter = 0; + mRemoveIslands = false; + } + + ~FractureToolImpl() + { + reset(); + } + + void release() override; + + /** + Reset FractureTool state. + */ + void reset() override; + + + /** + Set input mesh wich will be fractured, FractureTool will be reseted. + */ + void setSourceMesh(const Mesh* mesh) override; + + /** + Get chunk mesh in polygonal representation + */ + Mesh* createChunkMesh(int32_t chunkId) override; + + /** + Input mesh is scaled and transformed internally to fit unit cube centered in origin. + Method provides offset vector and scale parameter; + */ + void getTransformation(physx::PxVec3& offset, float& scale) override; + + + /** + Fractures specified chunk with voronoi method. + \param[in] chunkId Chunk to fracture + \param[in] cellPoints Array of voronoi sites + \param[in] replaceChunk if 'true', newly generated chunks will replace source chunk, if 'false', newly generated chunks will be at next depth level, source chunk will be parent for them. + Case replaceChunk == true && chunkId == 0 considered as wrong input parameters + \return If 0, fracturing is successful. + */ + int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPoints, bool replaceChunk) override; + + /** + Fractures specified chunk with voronoi method. Cells can be scaled along x,y,z axes. + \param[in] chunkId Chunk to fracture + \param[in] cellPoints Array of voronoi sites + \param[in] cellPoints Array of voronoi sites + \param[in] scale Voronoi cells scaling factor + \param[in] replaceChunk if 'true', newly generated chunks will replace source chunk, if 'false', newly generated chunks will be at next depth level, source chunk will be parent for them. + Case replaceChunk == true && chunkId == 0 considered as wrong input parameters + \return If 0, fracturing is successful. + */ + int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPoints, const physx::PxVec3& scale, bool replaceChunk) override; + + + /** + Fractures specified chunk with slicing method. + \param[in] chunkId Chunk to fracture + \param[in] conf Slicing parameters, see SlicingConfiguration. + \param[in] replaceChunk if 'true', newly generated chunks will replace source chunk, if 'false', newly generated chunks will be at next depth level, source chunk will be parent for them. + Case replaceChunk == true && chunkId == 0 considered as wrong input parameters + \param[in] rnd User supplied random number generator + + \return If 0, fracturing is successful. + */ + int32_t slicing(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) override; + + + /** + Creates resulting fractured mesh geometry from intermediate format + */ + void finalizeFracturing() override; + + uint32_t getChunkCount() const override; + + /** + Get chunk information + */ + const ChunkInfo& getChunkInfo(int32_t chunkIndex) override; + + /** + Get percentage of mesh overlap. + percentage computed as volume(intersection(meshA , meshB)) / volume (meshA) + \param[in] meshA Mesh A + \param[in] meshB Mesh B + \return mesh overlap percentage + */ + float getMeshOverlap(const Mesh& meshA, const Mesh& meshB) override; + + /** + Get chunk base mesh + \note User should call NVBLAST_FREE for output when it not needed anymore + \param[in] chunkIndex Chunk index + \param[out] output Array of triangles to be filled + \return number of triangles in base mesh + */ + uint32_t getBaseMesh(int32_t chunkIndex, Triangle*& output) override; + + /** + Return index of chunk with specified chunkId + \param[in] chunkId Chunk ID + \return Chunk index in internal buffer, if not exist -1 is returned. + */ + int32_t getChunkIndex(int32_t chunkId) override; + + /** + Return id of chunk with specified index. + \param[in] chunkIndex Chunk index + \return Chunk id or -1 if there is no such chunk. + */ + int32_t getChunkId(int32_t chunkIndex) override; + + /** + Return depth level of the given chunk + \param[in] chunkId Chunk ID + \return Chunk depth or -1 if there is no such chunk. + */ + int32_t getChunkDepth(int32_t chunkId) override; + + /** + Return array of chunks IDs with given depth. + \note User should call NVBLAST_FREE for chunkIds when it not needed anymore + \param[in] depth Chunk depth + \param[out] Pointer to array of chunk IDs + \return Number of chunks in array + */ + uint32_t getChunksIdAtDepth(uint32_t depth, int32_t*& chunkIds) override; + + + /** + Get result geometry without noise as vertex and index buffers, where index buffers contain series of triplets + which represent triangles. + \note User should call NVBLAST_FREE for vertexBuffer, indexBuffer and indexBufferOffsets when it not needed anymore + \param[out] vertexBuffer Array of vertices to be filled + \param[out] indexBuffer Array of indices to be filled + \param[out] indexBufferOffsets Array of offsets in indexBuffer for each base mesh. + Contains getChunkCount() + 1 elements. Last one is indexBuffer size + \return Number of vertices in vertexBuffer + */ + uint32_t getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t*& indexBuffer, uint32_t*& indexBufferOffsets) override; + + /** + Set automatic islands removing. May cause instabilities. + \param[in] isRemoveIslands Flag whether remove or not islands. + */ + void setRemoveIslands(bool isRemoveIslands) override; + + /** + Try find islands and remove them on some specifical chunk. If chunk has childs, island removing can lead to wrong results! Apply it before further chunk splitting. + \param[in] chunkId Chunk ID which should be checked for islands + \return Number of found islands is returned + */ + int32_t islandDetectionAndRemoving(int32_t chunkId) override; + + /** + Check if input mesh contains open edges. Open edges can lead to wrong fracturing results. + \return true if mesh contains open edges + */ + bool isMeshContainOpenEdges(const Mesh* input) override; + +private: + void eraseChunk(int32_t chunkId); + bool isAncestorForChunk(int32_t ancestorId, int32_t chunkId); + void deleteAllChildsOfChunk(int32_t chunkId); + int32_t slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd); + +protected: + /** + Mesh scaled to unite-cube and translated to the origin + */ + float mScaleFactor; + physx::PxVec3 mOffset; + + /* Chunk mesh wrappers */ + std::vector<Triangulator*> mChunkPostprocessors; + + + + int32_t mPlaneIndexerOffset; + int32_t mChunkIdCounter; + std::vector<ChunkInfo> mChunkData; + + bool mRemoveIslands; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTAUTHORINGFRACTURETOOLIMPL_H diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringInternalCommon.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringInternalCommon.h index b8fb20e..862016f 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringInternalCommon.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringInternalCommon.h @@ -1,16 +1,35 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTINTERNALCOMMON_H #define NVBLASTINTERNALCOMMON_H #include "NvBlastExtAuthoringTypes.h" +#include <algorithm> using namespace physx; @@ -74,15 +93,15 @@ Computes best direction to project points. */ NV_FORCE_INLINE ProjectionDirections getProjectionDirection(const physx::PxVec3& normal) { - float maxv = std::max(abs(normal.x), std::max(abs(normal.y), abs(normal.z))); + float maxv = std::max(std::abs(normal.x), std::max(std::abs(normal.y), std::abs(normal.z))); ProjectionDirections retVal; - if (maxv == abs(normal.x)) + if (maxv == std::abs(normal.x)) { retVal = YZ_PLANE; if (normal.x < 0) retVal = (ProjectionDirections)((int)retVal | (int)OPPOSITE_WINDING); return retVal; } - if (maxv == abs(normal.y)) + if (maxv == std::abs(normal.y)) { retVal = ZX_PLANE; if (normal.y > 0) retVal = (ProjectionDirections)((int)retVal | (int)OPPOSITE_WINDING); @@ -187,6 +206,54 @@ NV_INLINE bool getPlaneSegmentIntersection(const PxPlane& pl, const PxVec3& a, c return true; } + +#define VEC_COMPARISON_OFFSET 1e-5f +/** +Vertex comparator for vertex welding. +*/ +struct VrtComp +{ + bool operator()(const Vertex& a, const Vertex& b) const + { + if (a.p.x + VEC_COMPARISON_OFFSET < b.p.x) return true; + if (a.p.x - VEC_COMPARISON_OFFSET > b.p.x) return false; + if (a.p.y + VEC_COMPARISON_OFFSET < b.p.y) return true; + if (a.p.y - VEC_COMPARISON_OFFSET > b.p.y) return false; + if (a.p.z + VEC_COMPARISON_OFFSET < b.p.z) return true; + if (a.p.z - VEC_COMPARISON_OFFSET > b.p.z) return false; + + if (a.n.x + 1e-3 < b.n.x) return true; + if (a.n.x - 1e-3 > b.n.x) return false; + if (a.n.y + 1e-3 < b.n.y) return true; + if (a.n.y - 1e-3 > b.n.y) return false; + if (a.n.z + 1e-3 < b.n.z) return true; + if (a.n.z - 1e-3 > b.n.z) return false; + + + if (a.uv[0].x + 1e-3 < b.uv[0].x) return true; + if (a.uv[0].x - 1e-3 > b.uv[0].x) return false; + if (a.uv[0].y + 1e-3 < b.uv[0].y) return true; + return false; + }; +}; + +/** +Vertex comparator for vertex welding (not accounts normal and uv parameters of vertice). +*/ +struct VrtPositionComparator +{ + bool operator()(const physx::PxVec3& a, const physx::PxVec3& b) const + { + if (a.x + VEC_COMPARISON_OFFSET < b.x) return true; + if (a.x - VEC_COMPARISON_OFFSET > b.x) return false; + if (a.y + VEC_COMPARISON_OFFSET < b.y) return true; + if (a.y - VEC_COMPARISON_OFFSET > b.y) return false; + if (a.z + VEC_COMPARISON_OFFSET < b.z) return true; + if (a.z - VEC_COMPARISON_OFFSET > b.z) return false; + return false; + }; +}; + } // namespace Blast } // namespace Nv diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp new file mode 100644 index 0000000..602ae75 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp @@ -0,0 +1,1626 @@ + +#include <PxVec3.h> +#include <PxVec2.h> +#include <vector> +#include <queue> +#include <map> + +#include <NvBlastExtAuthoringMeshCleanerImpl.h> +#include <NvBlastExtAuthoringMeshImpl.h> +#include <NvBlastExtAuthoringInternalCommon.h> +#include <boost/multiprecision/cpp_int.hpp> + + + + +using physx::PxVec3; +using physx::PxVec2; + +using namespace Nv::Blast; +using namespace boost::multiprecision; + +/** + Exact rational vector types. +*/ +struct RVec3 +{ + cpp_rational x, y, z; + RVec3() + { + + } + + bool isZero() + { + return x.is_zero() && y.is_zero() && z.is_zero(); + } + + RVec3(cpp_rational _x, cpp_rational _y, cpp_rational _z) + { + x = _x; + y = _y; + z = _z; + } + + RVec3(const PxVec3& p) + { + x = cpp_rational(p.x); + y = cpp_rational(p.y); + z = cpp_rational(p.z); + } + PxVec3 toVec3() + { + return PxVec3(x.convert_to<float>(), y.convert_to<float>(), z.convert_to<float>()); + } + + RVec3 operator-(const RVec3& b) const + { + return RVec3(x - b.x, y - b.y, z - b.z); + } + RVec3 operator+(const RVec3& b) const + { + return RVec3(x + b.x, y + b.y, z + b.z); + } + RVec3 cross(const RVec3& in) const + { + return RVec3(y * in.z - in.y * z, in.x * z - x * in.z, x * in.y - in.x * y); + } + cpp_rational dot(const RVec3& in) const + { + return x * in.x + y * in.y + z * in.z; + } + RVec3 operator*(const cpp_rational& in) const + { + return RVec3(x * in, y * in, z * in); + } + + +}; + +struct RVec2 +{ + cpp_rational x, y; + RVec2() + { + + } + + RVec2(cpp_rational _x, cpp_rational _y) + { + x = _x; + y = _y; + } + + RVec2(const PxVec2& p) + { + x = cpp_rational(p.x); + y = cpp_rational(p.y); + } + PxVec2 toVec2() + { + return PxVec2(x.convert_to<float>(), y.convert_to<float>()); + } + + RVec2 operator-(const RVec2& b) const + { + return RVec2(x - b.x, y - b.y); + } + RVec2 operator+(const RVec2& b) const + { + return RVec2(x + b.x, y + b.y); + } + cpp_rational cross(const RVec2& in) const + { + return x * in.y - y * in.x; + } + cpp_rational dot(const RVec2& in) const + { + return x * in.x + y * in.y; + } + RVec2 operator*(const cpp_rational& in) const + { + return RVec2(x * in, y * in); + } +}; +struct RatPlane +{ + RVec3 n; + cpp_rational d; + + RatPlane(const RVec3& a, const RVec3& b, const RVec3& c) + { + n = (b - a).cross(c - a); + d = -n.dot(a); + }; + cpp_rational distance(RVec3& in) + { + return n.dot(in) + d; + } +}; + +bool isSame(const RatPlane& a, const RatPlane& b) +{ + if (a.d != b.d) return false; + if (a.n.x != b.n.x || a.n.y != b.n.y || a.n.z != b.n.z) return false; + return true; +} + +RVec3 planeSegmInters(RVec3& a, RVec3& b, RatPlane& pl) +{ + cpp_rational t = -(a.dot(pl.n) + pl.d) / pl.n.dot(b - a); + RVec3 on = a + (b - a) * t; + return on; +} + +enum POINT_CLASS +{ + ON_AB = 0, + ON_BC = 1, + ON_AC = 2, + INSIDE_TR, + OUTSIDE_TR, + ON_VERTEX +}; + + +int32_t isPointInside(const RVec2& a, const RVec2& b, const RVec2& c, const RVec2& p) +{ + cpp_rational v1 = (b - a).cross(p - a); + cpp_rational v2 = (c - b).cross(p - b); + cpp_rational v3 = (a - c).cross(p - c); + + + + int32_t v1s = v1.sign(); + int32_t v2s = v2.sign(); + int32_t v3s = v3.sign(); + + if (v1s * v2s < 0 || v1s * v3s < 0 || v2s * v3s < 0) return OUTSIDE_TR; + + if (v1s == 0 && v2s == 0) return OUTSIDE_TR; + if (v1s == 0 && v3s == 0) return OUTSIDE_TR; + if (v2s == 0 && v3s == 0) return OUTSIDE_TR; + + if (v1s == 0) return ON_AB; + if (v2s == 0) return ON_BC; + if (v3s == 0) return ON_AC; + + return INSIDE_TR; +} + +RVec2 getProjectedPointWithWinding(const RVec3& point, ProjectionDirections dir) +{ + if (dir & YZ_PLANE) + { + if (dir & OPPOSITE_WINDING) + { + return RVec2(point.z, point.y); + } + else + return RVec2(point.y, point.z); + } + if (dir & ZX_PLANE) + { + if (dir & OPPOSITE_WINDING) + { + return RVec2(point.z, point.x); + } + return RVec2(point.x, point.z); + } + if (dir & OPPOSITE_WINDING) + { + return RVec2(point.y, point.x); + } + return RVec2(point.x, point.y); +} + +struct DelTriangle +{ + int32_t p[3]; + int32_t n[3]; + int32_t parentTriangle; + int32_t getEdWP(int32_t vrt) + { + if (p[0] == vrt) return 1; + if (p[1] == vrt) return 2; + if (p[2] == vrt) return 0; + return -1; + } + int32_t getEdId(int32_t v1, int32_t v2) + { + if (p[0] == v1 && p[1] == v2) return 0; + if (p[1] == v1 && p[2] == v2) return 1; + if (p[2] == v1 && p[0] == v2) return 2; + return -1; + } + int32_t getOppP(int32_t v1, int32_t v2) + { + if (p[0] == v1 && p[1] == v2) return 2; + if (p[1] == v1 && p[2] == v2) return 0; + if (p[2] == v1 && p[0] == v2) return 1; + return -1; + } + + int32_t getOppPoint(int32_t v1, int32_t v2) + { + if (p[0] != v1 && p[0] != v2) return p[0]; + if (p[1] != v1 && p[1] != v2) return p[1]; + if (p[2] != v1 && p[2] != v2) return p[2]; + return -1; + } + bool compare(const DelTriangle& t) const + { + if (p[0] == t.p[0] && p[1] == t.p[1] && p[2] == t.p[2]) return true; + if (p[1] == t.p[0] && p[2] == t.p[1] && p[0] == t.p[2]) return true; + if (p[2] == t.p[0] && p[0] == t.p[1] && p[1] == t.p[2]) return true; + return false; + } + +}; + +struct DelEdge +{ + int32_t s, e; + int32_t nr, nl; +}; + + +bool isIntersectsTriangle(RVec2& a, RVec2& b, RVec2& c, RVec2& s, RVec2& e) +{ + RVec2 vec = e - s; + + if ((a - s).cross(vec) * (b - s).cross(vec) < 0) + { + RVec2 vec2 = b - a; + if ((s - a).cross(vec2) * (e - a).cross(vec) < 0) return true; + } + + if ((b - s).cross(vec) * (c - s).cross(vec) < 0) + { + RVec2 vec2 = c - b; + if ((s - b).cross(vec2) * (e - b).cross(vec) < 0) return true; + } + + if ((a - s).cross(vec) * (c - s).cross(vec) < 0) + { + RVec2 vec2 = a - c; + if ((s - c).cross(vec2) * (e - c).cross(vec) < 0) return true; + } + + return false; +} + + +inline int32_t inCircumcircle(RVec2& a, RVec2& b, RVec2& c, RVec2& p) +{ + RVec2 ta = a - p; + RVec2 tb = b - p; + RVec2 tc = c - p; + cpp_rational ad = ta.dot(ta); + cpp_rational bd = tb.dot(tb); + cpp_rational cd = tc.dot(tc); + + cpp_rational pred = ta.x * (tb.y * cd - tc.y * bd) - ta.y * (tb.x * cd - tc.x * bd) + ad * (tb.x * tc.y - tc.x * tb.y); + + + if (pred > 0) return 1; + if (pred < 0) return -1; + return 0; +} + +int32_t getEdge(std::vector<DelEdge>& edges, int32_t s, int32_t e) +{ + for (uint32_t i = 0; i < edges.size(); ++i) + { + if (edges[i].s == s && edges[i].e == e) return i; + } + + edges.push_back(DelEdge()); + edges.back().s = s; + edges.back().e = e; + return edges.size() - 1; +} + +void reubildAdjacency(std::vector<DelTriangle>& state) +{ + for (uint32_t i = 0; i < state.size(); ++i) + { + state[i].n[0] = state[i].n[1] = state[i].n[2] = -1; + } + for (uint32_t i = 0; i < state.size(); ++i) + { + if (state[i].p[0] == -1) continue; + for (uint32_t j = i + 1; j < state.size(); ++j) + { + if (state[j].p[0] == -1) continue; + for (uint32_t k = 0; k < 3; ++k) + { + for (uint32_t c = 0; c < 3; ++c) + { + if (state[i].p[k] == state[j].p[(c + 1) % 3] && state[i].p[(k + 1) % 3] == state[j].p[c]) { state[i].n[k] = j; state[j].n[c] = i; } + } + } + } + } +} + +void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, int32_t p, const std::vector<Edge>& edges) +{ + std::queue<int32_t> triangleToCheck; + + for (uint32_t i = 0; i < state.size(); ++i) + { + if (state[i].p[0] == -1) continue; + DelTriangle ctr = state[i]; + int32_t cv = isPointInside(vertices[ctr.p[0]], vertices[ctr.p[1]], vertices[ctr.p[2]], vertices[p]); + + if (cv == OUTSIDE_TR) continue; + if (cv == INSIDE_TR) + { + uint32_t taInd = state.size(); + uint32_t tbInd = state.size() + 1; + uint32_t tcInd = state.size() + 2; + state.resize(state.size() + 3); + + state[taInd].p[0] = ctr.p[2]; + state[taInd].p[1] = ctr.p[0]; + state[taInd].p[2] = p; + + state[taInd].n[0] = ctr.n[2]; + state[taInd].n[1] = tbInd; + state[taInd].n[2] = tcInd; + + state[tbInd].p[0] = ctr.p[0]; + state[tbInd].p[1] = ctr.p[1]; + state[tbInd].p[2] = p; + + state[tbInd].n[0] = ctr.n[0]; + state[tbInd].n[1] = tcInd; + state[tbInd].n[2] = taInd; + + state[tcInd].p[0] = ctr.p[1]; + state[tcInd].p[1] = ctr.p[2]; + state[tcInd].p[2] = p; + + state[tcInd].n[0] = ctr.n[1]; + state[tcInd].n[1] = taInd; + state[tcInd].n[2] = tbInd; + + + triangleToCheck.push(taInd); + triangleToCheck.push(tbInd); + triangleToCheck.push(tcInd); + + + /** + Change neighboors + */ + int32_t nb = state[i].n[0]; + if (nb != -1) + state[nb].n[state[nb].getEdId(state[i].p[1], state[i].p[0])] = tbInd; + nb = state[i].n[1]; + if (nb != -1) + state[nb].n[state[nb].getEdId(state[i].p[2], state[i].p[1])] = tcInd; + nb = state[i].n[2]; + if (nb != -1) + state[nb].n[state[nb].getEdId(state[i].p[0], state[i].p[2])] = taInd; + + + state[i].p[0] = -1; + } + else + { + uint32_t taInd = state.size(); + uint32_t tbInd = state.size() + 1; + state.resize(state.size() + 2); + + int32_t bPoint = state[i].p[(cv + 2) % 3]; + + state[taInd].p[0] = bPoint; + state[taInd].p[1] = state[i].p[cv]; + state[taInd].p[2] = p; + + state[tbInd].p[0] = bPoint; + state[tbInd].p[1] = p; + state[tbInd].p[2] = state[i].p[(cv + 1) % 3]; + + state[taInd].n[0] = state[i].n[(cv + 2) % 3]; + state[taInd].n[1] = -1; + state[taInd].n[2] = tbInd; + + state[tbInd].n[0] = taInd; + state[tbInd].n[1] = -1; + state[tbInd].n[2] = state[i].n[(cv + 1) % 3]; + + if (state[i].n[(cv + 1) % 3] != -1) + for (int32_t k = 0; k < 3; ++k) + if (state[state[i].n[(cv + 1) % 3]].n[k] == (int32_t)i) { + state[state[i].n[(cv + 1) % 3]].n[k] = tbInd; break; + } + if (state[i].n[(cv + 2) % 3] != -1) + for (int32_t k = 0; k < 3; ++k) + if (state[state[i].n[(cv + 2) % 3]].n[k] == (int32_t)i) { + state[state[i].n[(cv + 2) % 3]].n[k] = taInd; break; + } + + triangleToCheck.push(taInd); + triangleToCheck.push(tbInd); + + int32_t total = 2; + int32_t oppositeTr = 0; + if (state[i].n[cv] != -1) + { + oppositeTr = state[i].n[cv]; + total += 2; + uint32_t tcInd = state.size(); + uint32_t tdInd = state.size() + 1; + state.resize(state.size() + 2); + + int32_t oped = state[oppositeTr].getEdId(state[i].p[(cv + 1) % 3], state[i].p[cv]); + + + state[tcInd].n[0] = state[oppositeTr].n[(oped + 2) % 3]; + state[tcInd].n[1] = tbInd; + state[tbInd].n[1] = tcInd; + state[tcInd].n[2] = tdInd; + + state[tdInd].n[0] = tcInd; + state[tdInd].n[1] = taInd; + state[taInd].n[1] = tdInd; + state[tdInd].n[2] = state[oppositeTr].n[(oped + 1) % 3]; + if (state[oppositeTr].n[(oped + 2) % 3] != -1) + for (int32_t k = 0; k < 3; ++k) + if (state[state[oppositeTr].n[(oped + 2) % 3]].n[k] == oppositeTr) { + state[state[oppositeTr].n[(oped + 2) % 3]].n[k] = tcInd; break; + } + if (state[oppositeTr].n[(oped + 1) % 3] != -1) + for (int32_t k = 0; k < 3; ++k) + if (state[state[oppositeTr].n[(oped + 1) % 3]].n[k] == oppositeTr) { + state[state[oppositeTr].n[(oped + 1) % 3]].n[k] = tdInd; break; + } + + int32_t pop = state[oppositeTr].p[(oped + 2) % 3]; + state[tcInd].p[0] = pop; + state[tcInd].p[1] = state[i].p[(cv + 1) % 3]; + state[tcInd].p[2] = p; + + state[tdInd].p[0] = pop; + state[tdInd].p[1] = p; + state[tdInd].p[2] = state[i].p[cv]; + + + state[oppositeTr].p[0] = -1; + triangleToCheck.push(tcInd); + triangleToCheck.push(tdInd); + } + state[i].p[0] = -1; + } + break; + } + + while (!triangleToCheck.empty()) + { + int32_t ctrid = triangleToCheck.front(); + triangleToCheck.pop(); + DelTriangle& ctr = state[ctrid]; + int32_t oppTr = -5; + int32_t ced = 0; + for (uint32_t i = 0; i < 3; ++i) + { + if (ctr.p[i] != p && ctr.p[(i + 1) % 3] != p) + { + ced = i; + oppTr = ctr.n[i]; + break; + } + } + if (oppTr == -1) continue; + bool toCont = false; + for (size_t i = 0; i < edges.size(); ++i) + { + if ((int32_t)edges[i].s == ctr.p[ced] && ctr.p[(ced + 1) % 3] == (int32_t)edges[i].e) { toCont = true; break; } + if ((int32_t)edges[i].e == ctr.p[ced] && ctr.p[(ced + 1) % 3] == (int32_t)edges[i].s) { toCont = true; break; } + } + if (toCont) continue; + + + DelTriangle& otr = state[oppTr]; + + if (inCircumcircle(vertices[state[oppTr].p[0]], vertices[state[oppTr].p[1]], vertices[state[oppTr].p[2]], vertices[p]) > 0) + { + int32_t notPIndx = 0; + for (; notPIndx < 3; ++notPIndx) + { + if (otr.p[notPIndx] != ctr.p[0] && otr.p[notPIndx] != ctr.p[1] && otr.p[notPIndx] != ctr.p[2]) + break; + } + + int32_t oppCed = state[oppTr].getEdId(ctr.p[(ced + 1) % 3], ctr.p[ced]); + + int32_t ntr1 = ctrid, ntr2 = oppTr; + + DelTriangle nt1, nt2; + nt1.p[0] = state[oppTr].p[notPIndx]; + nt1.p[1] = p; + nt1.n[0] = ntr2; + nt1.p[2] = ctr.p[ced]; + nt1.n[1] = ctr.n[(ced + 2) % 3]; + nt1.n[2] = otr.n[(oppCed + 1) % 3]; + + if (nt1.n[2] != -1) + for (uint32_t k = 0; k < 3; ++k) + if (state[nt1.n[2]].n[k] == oppTr) state[nt1.n[2]].n[k] = ntr1; + + nt2.p[0] = p; + nt2.p[1] = state[oppTr].p[notPIndx]; + nt2.n[0] = ntr1; + nt2.p[2] = ctr.p[(ced + 1) % 3]; + nt2.n[1] = otr.n[(oppCed + 2) % 3]; + nt2.n[2] = ctr.n[(ced + 1) % 3]; + if (nt2.n[2] != -1) + for (uint32_t k = 0; k < 3; ++k) + if (state[nt2.n[2]].n[k] == ctrid) state[nt2.n[2]].n[k] = ntr2; + state[ntr1] = nt1; + state[ntr2] = nt2; + triangleToCheck.push(ntr1); + triangleToCheck.push(ntr2); + } + } + +} + +bool edgeIsIntersected(const RVec2& a, const RVec2& b, const RVec2& es, const RVec2& ee) +{ + RVec2 t = b - a; + cpp_rational temp = (es - a).cross(t) * (ee - a).cross(t); + + if (temp < 0) + { + t = es - ee; + if ((a - ee).cross(t) * (b - ee).cross(t) <= 0) return true; + } + return false; +} + +void triangulatePseudoPolygon(std::vector<RVec2>& vertices, int32_t ba, int32_t bb, std::vector<int32_t>& pseudo, std::vector<DelTriangle>& output) +{ + if (pseudo.empty()) return; + + int32_t c = 0; + if (pseudo.size() > 1) + { + for (uint32_t i = 1; i < pseudo.size(); ++i) + { + if (inCircumcircle(vertices[ba], vertices[bb], vertices[pseudo[c]], vertices[pseudo[i]]) > 0) + { + c = i; + } + } + std::vector<int32_t> toLeft; + std::vector<int32_t> toRight; + + for (int32_t t = 0; t < c; ++t) + { + toLeft.push_back(pseudo[t]); + } + for (size_t t = c + 1; t < pseudo.size(); ++t) + { + toRight.push_back(pseudo[t]); + } + if (toLeft.size() > 0) + triangulatePseudoPolygon(vertices, ba, pseudo[c], toLeft, output); + if (toRight.size() > 0) + triangulatePseudoPolygon(vertices, pseudo[c], bb, toRight, output); + } + output.push_back(DelTriangle()); + output.back().p[0] = ba; + output.back().p[1] = bb; + output.back().p[2] = pseudo[c]; +} + + + +void insertEdge(std::vector<RVec2>& vertices, std::vector<DelTriangle>& output, int32_t edBeg, int32_t edEnd) +{ + bool hasEdge = false; + for (auto& it : output) + { + for (uint32_t i = 0; i < 3; ++i) + if ((it.p[i] == edBeg || it.p[i] == edEnd) && (it.p[(i + 1) % 3] == edBeg || it.p[(i + 1) % 3] == edEnd)) + { + hasEdge = true; + } + } + if (hasEdge) return; + + int32_t startTriangle = -1; + int32_t edg = -1; + for (uint32_t i = 0; i < output.size(); ++i) + { + if (output[i].p[0] == -1) continue; + + if (output[i].p[0] == edBeg || output[i].p[1] == edBeg || output[i].p[2] == edBeg) + { + edg = output[i].getEdWP(edBeg); + if (edgeIsIntersected(vertices[edBeg], vertices[edEnd], vertices[output[i].p[edg]], vertices[output[i].p[(edg + 1) % 3]])) + { + startTriangle = i; + break; + } + } + } + if (startTriangle == -1) + { + return; + } + int32_t cvertex = edBeg; + + std::vector<int32_t> pointsAboveEdge; + std::vector<int32_t> pointsBelowEdge; + + RVec2 vec = vertices[edEnd] - vertices[edBeg]; + + if (vec.cross(vertices[output[startTriangle].p[edg]] - vertices[edBeg]) > 0) + { + pointsAboveEdge.push_back(output[startTriangle].p[edg]); + pointsBelowEdge.push_back(output[startTriangle].p[(edg + 1) % 3]); + } + else + { + pointsBelowEdge.push_back(output[startTriangle].p[edg]); + pointsAboveEdge.push_back(output[startTriangle].p[(edg + 1) % 3]); + } + + while (1) + { + DelTriangle& ctr = output[startTriangle]; + int32_t oed = ctr.getEdWP(cvertex); + int32_t nextTriangle = ctr.n[oed]; + + if (output[nextTriangle].p[0] == edEnd || output[nextTriangle].p[1] == edEnd || output[nextTriangle].p[2] == edEnd) + { + ctr.p[0] = -1; + output[nextTriangle].p[0] = -1; + break; + } + + DelTriangle& otr = output[nextTriangle]; + int32_t opp = otr.p[otr.getOppP(ctr.p[(oed + 1) % 3], ctr.p[oed % 3])]; + + int32_t nextPoint = 0; + if (vec.cross((vertices[opp] - vertices[edBeg])) > 0) + { + pointsAboveEdge.push_back(opp); + if (vec.cross(vertices[ctr.p[(oed + 1) % 3]] - vertices[edBeg]) > 0) + { + nextPoint = ctr.p[(oed + 1) % 3]; + } + else + { + nextPoint = ctr.p[oed]; + } + } + else + { + pointsBelowEdge.push_back(opp); + + if (vec.cross(vertices[ctr.p[(oed + 1) % 3]] - vertices[edBeg]) < 0) + { + nextPoint = ctr.p[(oed + 1) % 3]; + } + else + { + nextPoint = ctr.p[oed]; + } + } + startTriangle = nextTriangle; + cvertex = nextPoint; + ctr.p[0] = -1; + } + triangulatePseudoPolygon(vertices, edBeg, edEnd, pointsAboveEdge, output); + std::reverse(pointsBelowEdge.begin(), pointsBelowEdge.end()); + triangulatePseudoPolygon(vertices, edEnd, edBeg, pointsBelowEdge, output); + reubildAdjacency(output); +} + + + + + + +void buildCDT(std::vector<RVec3>& vertices, std::vector<Edge>& edges, std::vector<DelTriangle>& output, ProjectionDirections dr) +{ + std::vector<DelTriangle> state; + + DelTriangle crt; + std::vector<bool> added(vertices.size(), false); + + for (uint32_t i = 0; i < 3; ++i) + { + crt.p[i] = edges[i].s; + added[edges[i].s] = true; + crt.n[i] = -1; // dont have neighboors; + } + state.push_back(crt); + + + std::vector<RVec2> p2d(vertices.size()); + for (uint32_t i = 0; i < vertices.size(); ++i) + { + p2d[i] = getProjectedPointWithWinding(vertices[i], dr); + } + + for (size_t i = 0; i < edges.size(); ++i) + { + if (!added[edges[i].s]) + { + insertPoint(p2d, state, edges[i].s, edges); + added[edges[i].s] = true; + } + if (!added[edges[i].e]) + { + insertPoint(p2d, state, edges[i].e, edges); + added[edges[i].e] = true; + } + if (edges[i].s != edges[i].e) + { + insertEdge(p2d, state, edges[i].s, edges[i].e); + } + } + + for (uint32_t t = 0; t < state.size(); ++t) + { + if (state[t].p[0] != -1) + { + output.push_back(state[t]); + } + } +} + +int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, ProjectionDirections dir, std::vector<cpp_rational>& t1v, std::vector<cpp_rational>& t2v); + +void getTriangleIntersectionCoplanar(uint32_t tr1, uint32_t tr2, std::vector<std::vector<RVec3>>& stencil, ProjectionDirections dr) +{ + std::vector<cpp_rational> intr1[3]; + std::vector<cpp_rational> intr2[3]; + + RVec3 p1[3]; + p1[0] = stencil[tr1][0]; + p1[1] = stencil[tr1][1]; + p1[2] = stencil[tr1][3]; + + RVec3 p2[3]; + p2[0] = stencil[tr2][0]; + p2[1] = stencil[tr2][1]; + p2[2] = stencil[tr2][3]; + + for (uint32_t i = 0; i < 3; ++i) + { + for (uint32_t j = 0; j < 3; ++j) + { + intersectSegments(p1[i], p1[(i + 1) % 3], p2[j], p2[(j + 1) % 3], dr, intr1[i], intr2[j]); + } + } + + int32_t inRel1[3]; + for (uint32_t i = 0; i < 3; ++i) + { + inRel1[i] = isPointInside(getProjectedPointWithWinding(p2[0], dr), getProjectedPointWithWinding(p2[1], dr), getProjectedPointWithWinding(p2[2], dr), getProjectedPointWithWinding(p1[i], dr)); + } + + int32_t inRel2[3]; + for (uint32_t i = 0; i < 3; ++i) + { + inRel2[i] = isPointInside(getProjectedPointWithWinding(p1[0], dr), getProjectedPointWithWinding(p1[1], dr), getProjectedPointWithWinding(p1[2], dr), getProjectedPointWithWinding(p2[i], dr)); + } + + for (uint32_t i = 0; i < 3; ++i) + { + if (inRel1[i] == INSIDE_TR && inRel1[(i + 1) % 3] == INSIDE_TR) + { + stencil[tr2].push_back(p1[i]); + stencil[tr2].push_back(p1[(i + 1) % 3]); + } + else + { + if (inRel1[i] == INSIDE_TR && intr1[i].size() == 1) + { + stencil[tr2].push_back(p1[i]); + stencil[tr2].push_back((p1[(i + 1) % 3] - p1[i]) * intr1[i][0] + p1[i]); + } + if (inRel1[(i + 1) % 3] == INSIDE_TR && intr1[i].size() == 1) + { + stencil[tr2].push_back(p1[(i + 1) % 3]); + stencil[tr2].push_back((p1[(i + 1) % 3] - p1[i]) * intr1[i][0] + p1[i]); + } + if (intr1[i].size() == 2) + { + stencil[tr2].push_back((p1[(i + 1) % 3] - p1[i]) * intr1[i][0] + p1[i]); + stencil[tr2].push_back((p1[(i + 1) % 3] - p1[i]) * intr1[i][1] + p1[i]); + } + } + } + + for (uint32_t i = 0; i < 3; ++i) + { + if (inRel2[i] == INSIDE_TR && inRel2[(i + 1) % 3] == INSIDE_TR) + { + stencil[tr1].push_back(p2[i]); + stencil[tr1].push_back(p2[(i + 1) % 3]); + } + else + { + if (inRel2[i] == INSIDE_TR && intr2[i].size() == 1) + { + stencil[tr1].push_back(p2[i]); + stencil[tr1].push_back((p2[(i + 1) % 3] - p2[i]) * intr2[i][0] + p2[i]); + } + if (inRel2[(i + 1) % 3] == INSIDE_TR && intr2[i].size() == 1) + { + stencil[tr1].push_back(p2[(i + 1) % 3]); + stencil[tr1].push_back((p2[(i + 1) % 3] - p2[i]) * intr2[i][0] + p2[i]); + } + if (intr2[i].size() == 2) + { + stencil[tr1].push_back((p2[(i + 1) % 3] - p2[i]) * intr2[i][0] + p2[i]); + stencil[tr1].push_back((p2[(i + 1) % 3] - p2[i]) * intr2[i][1] + p2[i]); + } + } + } +} + + +int32_t getTriangleIntersection3d(uint32_t tr1, uint32_t tr2, std::vector<std::vector<RVec3>>& stencil, ProjectionDirections dr) +{ + RatPlane pl1(stencil[tr1][0], stencil[tr1][1], stencil[tr1][3]); + if (pl1.n.isZero()) + { + std::swap(tr1, tr2); + pl1 = RatPlane(stencil[tr1][0], stencil[tr1][1], stencil[tr1][3]); + if (pl1.n.isZero()) return 0; + } + + + cpp_rational d1 = pl1.distance(stencil[tr2][0]); + cpp_rational d2 = pl1.distance(stencil[tr2][1]); + cpp_rational d3 = pl1.distance(stencil[tr2][3]); + + int32_t sd1 = d1.sign(); + int32_t sd2 = d2.sign(); + int32_t sd3 = d3.sign(); + + + if (sd1 == 0 && sd2 == 0 && sd3 == 0) + { + getTriangleIntersectionCoplanar(tr1, tr2, stencil, dr); + return 0; + } + /** + Never intersected + */ + if (sd1 < 0 && sd2 < 0 && sd3 < 0) + return 0; + if (sd1 > 0 && sd2 > 0 && sd3 > 0) + return 0; + + RVec3 tb0 = stencil[tr2][0]; + RVec3 tb1 = stencil[tr2][1]; + RVec3 tb2 = stencil[tr2][3]; + + if (sd1 * sd3 > 0) + { + std::swap(tb1, tb2); + std::swap(d2, d3); + } + else + { + if (sd2 * sd3 > 0) + { + std::swap(tb0, tb2); + std::swap(d1, d3); + } + else + { + if (sd3 == 0 && sd1 * sd2 < 0) + { + std::swap(tb0, tb2); + std::swap(d1, d3); + } + } + } + + RatPlane pl2(stencil[tr2][0], stencil[tr2][1], stencil[tr2][3]); + + cpp_rational d21 = pl2.distance(stencil[tr1][0]); + cpp_rational d22 = pl2.distance(stencil[tr1][1]); + cpp_rational d23 = pl2.distance(stencil[tr1][3]); + + int32_t sd21 = d21.sign(); + int32_t sd22 = d22.sign(); + int32_t sd23 = d23.sign(); + + if (sd21 < 0 && sd22 < 0 && sd23 < 0) + return 0; + if (sd21 > 0 && sd22 > 0 && sd23 > 0) + return 0; + + + RVec3 ta0 = stencil[tr1][0]; + RVec3 ta1 = stencil[tr1][1]; + RVec3 ta2 = stencil[tr1][3]; + + + if (sd21 * sd23 > 0) + { + std::swap(ta1, ta2); + std::swap(d22, d23); + } + else + { + if (sd22 * sd23 > 0) + { + std::swap(ta0, ta2); + std::swap(d21, d23); + } + else + { + if (sd23 == 0 && sd21 * sd22 < 0) + { + std::swap(ta0, ta2); + std::swap(d21, d23); + } + } + } + ////////////////////////////////////////////////// + RVec3 dir = ta2 - ta0; + + cpp_rational dirPlaneDot = dir.dot(pl2.n); + + + RVec3 pointOnIntersectionLine; + if (dirPlaneDot != 0) + { + pointOnIntersectionLine = ta0 - dir * (d21 / dirPlaneDot); + } + else + { + pointOnIntersectionLine = ta0; + } + RVec3 interLineDir = pl1.n.cross(pl2.n); + cpp_rational sqd = interLineDir.dot(interLineDir); + if (sqd.is_zero()) return 0; + + cpp_rational t1p2 = (ta1 - pointOnIntersectionLine).dot(interLineDir) / sqd; + cpp_rational t1p3 = (ta2 - pointOnIntersectionLine).dot(interLineDir) / sqd; + cpp_rational t1p2param = t1p2; + if (d22 != d23) + { + t1p2param = t1p2 + (t1p3 - t1p2) * (d22 / (d22 - d23)); + } + + t1p2 = (tb0 - pointOnIntersectionLine).dot(interLineDir) / sqd; + t1p3 = (tb2 - pointOnIntersectionLine).dot(interLineDir) / sqd; + cpp_rational t2p1param = t1p2; + if (d1 != d3) + { + t2p1param = t1p2 + (t1p3 - t1p2) * d1 / (d1 - d3); + } + + t1p2 = (tb1 - pointOnIntersectionLine).dot(interLineDir) / sqd; + cpp_rational t2p2param = t1p2; + if (d2 != d3) + { + t2p2param = t1p2 + (t1p3 - t1p2) * d2 / (d2 - d3); + } + cpp_rational beg1 = 0; + + if (t1p2param < 0) + { + std::swap(beg1, t1p2param); + } + if (t2p2param < t2p1param) + { + std::swap(t2p2param, t2p1param); + } + cpp_rational minEnd = std::min(t1p2param, t2p2param); + cpp_rational maxBeg = std::max(beg1, t2p1param); + + if (minEnd > maxBeg) + { + RVec3 p1 = pointOnIntersectionLine + interLineDir * maxBeg; + RVec3 p2 = pointOnIntersectionLine + interLineDir * minEnd; + + stencil[tr1].push_back(p1); + stencil[tr1].push_back(p2); + + stencil[tr2].push_back(p1); + stencil[tr2].push_back(p2); + return 1; + } + return 0; +} + +int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, ProjectionDirections dir, std::vector<cpp_rational>& t1v, std::vector<cpp_rational>& t2v) +{ + RVec2 s1p = getProjectedPointWithWinding(s1, dir); + RVec2 e1p = getProjectedPointWithWinding(e1, dir); + + RVec2 s2p = getProjectedPointWithWinding(s2, dir); + RVec2 e2p = getProjectedPointWithWinding(e2, dir); + + RVec2 dir1 = e1p - s1p; + RVec2 dir2 = s2p - e2p; + + cpp_rational crs = dir1.cross(dir2); + if (crs != 0) + { + cpp_rational c1 = s2p.x - s1p.x; + cpp_rational c2 = s2p.y - s1p.y; + + cpp_rational det1 = c1 * dir2.y - c2 * dir2.x; + cpp_rational det2 = dir1.x * c2 - dir1.y * c1; + + cpp_rational t1 = det1 / crs; + cpp_rational t2 = det2 / crs; + + if (t1 > 0 && t1 < 1 && (t2 >= 0 && t2 <= 1)) + { + t1v.push_back(t1); + } + if (t2 > 0 && t2 < 1 && (t1 >= 0 && t1 <= 1)) + { + t2v.push_back(t2); + } + + } + else + { + if (dir1.cross(s2p - s1p) == 0) + { + if (dir1.x != 0) + { + cpp_rational t1 = (s2p.x - s1p.x) / dir1.x; + cpp_rational t2 = (e2p.x - s1p.x) / dir1.x; + if (t1 > 0 && t1 < 1) t1v.push_back(t1); + if (t2 > 0 && t2 < 1) t1v.push_back(t2); + } + else + { + if (dir1.y != 0) + { + cpp_rational t1 = (s2p.y - s1p.y) / dir1.y; + cpp_rational t2 = (e2p.y - s1p.y) / dir1.y; + if (t1 > 0 && t1 < 1) t1v.push_back(t1); + if (t2 > 0 && t2 < 1) t1v.push_back(t2); + } + } + } + if (dir2.cross(s1p - s2p) == 0) + { + dir2 = e2p - s2p; + if (dir2.x != 0) + { + cpp_rational t1 = (s1p.x - s2p.x) / dir2.x; + cpp_rational t2 = (e1p.x - s2p.x) / dir2.x; + if (t1 > 0 && t1 < 1) t2v.push_back(t1); + if (t2 > 0 && t2 < 1) t2v.push_back(t2); + } + else + { + if (dir2.y != 0) + { + cpp_rational t1 = (s1p.y - s2p.y) / dir2.y; + cpp_rational t2 = (e1p.y - s2p.y) / dir2.y; + if (t1 > 0 && t1 < 1) t2v.push_back(t1); + if (t2 > 0 && t2 < 1) t2v.push_back(t2); + } + } + } + } + return 1; +} + +struct RVec3Comparer +{ + bool operator()(const RVec3& a, const RVec3& b) const + { + if (a.x < b.x) return true; + if (a.x > b.x) return false; + if (a.y < b.y) return true; + if (a.y > b.y) return false; + if (a.z < b.z) return true; + return false; + } +}; + +void getBarycentricCoords(PxVec2& a, PxVec2& b, PxVec2& c, PxVec2& p, float& u, float& v) +{ + PxVec3 v1(b.x - a.x, c.x - a.x, a.x - p.x); + PxVec3 v2(b.y - a.y, c.y - a.y, a.y - p.y); + + PxVec3 resl = v1.cross(v2); + u = resl.x / resl.z; + v = resl.y / resl.z; +} + + +Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) +{ + /** + ======= Get mesh data =========== + */ + std::vector<Vertex> vertices; + std::vector<Edge> edges; + std::vector<Facet> facets; + + vertices.resize(mesh->getVerticesCount()); + edges.resize(mesh->getEdgesCount()); + facets.resize(mesh->getFacetCount()); + + PxBounds3 bnd; + bnd.setEmpty(); + + for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) + { + vertices[i] = mesh->getVertices()[i]; + bnd.include(vertices[i].p); + } + for (uint32_t i = 0; i < mesh->getEdgesCount(); ++i) + { + edges[i] = mesh->getEdges()[i]; + } + for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) + { + facets[i] = mesh->getFacetsBuffer()[i]; + } + //====================================== + + /** + Transform vertices to fit unit cube and snap them to grid. + **/ + float scale = 1.0f / bnd.getExtents().abs().maxElement(); + + int32_t gridSize = 10000; // Grid resolution to which vertices position will be snapped. + + for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) + { + vertices[i].p = (vertices[i].p - bnd.minimum) * scale; + vertices[i].p.x = std::floor(vertices[i].p.x * gridSize) / gridSize; + vertices[i].p.y = std::floor(vertices[i].p.y * gridSize) / gridSize; + vertices[i].p.z = std::floor(vertices[i].p.z * gridSize) / gridSize; + } + + std::vector<std::vector<RVec3>> triangleStencil(facets.size()); + + std::vector<PxVec3> facetsNormals(facets.size()); + std::vector<PxBounds3> facetBound(facets.size()); + + + for (uint32_t tr1 = 0; tr1 < facets.size(); ++tr1) + { + if (facets[tr1].edgesCount != 3) + { + return nullptr; + } + int32_t fed = facets[tr1].firstEdgeNumber; + triangleStencil[tr1].push_back(vertices[edges[fed].s].p); + triangleStencil[tr1].push_back(vertices[edges[fed].e].p); + triangleStencil[tr1].push_back(vertices[edges[fed + 1].s].p); + triangleStencil[tr1].push_back(vertices[edges[fed + 1].e].p); + triangleStencil[tr1].push_back(vertices[edges[fed + 2].s].p); + triangleStencil[tr1].push_back(vertices[edges[fed + 2].e].p); + + facetBound[tr1].setEmpty(); + facetBound[tr1].include(vertices[edges[fed].s].p); + facetBound[tr1].include(vertices[edges[fed].e].p); + facetBound[tr1].include(vertices[edges[fed + 2].s].p); + facetBound[tr1].fattenFast(0.001f); + + facetsNormals[tr1] = (vertices[edges[fed + 1].s].p - vertices[edges[fed].s].p).cross(vertices[edges[fed + 2].s].p - vertices[edges[fed].s].p); + } + + /** + Build intersections between all pairs of triangles. + */ + for (uint32_t tr1 = 0; tr1 < facets.size(); ++tr1) + { + if (triangleStencil[tr1].empty()) continue; + for (uint32_t tr2 = tr1 + 1; tr2 < facets.size(); ++tr2) + { + if (triangleStencil[tr2].empty()) continue; + if (facetBound[tr1].intersects(facetBound[tr2]) == false) continue; + + getTriangleIntersection3d(tr1, tr2, triangleStencil, getProjectionDirection(facetsNormals[tr1])); + } + } + + /** + Reintersect all segments + */ + for (uint32_t tr = 0; tr < triangleStencil.size(); ++tr) + { + std::vector<RVec3>& ctr = triangleStencil[tr]; + std::vector<std::vector<cpp_rational> > perSegmentInters(ctr.size() / 2); + for (uint32_t sg1 = 6; sg1 < ctr.size(); sg1 += 2) + { + for (uint32_t sg2 = sg1 + 2; sg2 < ctr.size(); sg2 += 2) + { + intersectSegments(ctr[sg1], ctr[sg1 + 1], ctr[sg2], ctr[sg2 + 1], getProjectionDirection(facetsNormals[tr]), perSegmentInters[sg1 / 2], perSegmentInters[sg2 / 2]); + } + } + + std::vector<RVec3> newStencil; + newStencil.reserve(ctr.size()); + + for (uint32_t i = 0; i < ctr.size(); i += 2) + { + int32_t csm = i / 2; + if (perSegmentInters[csm].size() == 0) + { + newStencil.push_back(ctr[i]); + newStencil.push_back(ctr[i + 1]); + } + else + { + cpp_rational current = 0; + newStencil.push_back(ctr[i]); + std::sort(perSegmentInters[csm].begin(), perSegmentInters[csm].end()); + for (size_t j = 0; j < perSegmentInters[csm].size(); ++j) + { + if (perSegmentInters[csm][j] > current) + { + current = perSegmentInters[csm][j]; + RVec3 pnt = (ctr[i + 1] - ctr[i]) * current + ctr[i]; + newStencil.push_back(pnt); + newStencil.push_back(pnt); + } + } + newStencil.push_back(ctr[i + 1]); + } + } + ctr = newStencil; + } + + std::vector<RVec3> finalPoints; + + std::vector<std::vector<Edge>> tsten(facets.size()); + + { + std::map<RVec3, uint32_t, RVec3Comparer> mapping; + for (uint32_t tr1 = 0; tr1 < triangleStencil.size(); ++tr1) + { + for (uint32_t j = 0; j < triangleStencil[tr1].size(); j += 2) + { + + auto it = mapping.find(triangleStencil[tr1][j]); + int32_t pt = 0; + if (it == mapping.end()) + { + mapping[triangleStencil[tr1][j]] = finalPoints.size(); + pt = finalPoints.size(); + finalPoints.push_back(triangleStencil[tr1][j]); + } + else + { + pt = it->second; + } + + Edge newed; + + newed.s = pt; + + it = mapping.find(triangleStencil[tr1][j + 1]); + if (it == mapping.end()) + { + mapping[triangleStencil[tr1][j + 1]] = finalPoints.size(); + pt = finalPoints.size(); + finalPoints.push_back(triangleStencil[tr1][j + 1]); + } + else + { + pt = it->second; + } + newed.e = pt; + bool hasNewEdge = false; + for (uint32_t e = 0; e < tsten[tr1].size(); ++e) + { + if (tsten[tr1][e].s == newed.s && tsten[tr1][e].e == newed.e) + { + hasNewEdge = true; + break; + } + if (tsten[tr1][e].e == newed.s && tsten[tr1][e].s == newed.e) + { + hasNewEdge = true; + break; + } + } + if (!hasNewEdge) tsten[tr1].push_back(newed); + } + } + } + + /** + Build constrained DT + */ + std::vector<DelTriangle> trs; + for (uint32_t i = 0; i < tsten.size(); ++i) + { + + if (tsten[i].size() < 3) continue; + if (tsten[i].size() > 3) + { + int32_t oldSize = trs.size(); + buildCDT(finalPoints, tsten[i], trs, getProjectionDirection(facetsNormals[i])); + for (uint32_t k = oldSize; k < trs.size(); ++k) + trs[k].parentTriangle = i; + } + else + { + trs.push_back(DelTriangle()); + trs.back().parentTriangle = i; + for (uint32_t v = 0; v < 3; ++v) + trs.back().p[v] = tsten[i][v].s; + } + + } + + /** + Remove 'deleted' triangles from array. + */ + { + std::vector < DelTriangle > trstemp; + trstemp.reserve(trs.size()); + for (uint32_t i = 0; i < trs.size(); ++i) + { + if (trs[i].p[0] != -1) + trstemp.push_back(trs[i]); + } + trs = trstemp; + } + + /** + Filter exterior surface + */ + std::vector<bool> fillingMask(trs.size(), false); + + std::map<std::pair<int32_t, int32_t>, int32_t> edgeMap; + std::vector<std::vector<int32_t> > edgeToTriangleMapping; + + for (uint32_t i = 0; i < trs.size(); ++i) + { + if (trs[i].p[0] == -1) continue; + if (trs[i].p[0] == trs[i].p[1] || trs[i].p[2] == trs[i].p[1] || trs[i].p[2] == trs[i].p[0]) + { + trs[i].p[0] = -1; + continue; + } + #if 0 // Filter null-area triangles. + if ((finalPoints[trs[i].p[1]] - finalPoints[trs[i].p[0]]).cross(finalPoints[trs[i].p[2]] - finalPoints[trs[i].p[0]]).isZero()) + { + trs[i].p[0] = -1; + continue; + } + #endif + for (uint32_t k = 0; k < 3; ++k) + { + int32_t es = trs[i].p[k]; + int32_t ee = trs[i].p[(k + 1) % 3]; + if (es > ee) + { + std::swap(es, ee); + } + auto pr = std::make_pair(es, ee); + auto iter = edgeMap.find(pr); + if (iter == edgeMap.end()) + { + edgeMap[pr] = edgeToTriangleMapping.size(); + trs[i].n[k] = edgeToTriangleMapping.size(); + edgeToTriangleMapping.resize(edgeToTriangleMapping.size() + 1); + edgeToTriangleMapping.back().push_back(i); + } + else + { + for (uint32_t j = 0; j < edgeToTriangleMapping[iter->second].size(); ++j) + { + if (trs[edgeToTriangleMapping[iter->second][j]].compare(trs[i])) + { + trs[i].p[0] = -1; + break; + } + } + if (trs[i].p[0] != -1) + { + trs[i].n[k] = iter->second; + edgeToTriangleMapping[iter->second].push_back(i); + } + } + } + } + + std::queue<int32_t> trque; + float maxx = -1000; + int32_t best = 0; + for (uint32_t i = 0; i < trs.size(); ++i) + { + if (trs[i].p[0] == -1) continue; + float m = std::max(finalPoints[trs[i].p[0]].x.convert_to<float>(), std::max(finalPoints[trs[i].p[1]].x.convert_to<float>(), finalPoints[trs[i].p[2]].x.convert_to<float>())); + if (m > maxx && facetsNormals[trs[i].parentTriangle].x > 0) + { + maxx = m; + best = i; + } + } + + trque.push(best); + while (!trque.empty()) + { + int32_t trid = trque.front(); + fillingMask[trid] = true; + DelTriangle& tr = trs[trque.front()]; + trque.pop(); + + for (uint32_t ed = 0; ed < 3; ++ed) + { + auto& tlist = edgeToTriangleMapping[tr.n[ed]]; + if (tlist.size() == 2) + { + for (uint32_t k = 0; k < tlist.size(); ++k) + { + int32_t to = tlist[k]; + if (to != trid && !fillingMask[to] && edgeToTriangleMapping[trs[to].n[0]].size() > 0 && edgeToTriangleMapping[trs[to].n[1]].size() > 0 && edgeToTriangleMapping[trs[to].n[2]].size() > 0) + { + trque.push(tlist[k]); + fillingMask[tlist[k]] = true; + } + } + } + if (tlist.size() > 2) + { + int32_t bestPath = (tlist[0] == trid) ? tlist[1] : tlist[0]; + RVec3 start = finalPoints[trs[trid].p[ed]]; + RVec3 axis = finalPoints[trs[trid].p[(ed + 1) % 3]] - start; + RVec3 nAxis = finalPoints[trs[trid].p[(ed + 2) % 3]] - start; + RVec3 normal = axis.cross(nAxis); + + + uint32_t op = trs[bestPath].getOppPoint(trs[trid].p[ed], trs[trid].p[(ed + 1) % 3]); + + RVec3 dir2 = (finalPoints[op] - start); + RVec3 normal2 = dir2.cross(axis); + cpp_rational bestDir = normal.cross(normal2).dot(axis); + cpp_rational oldDist = normal2.dot(normal2); + for (uint32_t k = 0; k < tlist.size(); ++k) + { + if (tlist[k] == trid) continue; + op = trs[tlist[k]].getOppPoint(trs[trid].p[ed], trs[trid].p[(ed + 1) % 3]); + dir2 = (finalPoints[op] - start); + normal2 = dir2.cross(axis); + cpp_rational newOne = normal.cross(normal2).dot(axis); + + if (newOne * oldDist < bestDir * normal2.dot(normal2)) + { + oldDist = normal2.dot(normal2); + bestPath = tlist[k]; + bestDir = newOne; + } + } + if (!fillingMask[bestPath] && edgeToTriangleMapping[trs[bestPath].n[0]].size() > 0 && edgeToTriangleMapping[trs[bestPath].n[1]].size() > 0 && edgeToTriangleMapping[trs[bestPath].n[2]].size() > 0) + { + trque.push(bestPath); + fillingMask[bestPath] = true; + } + } + edgeToTriangleMapping[tr.n[ed]].clear(); + } + + } + for (uint32_t id = 0; id < trs.size(); ++id) + { + if (!fillingMask[id]) + { + trs[id].p[0] = -1; // Remove triangle + } + } + ///////////////////////////////////////////////////////////////////////////////////////////// + + std::vector<PxVec3> newVertices; + newVertices.resize(finalPoints.size()); + for (uint32_t i = 0; i < finalPoints.size(); ++i) + { + newVertices[i].x = finalPoints[i].x.convert_to<float>(); + newVertices[i].y = finalPoints[i].y.convert_to<float>(); + newVertices[i].z = finalPoints[i].z.convert_to<float>(); + } + /** + Rescale mesh to initial coordinates. + */ + for (uint32_t i = 0; i < finalPoints.size(); ++i) + { + newVertices[i] = newVertices[i] * (1.0f / scale) + bnd.minimum; + } + for (uint32_t i = 0; i < vertices.size(); ++i) + { + vertices[i].p = vertices[i].p * (1.0f / scale) + bnd.minimum; + } + + std::vector<Triangle> result; + result.reserve(trs.size()); + { + std::vector<PxVec2> projectedTriangles(facets.size() * 3); + std::vector<Vertex> normalTriangles(facets.size() * 3); + + for (uint32_t i = 0; i < facets.size(); ++i) + { + for (uint32_t k = 0; k < 3; ++k) + { + normalTriangles[i * 3 + k] = vertices[edges[facets[i].firstEdgeNumber + k].s]; + projectedTriangles[i * 3 + k] = getProjectedPointWithWinding(vertices[edges[facets[i].firstEdgeNumber + k].s].p, getProjectionDirection(facetsNormals[i])); + } + } + + for (uint32_t i = 0; i < trs.size(); ++i) + { + if (trs[i].p[0] == -1) continue; + int32_t id = 0; + int32_t parentTriangle = trs[i].parentTriangle; + float u = 0, v = 0; + result.resize(result.size() + 1); + result.back().materialId = facets[parentTriangle].materialId; + result.back().smoothingGroup = facets[parentTriangle].smoothingGroup; + for (auto vert : { &result.back().a, &result.back().b , &result.back().c }) + { + vert->p = newVertices[trs[i].p[id]]; + PxVec2 p = getProjectedPointWithWinding(vert->p, getProjectionDirection(facetsNormals[parentTriangle])); + getBarycentricCoords(projectedTriangles[parentTriangle * 3], projectedTriangles[parentTriangle * 3 + 1], projectedTriangles[parentTriangle * 3 + 2], p, u, v); + vert->uv[0] = (1 - u - v) * normalTriangles[parentTriangle * 3].uv[0] + u * normalTriangles[parentTriangle * 3 + 1].uv[0] + v * normalTriangles[parentTriangle * 3 + 2].uv[0]; + vert->n = (1 - u - v) * normalTriangles[parentTriangle * 3].n + u * normalTriangles[parentTriangle * 3 + 1].n + v * normalTriangles[parentTriangle * 3 + 2].n; + ++id; + } + } + } + + /** + Reuse old buffers to create Mesh + */ + std::vector<PxVec3> newMeshVertices(result.size() * 3); + std::vector<PxVec3> newMeshNormals(result.size() * 3); + std::vector<PxVec2> newMeshUvs(result.size() * 3); + + std::vector<int32_t> newMaterialIds(result.size()); + std::vector<int32_t> newSmoothingGroups(result.size()); + + + for (uint32_t i = 0; i < result.size(); ++i) + { + Vertex* arr[3] = { &result[i].a, &result[i].b , &result[i].c }; + for (uint32_t k = 0; k < 3; ++k) + { + newMeshVertices[i * 3 + k] = arr[k]->p; + newMeshNormals[i * 3 + k] = arr[k]->n; + newMeshUvs[i * 3 + k] = arr[k]->uv[0]; + } + } + std::vector<uint32_t> serializedIndices; + serializedIndices.reserve(result.size() * 3); + int32_t cindex = 0; + for (uint32_t i = 0; i < result.size(); ++i) + { + newMaterialIds[i] = result[i].materialId; + newSmoothingGroups[i] = result[i].smoothingGroup; + + for (uint32_t pi = 0; pi < 3; ++pi) + serializedIndices.push_back(cindex++); + } + + MeshImpl* rMesh = new MeshImpl(newMeshVertices.data(), newMeshNormals.data(), newMeshUvs.data(), static_cast<uint32_t>(newMeshVertices.size()), serializedIndices.data(), static_cast<uint32_t>(serializedIndices.size())); + rMesh->setMaterialId(newMaterialIds.data()); + rMesh->setSmoothingGroup(newSmoothingGroups.data()); + return rMesh; +} + +void MeshCleanerImpl::release() +{ + delete this; +} + diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.h new file mode 100644 index 0000000..0eb1a85 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.h @@ -0,0 +1,25 @@ +#include "NvBlastExtAuthoringMeshCleaner.h" + +namespace Nv +{ +namespace Blast +{ + +class Mesh; + +class MeshCleanerImpl : public MeshCleaner +{ +public: + /** + Tries to remove self intersections and open edges in interior of mesh. + \param[in] mesh Mesh to be cleaned. + \return Cleaned mesh or nullptr if failed. + */ + virtual Mesh* cleanMesh(const Nv::Blast::Mesh* mesh) override; + virtual void release() override; + + ~MeshCleanerImpl() {}; +}; + +} +}
\ No newline at end of file diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMesh.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.cpp index a25d2fe..3497fda 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringMesh.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.cpp @@ -10,10 +10,11 @@ #define _CRT_SECURE_NO_WARNINGS -#include "NvBlastExtAuthoringMesh.h" +#include "NvBlastExtAuthoringMeshImpl.h" #include "NvBlastExtAuthoringTypes.h" #include <string.h> #include "NvBlastExtAuthoringPerlinNoise.h" +#include <cmath> using physx::PxVec2; using physx::PxVec3; @@ -24,7 +25,7 @@ namespace Nv namespace Blast { -Mesh::Mesh(PxVec3* position, PxVec3* normals, PxVec2* uv, uint32_t verticesCount, uint32_t* indices, uint32_t indicesCount) +MeshImpl::MeshImpl(const PxVec3* position, const PxVec3* normals, const PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount) { mVertices.resize(verticesCount); @@ -81,11 +82,14 @@ Mesh::Mesh(PxVec3* position, PxVec3* normals, PxVec2* uv, uint32_t verticesCount mEdges[i + 2].e = indices[i]; mFacets[facetId].firstEdgeNumber = i; mFacets[facetId].edgesCount = 3; + mFacets[facetId].materialId = 0; + //Unassigned for now + mFacets[facetId].smoothingGroup = -1; facetId++; } } -Mesh::Mesh(Vertex* vertices, Edge* edges, Facet* facets, uint32_t posCount, uint32_t edgesCount, uint32_t facetsCount) +MeshImpl::MeshImpl(const Vertex* vertices, const Edge* edges, const Facet* facets, uint32_t posCount, uint32_t edgesCount, uint32_t facetsCount) { mVertices.resize(posCount); mEdges.resize(edgesCount); @@ -101,7 +105,7 @@ Mesh::Mesh(Vertex* vertices, Edge* edges, Facet* facets, uint32_t posCount, uint } } -float Mesh::getMeshVolume() +float MeshImpl::getMeshVolume() { /** Check if mesh boundary consist only of triangles @@ -124,53 +128,80 @@ float Mesh::getMeshVolume() volume += (a.x * b.y * c.z - a.x * b.z * c.y - a.y * b.x * c.z + a.y * b.z * c.x + a.z * b.x * c.y - a.z * b.y * c.x); } - return (1.0f / 6.0f) * abs(volume); + return (1.0f / 6.0f) * std::abs(volume); } -uint32_t Mesh::getFacetCount() +uint32_t MeshImpl::getFacetCount() const { return static_cast<uint32_t>(mFacets.size()); } -Vertex* Mesh::getVertices() +Vertex* MeshImpl::getVerticesWritable() { return mVertices.data(); } -Edge* Mesh::getEdges() +Edge* MeshImpl::getEdgesWritable() { return mEdges.data(); } -uint32_t Mesh::getEdgesCount() +const Vertex* MeshImpl::getVertices() const +{ + return mVertices.data(); +} + +const Edge* MeshImpl::getEdges() const +{ + return mEdges.data(); +} + +uint32_t MeshImpl::getEdgesCount() const { return static_cast<uint32_t>(mEdges.size()); } -uint32_t Mesh::getVerticesCount() +uint32_t MeshImpl::getVerticesCount() const { return static_cast<uint32_t>(mVertices.size()); } -Facet* Mesh::getFacetsBuffer() +Facet* MeshImpl::getFacetsBufferWritable() { return mFacets.data(); } -Facet* Mesh::getFacet(int32_t facet) +const Facet* MeshImpl::getFacetsBuffer() const +{ + return mFacets.data(); +} +Facet* MeshImpl::getFacetWritable(int32_t facet) +{ + return &mFacets[facet]; +} +const Facet* MeshImpl::getFacet(int32_t facet) const { return &mFacets[facet]; } +MeshImpl::~MeshImpl() +{ +} + +void MeshImpl::release() +{ + delete this; +} -Mesh::~Mesh() +const PxBounds3& MeshImpl::getBoundingBox() const { + return mBounds; } -PxBounds3& Mesh::getBoundingBox() +PxBounds3& MeshImpl::getBoundingBoxWritable() { return mBounds; } -void Mesh::recalculateBoundingBox() +void MeshImpl::recalculateBoundingBox() { mBounds.setEmpty(); for (uint32_t i = 0; i < mVertices.size(); ++i) @@ -184,7 +215,7 @@ void Mesh::recalculateBoundingBox() void getTangents(PxVec3& normal, PxVec3& t1, PxVec3& t2) { - if (abs(normal.z) < 0.9) + if (std::abs(normal.z) < 0.9) { t1 = normal.cross(PxVec3(0, 0, 1)); } @@ -249,61 +280,85 @@ Mesh* getCuttingBox(const PxVec3& point, const PxVec3& normal, float size, int32 edges.push_back(Edge(1, 2)); edges.push_back(Edge(2, 3)); edges.push_back(Edge(3, 0)); - facets.push_back(Facet(0, 4, id)); + facets.push_back(Facet(0, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(0, 3)); edges.push_back(Edge(3, 7)); edges.push_back(Edge(7, 4)); edges.push_back(Edge(4, 0)); - facets.push_back(Facet(4, 4, id)); + facets.push_back(Facet(4, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(3, 2)); edges.push_back(Edge(2, 6)); edges.push_back(Edge(6, 7)); edges.push_back(Edge(7, 3)); - facets.push_back(Facet(8, 4, id)); + facets.push_back(Facet(8, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(5, 6)); edges.push_back(Edge(6, 2)); edges.push_back(Edge(2, 1)); edges.push_back(Edge(1, 5)); - facets.push_back(Facet(12, 4, id)); + facets.push_back(Facet(12, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(4, 5)); edges.push_back(Edge(5, 1)); edges.push_back(Edge(1, 0)); edges.push_back(Edge(0, 4)); - facets.push_back(Facet(16, 4, id)); + facets.push_back(Facet(16, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(4, 7)); edges.push_back(Edge(7, 6)); edges.push_back(Edge(6, 5)); edges.push_back(Edge(5, 4)); - facets.push_back(Facet(20, 4, id)); - return new Mesh(positions.data(), edges.data(), facets.data(), static_cast<uint32_t>(positions.size()), static_cast<uint32_t>(edges.size()), static_cast<uint32_t>(facets.size())); + facets.push_back(Facet(20, 4, MATERIAL_INTERIOR, id)); + return new MeshImpl(positions.data(), edges.data(), facets.data(), static_cast<uint32_t>(positions.size()), static_cast<uint32_t>(edges.size()), static_cast<uint32_t>(facets.size())); } void inverseNormalAndSetIndices(Mesh* mesh, int32_t id) { for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) { - mesh->getVertices()[i].n *= -1.0f; + mesh->getVerticesWritable()[i].n *= -1.0f; } for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) { - mesh->getFacet(i)->userData = id; + mesh->getFacetWritable(i)->userData = id; } +} +void MeshImpl::setMaterialId(int32_t* materialId) +{ + if (materialId != nullptr) + { + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + mFacets[i].materialId = *materialId; + ++materialId; + } + } } +void MeshImpl::setSmoothingGroup(int32_t* smoothingGroup) +{ + if (smoothingGroup != nullptr) + { + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + mFacets[i].smoothingGroup = *smoothingGroup; + ++smoothingGroup; + } + } +} + + void setCuttingBox(const PxVec3& point, const PxVec3& normal, Mesh* mesh, float size, int32_t id) { PxVec3 t1, t2; PxVec3 lNormal = normal.getNormalized(); getTangents(lNormal, t1, t2); - Vertex* positions = mesh->getVertices(); + Vertex* positions = mesh->getVerticesWritable(); positions[0].p = point + (t1 + t2) * size; positions[1].p = point + (t2 - t1) * size; @@ -332,12 +387,12 @@ void setCuttingBox(const PxVec3& point, const PxVec3& normal, Mesh* mesh, float for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) { - mesh->getFacet(i)->userData = id; + mesh->getFacetWritable(i)->userData = id; } mesh->recalculateBoundingBox(); } -bool Mesh::isValid() +bool MeshImpl::isValid() const { return mVertices.size() > 0 && mEdges.size() > 0 && mFacets.size() > 0; } @@ -388,7 +443,7 @@ Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& no edges.push_back(Edge(i * (resolution + 1) + j + 1, (i + 1) * (resolution + 1) + j + 1)); edges.push_back(Edge((i + 1) * (resolution + 1) + j + 1, (i + 1) * (resolution + 1) + j)); edges.push_back(Edge((i + 1) * (resolution + 1) + j, i * (resolution + 1) + j)); - facets.push_back(Facet(start, 4, id)); + facets.push_back(Facet(start, 4, MATERIAL_INTERIOR, id)); } } uint32_t offset = (resolution + 1) * (resolution + 1); @@ -437,7 +492,7 @@ Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& no edges.push_back(Edge(9 + offset, 8 + offset)); edges.push_back(Edge(8 + offset, 11 + offset)); - facets.push_back(Facet(edgeOffset, 8, id)); + facets.push_back(Facet(edgeOffset, 8, MATERIAL_INTERIOR, id)); @@ -445,34 +500,34 @@ Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& no edges.push_back(Edge(3 + offset, 7 + offset)); edges.push_back(Edge(7 + offset, 4 + offset)); edges.push_back(Edge(4 + offset, 0 + offset)); - facets.push_back(Facet(8 + edgeOffset, 4, id)); + facets.push_back(Facet(8 + edgeOffset, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(3 + offset, 2 + offset)); edges.push_back(Edge(2 + offset, 6 + offset)); edges.push_back(Edge(6 + offset, 7 + offset)); edges.push_back(Edge(7 + offset, 3 + offset)); - facets.push_back(Facet(12 + edgeOffset, 4, id)); + facets.push_back(Facet(12 + edgeOffset, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(5 + offset, 6 + offset)); edges.push_back(Edge(6 + offset, 2 + offset)); edges.push_back(Edge(2 + offset, 1 + offset)); edges.push_back(Edge(1 + offset, 5 + offset)); - facets.push_back(Facet(16 + edgeOffset, 4, id)); + facets.push_back(Facet(16 + edgeOffset, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(4 + offset, 5 + offset)); edges.push_back(Edge(5 + offset, 1 + offset)); edges.push_back(Edge(1 + offset, 0 + offset)); edges.push_back(Edge(0 + offset, 4 + offset)); - facets.push_back(Facet(20 + edgeOffset, 4, id)); + facets.push_back(Facet(20 + edgeOffset, 4, MATERIAL_INTERIOR, id)); edges.push_back(Edge(4 + offset, 7 + offset)); edges.push_back(Edge(7 + offset, 6 + offset)); edges.push_back(Edge(6 + offset, 5 + offset)); edges.push_back(Edge(5 + offset, 4 + offset)); - facets.push_back(Facet(24 + edgeOffset, 4, id)); + facets.push_back(Facet(24 + edgeOffset, 4, MATERIAL_INTERIOR, id)); // - return new Mesh(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size()); + return new MeshImpl(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size()); } Mesh* getBigBox(const PxVec3& point, float size) @@ -517,41 +572,41 @@ Mesh* getBigBox(const PxVec3& point, float size) edges.push_back(Edge(1, 2)); edges.push_back(Edge(2, 3)); edges.push_back(Edge(3, 0)); - facets.push_back(Facet(0, 4)); + facets.push_back(Facet(0, 4, MATERIAL_INTERIOR, 0)); edges.push_back(Edge(0, 3)); edges.push_back(Edge(3, 7)); edges.push_back(Edge(7, 4)); edges.push_back(Edge(4, 0)); - facets.push_back(Facet(4, 4)); + facets.push_back(Facet(4, 4, MATERIAL_INTERIOR, 0)); edges.push_back(Edge(3, 2)); edges.push_back(Edge(2, 6)); edges.push_back(Edge(6, 7)); edges.push_back(Edge(7, 3)); - facets.push_back(Facet(8, 4)); + facets.push_back(Facet(8, 4, MATERIAL_INTERIOR, 0)); edges.push_back(Edge(5, 6)); edges.push_back(Edge(6, 2)); edges.push_back(Edge(2, 1)); edges.push_back(Edge(1, 5)); - facets.push_back(Facet(12, 4)); + facets.push_back(Facet(12, 4, MATERIAL_INTERIOR, 0)); edges.push_back(Edge(4, 5)); edges.push_back(Edge(5, 1)); edges.push_back(Edge(1, 0)); edges.push_back(Edge(0, 4)); - facets.push_back(Facet(16, 4)); + facets.push_back(Facet(16, 4, MATERIAL_INTERIOR, 0)); edges.push_back(Edge(4, 7)); edges.push_back(Edge(7, 6)); edges.push_back(Edge(6, 5)); edges.push_back(Edge(5, 4)); - facets.push_back(Facet(20, 4)); + facets.push_back(Facet(20, 4, MATERIAL_INTERIOR, 0)); for (int i = 0; i < 8; ++i) positions[i].n = PxVec3(0, 0, 0); - return new Mesh(positions.data(), edges.data(), facets.data(), static_cast<uint32_t>(positions.size()), static_cast<uint32_t>(edges.size()), static_cast<uint32_t>(facets.size())); + return new MeshImpl(positions.data(), edges.data(), facets.data(), static_cast<uint32_t>(positions.size()), static_cast<uint32_t>(edges.size()), static_cast<uint32_t>(facets.size())); } } // namespace Blast diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.h new file mode 100644 index 0000000..ee36f9c --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.h @@ -0,0 +1,212 @@ +/* +* 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 NVBLASTAUTHORINGMESHIMPL_H +#define NVBLASTAUTHORINGMESHIMPL_H + +#include "NvBlastExtAuthoringMesh.h" +#include <vector> + +namespace Nv +{ +namespace Blast +{ + +/** + Class for internal mesh representation +*/ +class MeshImpl : public Mesh +{ +public: + + /** + Constructs mesh object from array of triangles. + \param[in] position Array of vertex positions + \param[in] normals Array of vertex normals + \param[in] uv Array of vertex uv coordinates + \param[in] verticesCount Vertices count + \param[in] indices Array of vertex indices. Indices contain vertex index triplets which form a mesh triangle. + \param[in] indicesCount Indices count (should be equal to numberOfTriangles * 3) + */ + MeshImpl(const physx::PxVec3* position, const physx::PxVec3* normals, const physx::PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount); + + /** + Constructs mesh object from array of facets. + \param[in] vertices Array of vertices + \param[in] edges Array of edges + \param[in] facets Array of facets + \param[in] posCount Vertices count + \param[in] edgesCount Edges count + \param[in] facetsCount Facets count + */ + MeshImpl(const Vertex* vertices, const Edge* edges, const Facet* facets, uint32_t posCount, uint32_t edgesCount, uint32_t facetsCount); + + ~MeshImpl(); + + virtual void release() override; + + /** + Return true if mesh is valid + */ + bool isValid() const override; + + /** + Return pointer on vertices array + */ + Vertex* getVerticesWritable() override; + + /** + Return pointer on edges array + */ + Edge* getEdgesWritable() override; + + /** + Return pointer on facets array + */ + Facet* getFacetsBufferWritable() override; + + /** + Return pointer on vertices array + */ + const Vertex* getVertices() const override; + + /** + Return pointer on edges array + */ + const Edge* getEdges() const override; + + /** + Return pointer on facets array + */ + const Facet* getFacetsBuffer() const override; + + /** + Return writable pointer on specified facet + */ + Facet* getFacetWritable(int32_t facet) override; + + /** + Return writable pointer on specified facet + */ + const Facet* getFacet(int32_t facet) const override; + + /** + Return edges count + */ + uint32_t getEdgesCount() const override; + + /** + Return vertices count + */ + uint32_t getVerticesCount() const override; + + /** + Return facet count + */ + uint32_t getFacetCount() const override; + + + /** + Return reference on mesh bounding box. + */ + const physx::PxBounds3& getBoundingBox() const override; + + /** + Return writable reference on mesh bounding box. + */ + physx::PxBounds3& getBoundingBoxWritable() override; + + /** + Recalculate bounding box + */ + void recalculateBoundingBox() override; + + /** + Compute mesh volume. Can be used only for triangulated meshes. + Return mesh volume. If mesh is not triangulated return 0. + */ + float getMeshVolume() override; + + + /** + Set per-facet material id. + */ + void setMaterialId(int32_t* materialIds) override; + + /** + Set per-facet smoothing group. + */ + void setSmoothingGroup(int32_t* smoothingGroup) override; + +private: + std::vector<Vertex> mVertices; + std::vector<Edge> mEdges; + std::vector<Facet> mFacets; + physx::PxBounds3 mBounds; +}; + + +/** + Helper functions +*/ + +/** + Set cutting box at some particular position. + \param[in] point Cutting face center + \param[in] normal Cutting face normal + \param[in] mesh Cutting box mesh + \param[in] size Cutting box size + \param[in] id Cutting box ID +*/ +void setCuttingBox(const physx::PxVec3& point, const physx::PxVec3& normal, Mesh* mesh, float size, int32_t id); +/** + Create cutting box at some particular position. + \param[in] point Cutting face center + \param[in] normal Cutting face normal + \param[in] size Cutting box size + \param[in] id Cutting box ID +*/ +Mesh* getCuttingBox(const physx::PxVec3& point, const physx::PxVec3& normal, float size, int32_t id); + +/** + Create box at some particular position. + \param[in] point Cutting face center + \param[in] size Cutting box size +*/ +Mesh* getBigBox(const physx::PxVec3& point, float size); + +/** + Create slicing box with noisy cutting surface. + \param[in] point Cutting face center + \param[in] normal Cutting face normal + \param[in] size Cutting box size + \param[in] jaggedPlaneSize Noisy surface size + \param[in] resolution Noisy surface resolution + \param[in] id Cutting box ID + \param[in] amplitude Noise amplitude + \param[in] frequency Noise frequency + \param[in] octaves Noise octaves + \param[in] seed Random generator seed, used for noise generation. +*/ +Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& normal, float size, float jaggedPlaneSize, uint32_t resolution, int32_t id, float amplitude, float frequency, int32_t octaves, int32_t seed); + + +/** + Inverses normals of cutting box and sets indices. + \param[in] mesh Cutting box mesh + \param[in] id Cutting box ID +*/ +void inverseNormalAndSetIndices(Mesh* mesh, int32_t id); + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTAUTHORINGMESHIMPL_H diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp new file mode 100644 index 0000000..72e9413 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp @@ -0,0 +1,975 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +// This warning arises when using some stl containers with older versions of VC +// c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1826): warning C4702: unreachable code +#include "NvPreprocessor.h" +#if NV_VC && NV_VC < 14 +#pragma warning(disable : 4702) +#endif + +#include "NvBlastExtAuthoringMeshNoiser.h" +#include "NvBlastExtAuthoringPerlinNoise.h" +#include <set> +#include <queue> +#include <NvBlastAssert.h> + +using namespace Nv::Blast; +using namespace std; + + +void MeshNoiser::computeFalloffAndNormals() +{ + // Map newly created vertices according to positions + + computePositionedMapping(); + + mGeometryGraph.resize(mVertices.size()); + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + if (mTrMeshEdToTr[i].c == 0) + { + continue; + } + int32_t v1 = mPositionMappedVrt[mEdges[i].s]; + int32_t v2 = mPositionMappedVrt[mEdges[i].e]; + + if (std::find(mGeometryGraph[v1].begin(), mGeometryGraph[v1].end(), v2) == mGeometryGraph[v1].end()) + mGeometryGraph[v1].push_back(v2); + if (std::find(mGeometryGraph[v2].begin(), mGeometryGraph[v2].end(), v1) == mGeometryGraph[v2].end()) + mGeometryGraph[v2].push_back(v1); + } + mVerticesDistances.clear(); + mVerticesDistances.resize(mVertices.size(), 10000.0f); + + std::queue<int32_t> que; + + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + if (mTrMeshEdToTr[i].c != 0 && (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == EXTERNAL_BORDER_EDGE)) + { + int32_t v1 = mPositionMappedVrt[mEdges[i].s]; + int32_t v2 = mPositionMappedVrt[mEdges[i].e]; + mVerticesDistances[v1] = 0.0f; + mVerticesDistances[v2] = 0.0f; + que.push(v1); + que.push(v2); + } + } + while (!que.empty()) + { + int32_t curr = que.front(); + que.pop(); + + for (uint32_t i = 0; i < mGeometryGraph[curr].size(); ++i) + { + int32_t to = mGeometryGraph[curr][i]; + float d = mVerticesDistances[curr] + 0.1f;// (mVertices[to].p - mVertices[curr].p).magnitudeSquared(); + if (d < mVerticesDistances[to]) + { + mVerticesDistances[to] = d; + que.push(to); + } + } + } + + for (uint32_t i = 0; i < mVerticesDistances.size(); ++i) + { + int32_t from = mPositionMappedVrt[i]; + mVerticesDistances[i] = mVerticesDistances[from]; + } +} + +bool edgeOverlapTest(PxVec3& as, PxVec3& ae, PxVec3& bs, PxVec3& be) +{ + //return false; + if (std::max(std::min(as.x, ae.x), std::min(bs.x, be.x)) > std::min(std::max(as.x, ae.x), std::max(bs.x, be.x))) return false; + if (std::max(std::min(as.y, ae.y), std::min(bs.y, be.y)) > std::min(std::max(as.y, ae.y), std::max(bs.y, be.y))) return false; + if (std::max(std::min(as.z, ae.z), std::min(bs.z, be.z)) > std::min(std::max(as.z, ae.z), std::max(bs.z, be.z))) return false; + + return ((bs - as).cross(ae - as)).magnitudeSquared() < 1e-6f && ((be - as).cross(ae - as)).magnitudeSquared() < 1e-6f; +} + +void MeshNoiser::computePositionedMapping() +{ + std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap; + mPositionMappedVrt.clear(); + mPositionMappedVrt.resize(mVertices.size()); + + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + auto it = mPosMap.find(mVertices[i].p); + + if (it == mPosMap.end()) + { + mPosMap[mVertices[i].p] = i; + mPositionMappedVrt[i] = i; + } + else + { + mPositionMappedVrt[i] = it->second; + } + } +} + + + + +void MeshNoiser::relax(int32_t iteration, float factor, std::vector<Vertex>& vertices) +{ + std::vector<PxVec3> verticesTemp(vertices.size()); + std::vector<PxVec3> normalsTemp(vertices.size()); + for (int32_t iter = 0; iter < iteration; ++iter) + { + for (uint32_t i = 0; i < vertices.size(); ++i) + { + if (mRestrictionFlag[i]) + { + continue; + } + PxVec3 cps = vertices[i].p; + PxVec3 cns = mVerticesNormalsSmoothed[i]; + PxVec3 averaged(0, 0, 0); + PxVec3 averagedNormal(0, 0, 0); + + for (uint32_t p = 0; p < mGeometryGraph[mPositionMappedVrt[i]].size(); ++p) + { + int32_t to = mGeometryGraph[mPositionMappedVrt[i]][p]; + averaged += vertices[to].p; + averagedNormal += mVerticesNormalsSmoothed[to]; + + } + averaged *= (1.0f / mGeometryGraph[mPositionMappedVrt[i]].size()); + averagedNormal *= (1.0f / mGeometryGraph[mPositionMappedVrt[i]].size()); + verticesTemp[i] = cps + (averaged - cps) * factor; + normalsTemp[i] = cns * (1.0f - factor) + averagedNormal * factor; + } + for (uint32_t i = 0; i < vertices.size(); ++i) + { + if (mRestrictionFlag[i]) + { + continue; + } + vertices[i].p = verticesTemp[i]; + mVerticesNormalsSmoothed[i] = normalsTemp[i].getNormalized(); + + } + } + +} + +NV_FORCE_INLINE void markEdge(int32_t ui, int32_t ed, std::vector<MeshNoiser::EdgeFlag>& shortMarkup, std::vector<int32_t>& lastOwner) +{ + if (shortMarkup[ed] == MeshNoiser::NONE) + { + if (ui == 0) + { + shortMarkup[ed] = MeshNoiser::EXTERNAL_EDGE; + } + else + { + shortMarkup[ed] = MeshNoiser::INTERNAL_EDGE; + } + lastOwner[ed] = ui; + } + else + { + if (ui != 0) + { + if (shortMarkup[ed] == MeshNoiser::EXTERNAL_EDGE) + { + shortMarkup[ed] = MeshNoiser::EXTERNAL_BORDER_EDGE; + } + if ((shortMarkup[ed] == MeshNoiser::INTERNAL_EDGE) && ui != lastOwner[ed]) + { + shortMarkup[ed] = MeshNoiser::INTERNAL_BORDER_EDGE; + } + } + else + { + if (shortMarkup[ed] != MeshNoiser::EXTERNAL_EDGE) + { + shortMarkup[ed] = MeshNoiser::EXTERNAL_BORDER_EDGE; + } + } + } +} + +void MeshNoiser::prebuildEdgeFlagArray() +{ + mRestrictionFlag.clear(); + mRestrictionFlag.resize(mVertices.size()); + mEdgeFlag.clear(); + mEdgeFlag.resize(mEdges.size(), NONE); + + std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap; + mPositionMappedVrt.clear(); + mPositionMappedVrt.resize(mVertices.size(), 0); + + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + auto it = mPosMap.find(mVertices[i].p); + + if (it == mPosMap.end()) + { + mPosMap[mVertices[i].p] = i; + mPositionMappedVrt[i] = i; + } + else + { + mPositionMappedVrt[i] = it->second; + } + } + + std::map<Edge, int32_t> mPositionEdgeMap; + std::vector<int32_t> mPositionBasedEdges(mEdges.size()); + + + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + Edge tmp = Edge(mPositionMappedVrt[mEdges[i].s], mPositionMappedVrt[mEdges[i].e]); + if (tmp.e < tmp.s) std::swap(tmp.e, tmp.s); + auto it = mPositionEdgeMap.find(tmp); + if (it == mPositionEdgeMap.end()) + { + mPositionEdgeMap[tmp] = i; + mPositionBasedEdges[i] = i; + } + else + { + mPositionBasedEdges[i] = it->second; + } + } + + std::vector<EdgeFlag> shortMarkup(mEdges.size(), NONE); + std::vector<int32_t> lastOwner(mEdges.size(), 0); + + std::vector<std::vector<int32_t> > edgeOverlap(mEdges.size()); + for (auto it1 = mPositionEdgeMap.begin(); it1 != mPositionEdgeMap.end(); ++it1) + { + auto it2 = it1; + it2++; + for (; it2 != mPositionEdgeMap.end(); ++it2) + { + Edge& ed1 = mEdges[it1->second]; + Edge& ed2 = mEdges[it2->second]; + + if (edgeOverlapTest(mVertices[ed1.s].p, mVertices[ed1.e].p, mVertices[ed2.s].p, mVertices[ed2.e].p)) + { + edgeOverlap[it1->second].push_back(it2->second); + } + } + } + + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + int32_t ui = mTriangles[i].userData; + int32_t ed = mPositionBasedEdges[findEdge(Edge(mTriangles[i].ea, mTriangles[i].eb))]; + + + markEdge(ui, ed, shortMarkup, lastOwner); + for (uint32_t ov = 0; ov < edgeOverlap[ed].size(); ++ov) + { + markEdge(ui, edgeOverlap[ed][ov], shortMarkup, lastOwner); + } + + ed = mPositionBasedEdges[findEdge(Edge(mTriangles[i].ea, mTriangles[i].ec))]; + markEdge(ui, ed, shortMarkup, lastOwner); + for (uint32_t ov = 0; ov < edgeOverlap[ed].size(); ++ov) + { + markEdge(ui, edgeOverlap[ed][ov], shortMarkup, lastOwner); + } + + ed = mPositionBasedEdges[findEdge(Edge(mTriangles[i].eb, mTriangles[i].ec))]; + markEdge(ui, ed, shortMarkup, lastOwner); + for (uint32_t ov = 0; ov < edgeOverlap[ed].size(); ++ov) + { + markEdge(ui, edgeOverlap[ed][ov], shortMarkup, lastOwner); + } + + } + + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + mEdgeFlag[i] = shortMarkup[mPositionBasedEdges[i]]; + } + + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + if (mTriangles[i].userData != 0) continue; + + int32_t ed = findEdge(Edge(mTriangles[i].ea, mTriangles[i].eb)); + mEdgeFlag[ed] = EXTERNAL_EDGE; + ed = findEdge(Edge(mTriangles[i].ec, mTriangles[i].eb)); + mEdgeFlag[ed] = EXTERNAL_EDGE; + ed = findEdge(Edge(mTriangles[i].ea, mTriangles[i].ec)); + mEdgeFlag[ed] = EXTERNAL_EDGE; + } +} + + + + +NV_FORCE_INLINE int32_t MeshNoiser::addVerticeIfNotExist(const Vertex& p) +{ + auto it = mVertMap.find(p); + if (it == mVertMap.end()) + { + mVertMap[p] = static_cast<int32_t>(mVertices.size()); + mVertices.push_back(p); + return static_cast<int32_t>(mVertices.size()) - 1; + } + else + { + return it->second; + } +} + +NV_FORCE_INLINE int32_t MeshNoiser::addEdge(const Edge& e) +{ + Edge ed = e; + if (ed.e < ed.s) std::swap(ed.s, ed.e); + auto it = mEdgeMap.find(ed); + if (it == mEdgeMap.end()) + { + mTrMeshEdToTr.push_back(EdgeToTriangles()); + mEdgeMap[ed] = (int)mEdgeMap.size(); + mEdges.push_back(ed); + mEdgeFlag.push_back(INTERNAL_EDGE); + return (int32_t)mEdges.size() - 1; + } + else + { + return it->second; + } +} + +NV_FORCE_INLINE int32_t MeshNoiser::findEdge(const Edge& e) +{ + Edge ed = e; + if (ed.e < ed.s) std::swap(ed.s, ed.e); + auto it = mEdgeMap.find(ed); + if (it == mEdgeMap.end()) + { + return -1; + } + else + { + return it->second; + } +} + + +/** + Weld input vertices, build edge and triangle buffers +*/ +void MeshNoiser::setMesh(const vector<Triangle>& mesh) +{ + uint32_t a, b, c; + PxBounds3 box; + box.setEmpty(); + for (uint32_t i = 0; i < mesh.size(); ++i) + { + const Triangle& tr = mesh[i]; + a = addVerticeIfNotExist(tr.a); + b = addVerticeIfNotExist(tr.b); + c = addVerticeIfNotExist(tr.c); + box.include(tr.a.p); + box.include(tr.b.p); + box.include(tr.c.p); + addEdge(Edge(a, b)); + addEdge(Edge(b, c)); + addEdge(Edge(a, c)); + mTriangles.push_back(TriangleIndexed(a, b, c)); + mTriangles.back().userData = tr.userData; + mTriangles.back().materialId = tr.materialId; + mTriangles.back().smoothingGroup = tr.smoothingGroup; + + } + mOffset = box.getCenter(); + mScale = max(box.getExtents(0), max(box.getExtents(1), box.getExtents(2))); + float invScale = 1.0f / mScale; + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].p = mVertices[i].p - box.getCenter(); + mVertices[i].p *= invScale; + } +} + + +void MeshNoiser::tesselateInternalSurface(float maxLenIn) +{ + if (mTriangles.empty()) + { + return; + } + + updateEdgeTriangleInfo(); + prebuildEdgeFlagArray(); + mRestrictionFlag.resize(mVertices.size(), 0); + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + if (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == EXTERNAL_BORDER_EDGE || mEdgeFlag[i] == INTERNAL_BORDER_EDGE) + { + mRestrictionFlag[mEdges[i].s] = 1; + mRestrictionFlag[mEdges[i].e] = 1; + } + } + + + float maxLen = maxLenIn; + float mlSq = maxLen * maxLen; + float minD = maxLen * 0.5f; + minD = minD * minD; + + for (int32_t iter = 0; iter < 15; ++iter) + { + updateVertEdgeInfo(); + uint32_t oldSize = (uint32_t)mEdges.size(); + for (uint32_t i = 0; i < oldSize; ++i) + { + if (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == INTERNAL_BORDER_EDGE) + { + continue; + } + if ((mVertices[mEdges[i].s].p - mVertices[mEdges[i].e].p).magnitudeSquared() < minD) + { + collapseEdge(i); + } + } + oldSize = (uint32_t)mEdges.size(); + updateEdgeTriangleInfo(); + for (uint32_t i = 0; i < oldSize; ++i) + { + if (mEdgeFlag[i] == EXTERNAL_EDGE) + { + continue; + } + if ((mVertices[mEdges[i].s].p - mVertices[mEdges[i].e].p).magnitudeSquared() > mlSq) + { + divideEdge(i); + } + } + } + computeFalloffAndNormals(); + prebuildTesselatedTriangles(); + isTesselated = true; +} + +void MeshNoiser::updateEdgeTriangleInfo() +{ + mTrMeshEdToTr.clear(); + mTrMeshEdToTr.resize(mEdges.size()); + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + TriangleIndexed& tr = mTriangles[i]; + if (tr.ea == NOT_VALID_VERTEX) + continue; + int32_t ed = addEdge(Edge(tr.ea, tr.eb)); + mTrMeshEdToTr[ed].add(i); + ed = addEdge(Edge(tr.ea, tr.ec)); + mTrMeshEdToTr[ed].add(i); + ed = addEdge(Edge(tr.ec, tr.eb)); + mTrMeshEdToTr[ed].add(i); + } +} + +void MeshNoiser::updateVertEdgeInfo() +{ + mVertexToTriangleMap.clear(); + mVertexToTriangleMap.resize(mVertices.size()); + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + TriangleIndexed& tr = mTriangles[i]; + if (tr.ea == NOT_VALID_VERTEX) continue; + mVertexToTriangleMap[tr.ea].push_back(i); + mVertexToTriangleMap[tr.eb].push_back(i); + mVertexToTriangleMap[tr.ec].push_back(i); + } + mVertexValence.clear(); + mVertexValence.resize(mVertices.size(), 0); + + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + if (mTrMeshEdToTr[i].c != 0) + { + mVertexValence[mEdges[i].s]++; + mVertexValence[mEdges[i].e]++; + } + } +} + + +void MeshNoiser::collapseEdge(int32_t id) +{ + Edge cEdge = mEdges[id]; + uint32_t from = cEdge.s; + uint32_t to = cEdge.e; + + if (mRestrictionFlag[from] && mRestrictionFlag[to]) + { + return; + } + + if (mVertexValence[from] > mVertexValence[to]) + { + std::swap(from, to); + } + + if (mRestrictionFlag[from]) + { + std::swap(from, to); + } + + std::set<int32_t> connectedToBegin; + std::set<int32_t> connectedToEnd; + std::set<int32_t> neighboorTriangles; + + int32_t trWithEdge[2] = {-1, -1}; + int32_t cntr = 0; + for (uint32_t i = 0; i < mVertexToTriangleMap[from].size(); ++i) + { + if (mTriangles[mVertexToTriangleMap[from][i]].ea == NOT_VALID_VERTEX) + continue; + if (neighboorTriangles.insert(mVertexToTriangleMap[from][i]).second && mTriangles[mVertexToTriangleMap[from][i]].isContainEdge(from, to)) + { + trWithEdge[cntr] = mVertexToTriangleMap[from][i]; + cntr++; + } + } + for (uint32_t i = 0; i < mVertexToTriangleMap[to].size(); ++i) + { + if (mTriangles[mVertexToTriangleMap[to][i]].ea == NOT_VALID_VERTEX) + continue; + if (neighboorTriangles.insert(mVertexToTriangleMap[to][i]).second && mTriangles[mVertexToTriangleMap[to][i]].isContainEdge(from, to)) + { + trWithEdge[cntr] = mVertexToTriangleMap[to][i]; + cntr++; + } + } + + if (cntr == 0) + { + return; + } + if (cntr > 2) + { + return; + } + + for (uint32_t i: neighboorTriangles) + { + if (mTriangles[i].ea == from || mTriangles[i].eb == from || mTriangles[i].ec == from) + { + if (mTriangles[i].ea != to && mTriangles[i].ea != from) + connectedToBegin.insert(mTriangles[i].ea); + if (mTriangles[i].eb != to && mTriangles[i].eb != from) + connectedToBegin.insert(mTriangles[i].eb); + if (mTriangles[i].ec != to && mTriangles[i].ec != from) + connectedToBegin.insert(mTriangles[i].ec); + } + + if (mTriangles[i].ea == to || mTriangles[i].eb == to || mTriangles[i].ec == to) + { + if (mTriangles[i].ea != to && mTriangles[i].ea != from) + connectedToEnd.insert(mTriangles[i].ea); + if (mTriangles[i].eb != to && mTriangles[i].eb != from) + connectedToEnd.insert(mTriangles[i].eb); + if (mTriangles[i].ec != to && mTriangles[i].ec != from) + connectedToEnd.insert(mTriangles[i].ec); + } + } + bool canBeCollapsed = true; + for (auto it = connectedToBegin.begin(); it != connectedToBegin.end(); ++it) + { + uint32_t currV = *it; + if (connectedToEnd.find(currV) == connectedToEnd.end()) + continue; + bool found = false; + for (int32_t tr : neighboorTriangles) + { + if ((mTriangles[tr].ea == from || mTriangles[tr].eb == from || mTriangles[tr].ec == from) && + (mTriangles[tr].ea == to || mTriangles[tr].eb == to || mTriangles[tr].ec == to) && + (mTriangles[tr].ea == currV || mTriangles[tr].eb == currV || mTriangles[tr].ec == currV)) + { + found = true; + break; + } + } + if (!found) + { + canBeCollapsed = false; + break; + } + } + if (canBeCollapsed) + { + for (int32_t i : neighboorTriangles) + { + if (trWithEdge[0] == i) continue; + if (cntr == 2 && trWithEdge[1] == i) continue; + TriangleIndexed tr = mTriangles[i]; + PxVec3 oldNormal = (mVertices[tr.eb].p - mVertices[tr.ea].p).cross(mVertices[tr.ec].p - mVertices[tr.ea].p); + + if (tr.ea == from) + { + tr.ea = to; + } + else + if (tr.eb == from) + { + tr.eb = to; + } + else + if (tr.ec == from) + { + tr.ec = to; + } + PxVec3 newNormal = (mVertices[tr.eb].p - mVertices[tr.ea].p).cross(mVertices[tr.ec].p - mVertices[tr.ea].p); + if (newNormal.magnitude() < 1e-8f) + { + canBeCollapsed = false; + break; + } + if (oldNormal.dot(newNormal) < 0) + { + canBeCollapsed = false; + break; + } + } + mTriangles[trWithEdge[0]].ea = NOT_VALID_VERTEX; + if (cntr == 2)mTriangles[trWithEdge[1]].ea = NOT_VALID_VERTEX; + + for (int32_t i : neighboorTriangles) + { + if (mTriangles[i].ea == NOT_VALID_VERTEX) + continue; + if (mTriangles[i].ea == from) + { + mTriangles[i].ea = to; + mVertexToTriangleMap[from].clear(); + mVertexToTriangleMap[to].push_back(i); + } + else + if (mTriangles[i].eb == from) + { + mTriangles[i].eb = to; + mVertexToTriangleMap[from].clear(); + mVertexToTriangleMap[to].push_back(i); + } + else + if (mTriangles[i].ec == from) + { + mTriangles[i].ec = to; + mVertexToTriangleMap[from].clear(); + mVertexToTriangleMap[to].push_back(i); + } + } + } +} + + +void MeshNoiser::divideEdge(int32_t id) +{ + + if (mTrMeshEdToTr[id].c == 0 ) + { + return; + } + + Edge cEdge = mEdges[id]; + EdgeFlag snapRestriction = mEdgeFlag[id]; + Vertex middle; + uint32_t nv = NOT_VALID_VERTEX; + for (int32_t t = 0; t < mTrMeshEdToTr[id].c; ++t) + { + int32_t oldTriangleIndex = mTrMeshEdToTr[id].tr[t]; + TriangleIndexed tr = mTriangles[mTrMeshEdToTr[id].tr[t]]; + + if (tr.ea == NOT_VALID_VERTEX) + { + continue; + } + + uint32_t pbf[3]; + pbf[0] = tr.ea; + pbf[1] = tr.eb; + pbf[2] = tr.ec; + for (int32_t p = 0; p < 3; ++p) + { + int32_t pnx = (p + 1) % 3; + int32_t opp = (p + 2) % 3; + + if ((pbf[p] == cEdge.s && pbf[pnx] == cEdge.e) || (pbf[p] == cEdge.e && pbf[pnx] == cEdge.s)) + { + if (nv == NOT_VALID_VERTEX) + { + middle.p = (mVertices[pbf[p]].p + mVertices[pbf[pnx]].p) * 0.5f; + middle.n = (mVertices[pbf[p]].n + mVertices[pbf[pnx]].n) * 0.5f; + middle.uv[0] = (mVertices[pbf[p]].uv[0] + mVertices[pbf[pnx]].uv[0]) * 0.5f; + + nv = (uint32_t)mVertices.size(); + mVertices.push_back(middle); + } + if (nv < mRestrictionFlag.size()) + { + mRestrictionFlag[nv] = ((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE)); + } + else + { + mRestrictionFlag.push_back((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE)); + } + + uint32_t ind1 = addEdge(Edge(pbf[p], nv)); + uint32_t ind2 = addEdge(Edge(nv, pbf[pnx])); + uint32_t ind3 = addEdge(Edge(nv, pbf[opp])); + + + mEdgeFlag[ind1] = snapRestriction; + mEdgeFlag[ind2] = snapRestriction; + mEdgeFlag[ind3] = INTERNAL_EDGE; + + mTrMeshEdToTr[ind1].add(mTrMeshEdToTr[id].tr[t]); + int32_t userInfo = mTriangles[mTrMeshEdToTr[id].tr[t]].userData; + int32_t matId = mTriangles[mTrMeshEdToTr[id].tr[t]].materialId; + mTriangles[mTrMeshEdToTr[id].tr[t]] = TriangleIndexed(pbf[p], nv, pbf[opp]); + mTriangles[mTrMeshEdToTr[id].tr[t]].userData = userInfo; + mTriangles[mTrMeshEdToTr[id].tr[t]].materialId = matId; + mTrMeshEdToTr[ind2].add((int32_t)mTriangles.size()); + mTrMeshEdToTr[ind3].add((int32_t)mTrMeshEdToTr[id].tr[t]); + mTrMeshEdToTr[ind3].add((int32_t)mTriangles.size()); + mTriangles.push_back(TriangleIndexed(nv,pbf[pnx], pbf[opp])); + mTriangles.back().userData = userInfo; + mTriangles.back().materialId = matId; + int32_t ed1 = findEdge(Edge(pbf[pnx], pbf[opp])); + mTrMeshEdToTr[ed1].replace(oldTriangleIndex, (int32_t)mTriangles.size() - 1); + break; + } + } + } +} + + +float falloffFunction(float x, float mx) +{ + float t = (x) / (mx + 1e-6f); + t = std::min(1.0f, t); + return t * t; +} + +void MeshNoiser::recalcNoiseDirs() +{ + /** + Compute normals direction to apply noise + */ + mVerticesNormalsSmoothed.resize(mVertices.size(), PxVec3(0, 0, 0)); + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + if (mTriangles[i].ea == NOT_VALID_VERTEX) + { + continue; + } + TriangleIndexed& tr = mTriangles[i]; + if (tr.userData == 0) continue; + + if (tr.userData < 0) + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += mVertices[tr.ea].n.getNormalized(); + else + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] -= mVertices[tr.ea].n.getNormalized(); + + if (tr.userData < 0) + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += mVertices[tr.eb].n.getNormalized(); + else + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] -= mVertices[tr.eb].n.getNormalized(); + + if (tr.userData < 0) + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] += mVertices[tr.ec].n.getNormalized(); + else + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] -= mVertices[tr.ec].n.getNormalized(); + + } + for (uint32_t i = 0; i < mVerticesNormalsSmoothed.size(); ++i) + { + + mVerticesNormalsSmoothed[i] = mVerticesNormalsSmoothed[mPositionMappedVrt[i]]; + mVerticesNormalsSmoothed[i].normalize(); + } +} + + + +void MeshNoiser::applyNoise(SimplexNoise& noise, float falloff, int32_t /*relaxIterations*/, float /*relaxFactor*/) +{ + NVBLAST_ASSERT(isTesselated); + if (isTesselated == false) + { + return; + } + mRestrictionFlag.clear(); + mRestrictionFlag.resize(mVertices.size(), false); + + for (uint32_t i = 0; i < mEdges.size(); ++i) + { + if (mTrMeshEdToTr[i].c != 0) + { + if (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == EXTERNAL_BORDER_EDGE) + { + mRestrictionFlag[mEdges[i].e] = true; + mRestrictionFlag[mEdges[i].s] = true; + } + } + } + std::vector<Vertex> localVertices = mVertices; + + recalcNoiseDirs(); + + //relax(relaxIterations, relaxFactor, localVertices); + + + /** + Apply noise + */ + for (uint32_t i = 0; i < localVertices.size(); ++i) + { + + if (!mRestrictionFlag[i]) + { + + float d = noise.sample(localVertices[i].p); + localVertices[i].p += (falloffFunction(mVerticesDistances[i], falloff)) * mVerticesNormalsSmoothed[i] * d; + } + } + + + /* Recalculate smoothed normals*/ + mVerticesNormalsSmoothed.assign(mVerticesNormalsSmoothed.size(), PxVec3(0, 0, 0)); + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + if (mTriangles[i].ea == NOT_VALID_VERTEX) + { + continue; + } + TriangleIndexed& tr = mTriangles[i]; + if (tr.userData == 0) continue; + + Triangle pTr(localVertices[tr.ea], localVertices[tr.eb], localVertices[tr.ec]); + PxVec3 nrm = pTr.getNormal().getNormalized(); + + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += nrm; + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += nrm; + mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] += nrm; + } + for (uint32_t i = 0; i < mVerticesNormalsSmoothed.size(); ++i) + { + mVerticesNormalsSmoothed[i] = mVerticesNormalsSmoothed[mPositionMappedVrt[i]]; + mVerticesNormalsSmoothed[i].normalize(); + } + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + if (mTriangles[i].ea == NOT_VALID_VERTEX) + { + continue; + } + TriangleIndexed& tr = mTriangles[i]; + if (tr.userData == 0) continue; + + localVertices[tr.ea].n = mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]]; + localVertices[tr.eb].n = mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]]; + localVertices[tr.ec].n = mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]]; + } + + mResultTriangles.clear(); + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + if (mTriangles[i].ea == NOT_VALID_VERTEX) + { + continue; + } + mResultTriangles.push_back(Triangle(localVertices[mTriangles[i].ea], localVertices[mTriangles[i].eb], localVertices[mTriangles[i].ec])); + mResultTriangles.back().userData = mTriangles[i].userData; + mResultTriangles.back().materialId = mTriangles[i].materialId; + mResultTriangles.back().smoothingGroup = mTriangles[i].smoothingGroup; + + } +} + + +void MeshNoiser::prebuildTesselatedTriangles() +{ + mResultTriangles.clear(); + + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].p = mVertices[i].p * mScale + mOffset; + } + + for (uint32_t i = 0; i < mTriangles.size(); ++i) + { + if (mTriangles[i].ea == NOT_VALID_VERTEX) + { + continue; + } + mResultTriangles.push_back(Triangle(mVertices[mTriangles[i].ea], mVertices[mTriangles[i].eb], mVertices[mTriangles[i].ec])); + mResultTriangles.back().userData = mTriangles[i].userData; + mResultTriangles.back().materialId = mTriangles[i].materialId; + mResultTriangles.back().smoothingGroup = mTriangles[i].smoothingGroup; + + } + +} + + +std::vector<Triangle> MeshNoiser::getMesh() +{ + return mResultTriangles; +} + + +void MeshNoiser::reset() +{ + mVertices.clear(); + mTriangles.clear(); + mEdges.clear(); + mVertMap.clear(); + mEdgeMap.clear(); + mResultTriangles.clear(); + mRestrictionFlag.clear(); + mEdgeFlag.clear(); + mTrMeshEdToTr.clear(); + mVertexValence.clear(); + mVertexToTriangleMap.clear(); + + mVerticesDistances.clear(); + mVerticesNormalsSmoothed.clear(); + mPositionMappedVrt.clear(); + mGeometryGraph.clear(); + + isTesselated = false; + mOffset = PxVec3(0, 0, 0); + mScale = 1.0f; +}
\ No newline at end of file diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h new file mode 100644 index 0000000..893cf63 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h @@ -0,0 +1,193 @@ +// 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 NVBLASTEXTAUTHORINGMESHNOISER_H +#define NVBLASTEXTAUTHORINGMESHNOISER_H +#include <vector> +#include <map> +#include "NvBlastExtAuthoringInternalCommon.h" + +namespace Nv +{ + namespace Blast + { + class SimplexNoise; + + /** + Structure used on tesselation stage. Maps edge to two neighboor triangles + */ + struct EdgeToTriangles + { + int32_t tr[2]; + int32_t c; + EdgeToTriangles() + { + c = 0; + } + /** + Add triangle to edge. Should not be called more than twice for one edge!!!!. + */ + void add(int32_t t) + { + tr[c] = t; + ++c; + } + /** + Replaces mapping from one triangle to another. + */ + void replace(int32_t from, int32_t to) + { + if (tr[0] == from) + { + tr[0] = to; + } + else + { + if (c == 2 && tr[1] == from) + { + tr[1] = to; + } + } + } + /** + Get triangle which is mapped by this edge and which index is different than provided. + */ + int32_t getNot(int32_t id) + { + if (tr[0] != id) + { + return tr[0]; + } + if (c == 2 && tr[1] != id) + { + return tr[1]; + } + return -1; + } + + }; + + /** + Tool for graphic mesh tesselation and adding noise to internal surface. Each triangle must have initialized + Triangle::userInfo field (0 for external surface triangles and != 0 for internal) + */ + class MeshNoiser + { + public: + MeshNoiser() + { + reset(); + } + + void reset(); + + /** + Edge flags + */ + enum EdgeFlag { INTERNAL_EDGE, EXTERNAL_BORDER_EDGE, INTERNAL_BORDER_EDGE, EXTERNAL_EDGE, NONE }; + + + /** + Set mesh to tesselate and apply noise + */ + void setMesh(const std::vector<Triangle>& mesh); + + /** + Tesselate internal surface. + \param[in] maxLen - maximal length of edge on internal surface. + */ + void tesselateInternalSurface(float maxLen); + + /** + Apply noise to internal surface. Must be called only after tesselation!!! + \param[in] noise - noise generator + \param[in] falloff - damping of noise around of external surface + \param[in] relaxIterations - number of smoothing iterations before applying noise + \param[in] relaxFactor - amount of smooting before applying noise. + */ + void applyNoise(SimplexNoise& noise, float falloff, int32_t relaxIterations, float relaxFactor); + + std::vector<Triangle> getMesh(); + + private: + PxVec3 mOffset; + float mScale; + bool isTesselated; + /** + Mesh data + */ + std::vector<Vertex> mVertices; + std::vector<TriangleIndexed> mTriangles; + std::vector<Edge> mEdges; + std::map<Vertex, int32_t, VrtComp> mVertMap; + std::map<Edge, int32_t> mEdgeMap; + + + /** + Final triangles. + */ + std::vector<Triangle> mResultTriangles; + + + int32_t addVerticeIfNotExist(const Vertex& p); + int32_t addEdge(const Edge& e); + int32_t findEdge(const Edge& e); + + + + void collapseEdge(int32_t id); + void divideEdge(int32_t id); + void updateVertEdgeInfo(); + void updateEdgeTriangleInfo(); + void relax(int32_t iterations, float factor, std::vector<Vertex>& vertices); + void recalcNoiseDirs(); + + + std::vector<bool> mRestrictionFlag; + std::vector<EdgeFlag> mEdgeFlag; + std::vector<EdgeToTriangles> mTrMeshEdToTr; + std::vector<int32_t> mVertexValence; + std::vector<std::vector<int32_t> > mVertexToTriangleMap; + + + + std::vector<float> mVerticesDistances; + std::vector<physx::PxVec3> mVerticesNormalsSmoothed; + std::vector<int32_t> mPositionMappedVrt; + std::vector<std::vector<int32_t> > mGeometryGraph; + + void prebuildEdgeFlagArray(); + void computePositionedMapping(); + void computeFalloffAndNormals(); + + void prebuildTesselatedTriangles(); + }; + + } // namespace Blast +} // namespace Nv +#endif // ! NVBLASTEXTAUTHORINGMESHNOISER_H diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h index 95308c2..2b17f0c 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #ifndef NVBLASTEXTAUTHORINGPERLINNOISE_H #define NVBLASTEXTAUTHORINGPERLINNOISE_H diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp index 0b7187f..cc2442c 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.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. + // This warning arises when using some stl containers with older versions of VC // c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1826): warning C4702: unreachable code @@ -24,13 +42,11 @@ #include <set> #include "NvBlastExtAuthoringBooleanTool.h" #include <queue> -#include "NvBlastExtAuthoringPerlinNoise.h" #include <NvBlastAssert.h> using physx::PxVec3; using physx::PxVec2; -#define VEC_COMPARISON_OFFSET 1e-5f #define TWO_VERTICES_THRESHOLD 1e-7 namespace Nv @@ -38,40 +54,6 @@ namespace Nv namespace Blast { -bool VrtComp::operator()(const Vertex& a, const Vertex& b) const -{ - if (a.p.x + VEC_COMPARISON_OFFSET < b.p.x) return true; - if (a.p.x - VEC_COMPARISON_OFFSET > b.p.x) return false; - if (a.p.y + VEC_COMPARISON_OFFSET < b.p.y) return true; - if (a.p.y - VEC_COMPARISON_OFFSET > b.p.y) return false; - if (a.p.z + VEC_COMPARISON_OFFSET < b.p.z) return true; - if (a.p.z - VEC_COMPARISON_OFFSET > b.p.z) return false; - - if (a.n.x + 1e-3 < b.n.x) return true; - if (a.n.x - 1e-3 > b.n.x) return false; - if (a.n.y + 1e-3 < b.n.y) return true; - if (a.n.y - 1e-3 > b.n.y) return false; - if (a.n.z + 1e-3 < b.n.z) return true; - if (a.n.z - 1e-3 > b.n.z) return false; - - - if (a.uv[0].x + 1e-3 < b.uv[0].x) return true; - if (a.uv[0].x - 1e-3 > b.uv[0].x) return false; - if (a.uv[0].y + 1e-3 < b.uv[0].y) return true; - return false; -} - -bool VrtPositionComparator::operator()(const PxVec3& a, const PxVec3& b) const -{ - if (a.x + VEC_COMPARISON_OFFSET < b.x) return true; - if (a.x - VEC_COMPARISON_OFFSET > b.x) return false; - if (a.y + VEC_COMPARISON_OFFSET < b.y) return true; - if (a.y - VEC_COMPARISON_OFFSET > b.y) return false; - if (a.z + VEC_COMPARISON_OFFSET < b.z) return true; - if (a.z - VEC_COMPARISON_OFFSET > b.z) return false; - return false; -} - NV_FORCE_INLINE bool compareTwoVertices(const PxVec3& a, const PxVec3& b) { return std::abs(b.x - a.x) < TWO_VERTICES_THRESHOLD && std::abs(b.y - a.y) < TWO_VERTICES_THRESHOLD && std::abs(b.z - a.z) < TWO_VERTICES_THRESHOLD; @@ -100,7 +82,7 @@ inline bool pointInside(PxVec2 a, PxVec2 b, PxVec2 c, PxVec2 pnt) (v1 <= 0.0f && v2 <= 0.0f && v3 <= 0.0f); } -void ChunkPostProcessor::triangulatePolygonWithEarClipping(std::vector<uint32_t>& inputPolygon, Vertex* vert, ProjectionDirections dir) +void Triangulator::triangulatePolygonWithEarClipping(std::vector<uint32_t>& inputPolygon, Vertex* vert, ProjectionDirections dir) { // return; //for (uint32_t i = 0; i < inputPolygon.size(); ++i) @@ -144,10 +126,6 @@ void ChunkPostProcessor::triangulatePolygonWithEarClipping(std::vector<uint32_t> } if (good) { - addEdgeTr(Edge(inputPolygon[curr], inputPolygon[prev])); - addEdgeTr(Edge(inputPolygon[next], inputPolygon[prev])); - addEdgeTr(Edge(inputPolygon[curr], inputPolygon[next])); - mBaseMeshTriangles.push_back(TriangleIndexed(inputPolygon[curr], inputPolygon[prev], inputPolygon[next])); vCount--; inputPolygon.erase(inputPolygon.begin() + curr); @@ -321,7 +299,7 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> return 0; } -void ChunkPostProcessor::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* vertices, int32_t userData) +void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* vertices, int32_t userData, int32_t materialId, int32_t smoothingGroup) { std::vector<std::vector<uint32_t> > serializedLoops; @@ -439,7 +417,7 @@ void ChunkPostProcessor::buildPolygonAndTriangulate(std::vector<Edge>& edges, Ve int32_t baseLoop = loopsInfo[extPoly].index; for (uint32_t intPoly = 0; intPoly < loopsInfo.size(); ++intPoly) { - if (loopsInfo[intPoly].area > 0 || loopsInfo[intPoly].used || abs(loopsInfo[intPoly].area) > loopsInfo[extPoly].area) + if (loopsInfo[intPoly].area > 0 || loopsInfo[intPoly].used || std::abs(loopsInfo[intPoly].area) > loopsInfo[extPoly].area) { continue; } @@ -454,11 +432,13 @@ void ChunkPostProcessor::buildPolygonAndTriangulate(std::vector<Edge>& edges, Ve } for (uint32_t i = oldSize; i < mBaseMeshTriangles.size(); ++i) { - mBaseMeshTriangles[i].userInfo = userData; + mBaseMeshTriangles[i].userData = userData; + mBaseMeshTriangles[i].materialId = materialId; + mBaseMeshTriangles[i].smoothingGroup = smoothingGroup; } } -NV_FORCE_INLINE int32_t ChunkPostProcessor::addVerticeIfNotExist(Vertex& p) +NV_FORCE_INLINE int32_t Triangulator::addVerticeIfNotExist(const Vertex& p) { auto it = mVertMap.find(p); if (it == mVertMap.end()) @@ -473,7 +453,7 @@ NV_FORCE_INLINE int32_t ChunkPostProcessor::addVerticeIfNotExist(Vertex& p) } } -NV_FORCE_INLINE void ChunkPostProcessor::addEdgeIfValid(EdgeWithParent& ed) +NV_FORCE_INLINE void Triangulator::addEdgeIfValid(EdgeWithParent& ed) { if (ed.s == ed.e) return; @@ -497,14 +477,14 @@ NV_FORCE_INLINE void ChunkPostProcessor::addEdgeIfValid(EdgeWithParent& ed) -void ChunkPostProcessor::prepare(Mesh* mesh) +void Triangulator::prepare(const Mesh* mesh) { - Edge* ed = mesh->getEdges(); - Vertex* vr = mesh->getVertices(); + const Edge* ed = mesh->getEdges(); + const Vertex* vr = mesh->getVertices(); mBaseMapping.resize(mesh->getVerticesCount()); for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) { - Facet* fc = mesh->getFacet(i); + const Facet* fc = mesh->getFacet(i); for (uint32_t j = fc->firstEdgeNumber; j < fc->firstEdgeNumber + fc->edgesCount; ++j) { int32_t a = addVerticeIfNotExist(vr[ed[j].s]); @@ -527,29 +507,17 @@ void ChunkPostProcessor::prepare(Mesh* mesh) } -void ChunkPostProcessor::reset() +void Triangulator::reset() { - isTesselated = false; mVertices.clear(); mBaseMeshEdges.clear(); mVertMap.clear(); mEdgeMap.clear(); - mTrMeshEdgeMap.clear(); - mTrMeshEdges.clear(); - mTrMeshEdToTr.clear(); mBaseMeshTriangles.clear(); - mEdgeFlag.clear(); - mVertexValence.clear(); - mRestrictionFlag.clear(); - mVerticesDistances.clear(); - mVerticesNormalsSmoothed.clear(); - mBaseMeshResultTriangles.clear(); - mTesselatedMeshResultTriangles.clear(); - mTesselatedMeshTriangles.clear(); } -void ChunkPostProcessor::triangulate(Mesh* mesh) +void Triangulator::triangulate(const Mesh* mesh) { reset(); if (mesh == nullptr || !mesh->isValid()) @@ -569,17 +537,16 @@ void ChunkPostProcessor::triangulate(Mesh* mesh) { if (temp.empty() == false) { - buildPolygonAndTriangulate(temp, &mVertices[0], mesh->getFacet(fP)->userData); + buildPolygonAndTriangulate(temp, mVertices.data(), mesh->getFacet(fP)->userData, mesh->getFacet(fP)->materialId, mesh->getFacet(fP)->smoothingGroup); } temp.clear(); fP = mBaseMeshEdges[i].parent; } temp.push_back(Edge(mBaseMeshEdges[i].s, mBaseMeshEdges[i].e)); } - buildPolygonAndTriangulate(temp, &mVertices[0], mesh->getFacet(fP)->userData); + buildPolygonAndTriangulate(temp, mVertices.data(), mesh->getFacet(fP)->userData, mesh->getFacet(fP)->materialId, mesh->getFacet(fP)->smoothingGroup); /* Build final triangles */ - mBaseMeshResultTriangles.clear(); for (uint32_t i = 0; i < mBaseMeshTriangles.size(); ++i) { @@ -588,683 +555,19 @@ void ChunkPostProcessor::triangulate(Mesh* mesh) continue; } mBaseMeshResultTriangles.push_back(Triangle(mVertices[mBaseMeshTriangles[i].ea], mVertices[mBaseMeshTriangles[i].eb], mVertices[mBaseMeshTriangles[i].ec])); - mBaseMeshResultTriangles.back().userInfo = mBaseMeshTriangles[i].userInfo; - } - - computePositionedMapping(); -} - -void ChunkPostProcessor::prebuildTesselatedTriangles() -{ - mTesselatedMeshResultTriangles.clear(); - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - if (mTesselatedMeshTriangles[i].ea == NOT_VALID_VERTEX) - { - continue; - } - mTesselatedMeshResultTriangles.push_back(Triangle(mVertices[mTesselatedMeshTriangles[i].ea], mVertices[mTesselatedMeshTriangles[i].eb], mVertices[mTesselatedMeshTriangles[i].ec])); - mTesselatedMeshResultTriangles.back().userInfo = mTesselatedMeshTriangles[i].userInfo; - } - -} - - -int32_t ChunkPostProcessor::addEdgeTr(const Edge& e) -{ - Edge ed = e; - if (ed.e < ed.s) std::swap(ed.s, ed.e); - auto it = mTrMeshEdgeMap.find(ed); - if (it == mTrMeshEdgeMap.end()) - { - mTrMeshEdToTr.push_back(EdgeToTriangles()); - mTrMeshEdgeMap[ed] = (int)mTrMeshEdToTr.size() - 1; - mTrMeshEdges.push_back(ed); - mEdgeFlag.push_back(INTERNAL_EDGE); - return (int32_t)mTrMeshEdToTr.size() - 1; - } - else - { - return it->second; - } -} - -int32_t ChunkPostProcessor::findEdge(const Edge& e) -{ - Edge ed = e; - if (ed.e < ed.s) std::swap(ed.s, ed.e); - auto it = mTrMeshEdgeMap.find(ed); - if (it == mTrMeshEdgeMap.end()) - { - return -1; - } - return it->second; -} - -void ChunkPostProcessor::updateEdgeTriangleInfo() -{ - mTrMeshEdToTr.clear(); - mTrMeshEdToTr.resize(mTrMeshEdges.size()); - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - TriangleIndexed& tr = mTesselatedMeshTriangles[i]; - if (tr.ea == NOT_VALID_VERTEX) - continue; - int32_t ed = addEdgeTr(Edge(tr.ea, tr.eb)); - mTrMeshEdToTr[ed].add(i); - ed = addEdgeTr(Edge(tr.ea, tr.ec)); - mTrMeshEdToTr[ed].add(i); - ed = addEdgeTr(Edge(tr.ec, tr.eb)); - mTrMeshEdToTr[ed].add(i); - } -} - -void ChunkPostProcessor::updateVertEdgeInfo() -{ - mVertexToTriangleMap.clear(); - mVertexToTriangleMap.resize(mVertices.size()); - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - TriangleIndexed& tr = mTesselatedMeshTriangles[i]; - if (tr.ea == NOT_VALID_VERTEX) continue; - mVertexToTriangleMap[tr.ea].push_back(i); - mVertexToTriangleMap[tr.eb].push_back(i); - mVertexToTriangleMap[tr.ec].push_back(i); - } - mVertexValence.clear(); - mVertexValence.resize(mVertices.size(), 0); - - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - if (mTrMeshEdToTr[i].c != 0) - { - mVertexValence[mTrMeshEdges[i].s]++; - mVertexValence[mTrMeshEdges[i].e]++; - } - } -} - - -void ChunkPostProcessor::collapseEdge(int32_t id) -{ - Edge cEdge = mTrMeshEdges[id]; - uint32_t from = cEdge.s; - uint32_t to = cEdge.e; - - - if (mRestrictionFlag[from] && mRestrictionFlag[to]) - { - return; - } - - if (mVertexValence[from] > mVertexValence[to]) - { - std::swap(from, to); - } - - if (mRestrictionFlag[from]) - { - std::swap(from, to); - } - - std::set<int32_t> connectedToBegin; - std::set<int32_t> connectedToEnd; - std::set<int32_t> neighboorTriangles; - - int32_t trWithEdge[2] = {-1, -1}; - int32_t cntr = 0; - for (uint32_t i = 0; i < mVertexToTriangleMap[from].size(); ++i) - { - if (mTesselatedMeshTriangles[mVertexToTriangleMap[from][i]].ea == NOT_VALID_VERTEX) - continue; - if (neighboorTriangles.insert(mVertexToTriangleMap[from][i]).second && mTesselatedMeshTriangles[mVertexToTriangleMap[from][i]].isContainEdge(from, to)) - { - trWithEdge[cntr] = mVertexToTriangleMap[from][i]; - cntr++; - } - } - for (uint32_t i = 0; i < mVertexToTriangleMap[to].size(); ++i) - { - if (mTesselatedMeshTriangles[mVertexToTriangleMap[to][i]].ea == NOT_VALID_VERTEX) - continue; - if (neighboorTriangles.insert(mVertexToTriangleMap[to][i]).second && mTesselatedMeshTriangles[mVertexToTriangleMap[to][i]].isContainEdge(from, to)) - { - trWithEdge[cntr] = mVertexToTriangleMap[to][i]; - cntr++; - } - } - - if (cntr == 0) - { - return; - } - if (cntr > 2) - { - return; - } - - for (uint32_t i: neighboorTriangles) - { - if (mTesselatedMeshTriangles[i].ea == from || mTesselatedMeshTriangles[i].eb == from || mTesselatedMeshTriangles[i].ec == from) - { - if (mTesselatedMeshTriangles[i].ea != to && mTesselatedMeshTriangles[i].ea != from) - connectedToBegin.insert(mTesselatedMeshTriangles[i].ea); - if (mTesselatedMeshTriangles[i].eb != to && mTesselatedMeshTriangles[i].eb != from) - connectedToBegin.insert(mTesselatedMeshTriangles[i].eb); - if (mTesselatedMeshTriangles[i].ec != to && mTesselatedMeshTriangles[i].ec != from) - connectedToBegin.insert(mTesselatedMeshTriangles[i].ec); - } - - if (mTesselatedMeshTriangles[i].ea == to || mTesselatedMeshTriangles[i].eb == to || mTesselatedMeshTriangles[i].ec == to) - { - if (mTesselatedMeshTriangles[i].ea != to && mTesselatedMeshTriangles[i].ea != from) - connectedToEnd.insert(mTesselatedMeshTriangles[i].ea); - if (mTesselatedMeshTriangles[i].eb != to && mTesselatedMeshTriangles[i].eb != from) - connectedToEnd.insert(mTesselatedMeshTriangles[i].eb); - if (mTesselatedMeshTriangles[i].ec != to && mTesselatedMeshTriangles[i].ec != from) - connectedToEnd.insert(mTesselatedMeshTriangles[i].ec); - } - } - bool canBeCollapsed = true; - for (auto it = connectedToBegin.begin(); it != connectedToBegin.end(); ++it) - { - uint32_t currV = *it; - if (connectedToEnd.find(currV) == connectedToEnd.end()) - continue; - bool found = false; - for (int32_t tr : neighboorTriangles) - { - if ((mTesselatedMeshTriangles[tr].ea == from || mTesselatedMeshTriangles[tr].eb == from || mTesselatedMeshTriangles[tr].ec == from) && - (mTesselatedMeshTriangles[tr].ea == to || mTesselatedMeshTriangles[tr].eb == to || mTesselatedMeshTriangles[tr].ec == to) && - (mTesselatedMeshTriangles[tr].ea == currV || mTesselatedMeshTriangles[tr].eb == currV || mTesselatedMeshTriangles[tr].ec == currV)) - { - found = true; - break; - } - } - if (!found) - { - canBeCollapsed = false; - break; - } - } - - if (canBeCollapsed) - { - for (int32_t i : neighboorTriangles) - { - if (trWithEdge[0] == i) continue; - if (cntr == 2 && trWithEdge[1] == i) continue; - TriangleIndexed tr = mTesselatedMeshTriangles[i]; - PxVec3 oldNormal = (mVertices[tr.eb].p - mVertices[tr.ea].p).cross(mVertices[tr.ec].p - mVertices[tr.ea].p); - - if (tr.ea == from) - { - tr.ea = to; - } - else - if (tr.eb == from) - { - tr.eb = to; - } - else - if (tr.ec == from) - { - tr.ec = to; - } - PxVec3 newNormal = (mVertices[tr.eb].p - mVertices[tr.ea].p).cross(mVertices[tr.ec].p - mVertices[tr.ea].p); - if (newNormal.magnitude() < 1e-8f) - { - canBeCollapsed = false; - break; - } - if (oldNormal.dot(newNormal) < 0) - { - canBeCollapsed = false; - break; - } - } - } - - if (canBeCollapsed) - { - mTesselatedMeshTriangles[trWithEdge[0]].ea = NOT_VALID_VERTEX; - if (cntr == 2)mTesselatedMeshTriangles[trWithEdge[1]].ea = NOT_VALID_VERTEX; - - for (int32_t i : neighboorTriangles) - { - if (mTesselatedMeshTriangles[i].ea == NOT_VALID_VERTEX) - continue; - if (mTesselatedMeshTriangles[i].ea == from) - { - mTesselatedMeshTriangles[i].ea = to; - mVertexToTriangleMap[from].clear(); - mVertexToTriangleMap[to].push_back(i); - } - else - if (mTesselatedMeshTriangles[i].eb == from) - { - mTesselatedMeshTriangles[i].eb = to; - mVertexToTriangleMap[from].clear(); - mVertexToTriangleMap[to].push_back(i); - } - else - if (mTesselatedMeshTriangles[i].ec == from) - { - mTesselatedMeshTriangles[i].ec = to; - mVertexToTriangleMap[from].clear(); - mVertexToTriangleMap[to].push_back(i); - } - } - } -} - - -void ChunkPostProcessor::divideEdge(int32_t id) -{ - - if (mTrMeshEdToTr[id].c == 0 ) - { - return; - } - - Edge cEdge = mTrMeshEdges[id]; - EdgeFlag snapRestriction = mEdgeFlag[id]; - Vertex middle; - uint32_t nv = NOT_VALID_VERTEX; - for (int32_t t = 0; t < mTrMeshEdToTr[id].c; ++t) - { - int32_t oldTriangleIndex = mTrMeshEdToTr[id].tr[t]; - TriangleIndexed tr = mTesselatedMeshTriangles[mTrMeshEdToTr[id].tr[t]]; - - if (tr.ea == NOT_VALID_VERTEX) - { - continue; - } - - uint32_t pbf[3]; - pbf[0] = tr.ea; - pbf[1] = tr.eb; - pbf[2] = tr.ec; - for (int32_t p = 0; p < 3; ++p) - { - int32_t pnx = (p + 1) % 3; - int32_t opp = (p + 2) % 3; - - if ((pbf[p] == cEdge.s && pbf[pnx] == cEdge.e) || (pbf[p] == cEdge.e && pbf[pnx] == cEdge.s)) - { - if (nv == NOT_VALID_VERTEX) - { - middle.p = (mVertices[pbf[p]].p + mVertices[pbf[pnx]].p) * 0.5f; - middle.n = (mVertices[pbf[p]].n + mVertices[pbf[pnx]].n) * 0.5f; - middle.uv[0] = (mVertices[pbf[p]].uv[0] + mVertices[pbf[pnx]].uv[0]) * 0.5f; - - nv = (uint32_t)mVertices.size(); - mVertices.push_back(middle); - } - if (nv < mRestrictionFlag.size()) - { - mRestrictionFlag[nv] = ((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE)); - } - else - { - mRestrictionFlag.push_back((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE)); - } - - uint32_t ind1 = addEdgeTr(Edge(pbf[p], nv)); - uint32_t ind2 = addEdgeTr(Edge(nv, pbf[pnx])); - uint32_t ind3 = addEdgeTr(Edge(nv, pbf[opp])); - - - mEdgeFlag[ind1] = snapRestriction; - mEdgeFlag[ind2] = snapRestriction; - mEdgeFlag[ind3] = INTERNAL_EDGE; - - mTrMeshEdToTr[ind1].add(mTrMeshEdToTr[id].tr[t]); - int32_t userInfo = mTesselatedMeshTriangles[mTrMeshEdToTr[id].tr[t]].userInfo; - mTesselatedMeshTriangles[mTrMeshEdToTr[id].tr[t]] = TriangleIndexed(pbf[p], nv, pbf[opp]); - mTesselatedMeshTriangles[mTrMeshEdToTr[id].tr[t]].userInfo = userInfo; - mTrMeshEdToTr[ind2].add((int32_t)mTesselatedMeshTriangles.size()); - mTrMeshEdToTr[ind3].add((int32_t)mTrMeshEdToTr[id].tr[t]); - mTrMeshEdToTr[ind3].add((int32_t)mTesselatedMeshTriangles.size()); - mTesselatedMeshTriangles.push_back(TriangleIndexed(nv,pbf[pnx], pbf[opp])); - mTesselatedMeshTriangles.back().userInfo = userInfo; - int32_t ed1 = findEdge(Edge(pbf[pnx], pbf[opp])); - mTrMeshEdToTr[ed1].replace(oldTriangleIndex, (int32_t)mTesselatedMeshTriangles.size() - 1); - break; - } - } - } -} - + mBaseMeshResultTriangles.back().userData = mBaseMeshTriangles[i].userData; + mBaseMeshResultTriangles.back().materialId = mBaseMeshTriangles[i].materialId; + mBaseMeshResultTriangles.back().smoothingGroup = mBaseMeshTriangles[i].smoothingGroup; -NV_FORCE_INLINE void markEdge(int32_t ui, int32_t ed, std::vector<ChunkPostProcessor::EdgeFlag>& shortMarkup, std::vector<int32_t>& lastOwner) -{ - if (shortMarkup[ed] == ChunkPostProcessor::NONE) - { - if (ui == 0) - { - shortMarkup[ed] = ChunkPostProcessor::EXTERNAL_EDGE; - } - else - { - shortMarkup[ed] = ChunkPostProcessor::INTERNAL_EDGE; - } - lastOwner[ed] = ui; } - else - { - if (ui != 0) - { - if (shortMarkup[ed] == ChunkPostProcessor::EXTERNAL_EDGE) - { - shortMarkup[ed] = ChunkPostProcessor::EXTERNAL_BORDER_EDGE; - } - if ((shortMarkup[ed] == ChunkPostProcessor::INTERNAL_EDGE) && ui != lastOwner[ed]) - { - shortMarkup[ed] = ChunkPostProcessor::INTERNAL_BORDER_EDGE; - } - } - else - { - if (shortMarkup[ed] != ChunkPostProcessor::EXTERNAL_EDGE) - { - shortMarkup[ed] = ChunkPostProcessor::EXTERNAL_BORDER_EDGE; - } - } - } -} - -float falloffFunction(float x, float mx) -{ - float t = (x) / (mx + 1e-6f); - t = std::min(1.0f, t); - return t * t; -} - -void ChunkPostProcessor::recalcNoiseDirs() -{ - /** - Compute normals direction to apply noise - */ - mVerticesNormalsSmoothed.resize(mVertices.size(), PxVec3(0, 0, 0)); - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - if (mTesselatedMeshTriangles[i].ea == NOT_VALID_VERTEX) - { - continue; - } - TriangleIndexed& tr = mTesselatedMeshTriangles[i]; - if (tr.userInfo == 0) continue; - - if (tr.userInfo < 0) - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += mVertices[tr.ea].n.getNormalized(); - else - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] -= mVertices[tr.ea].n.getNormalized(); - - if (tr.userInfo < 0) - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += mVertices[tr.eb].n.getNormalized(); - else - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] -= mVertices[tr.eb].n.getNormalized(); - - if (tr.userInfo < 0) - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] += mVertices[tr.ec].n.getNormalized(); - else - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] -= mVertices[tr.ec].n.getNormalized(); - - } - for (uint32_t i = 0; i < mVerticesNormalsSmoothed.size(); ++i) - { - - mVerticesNormalsSmoothed[i] = mVerticesNormalsSmoothed[mPositionMappedVrt[i]]; - mVerticesNormalsSmoothed[i].normalize(); - } -} - - - -void ChunkPostProcessor::applyNoise(SimplexNoise& noise, float falloff, int32_t relaxIterations, float relaxFactor) -{ - NVBLAST_ASSERT(isTesselated); - if (isTesselated == false) - { - return; - } - mRestrictionFlag.clear(); - mRestrictionFlag.resize(mVertices.size(), false); - - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - if (mTrMeshEdToTr[i].c != 0) - { - if (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == EXTERNAL_BORDER_EDGE) - { - mRestrictionFlag[mTrMeshEdges[i].e] = true; - mRestrictionFlag[mTrMeshEdges[i].s] = true; - } - } - } - std::vector<Vertex> localVertices = mVertices; - - recalcNoiseDirs(); - - relax(relaxIterations, relaxFactor, localVertices); - - - /** - Apply noise - */ - for (uint32_t i = 0; i < localVertices.size(); ++i) - { - - if (!mRestrictionFlag[i]) - { - - float d = noise.sample(localVertices[i].p); - localVertices[i].p += (falloffFunction(mVerticesDistances[i], falloff)) * mVerticesNormalsSmoothed[i] * d; - } - } - - - /* Recalculate smoothed normals*/ - mVerticesNormalsSmoothed.assign(mVerticesNormalsSmoothed.size(), PxVec3(0, 0, 0)); - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - if (mTesselatedMeshTriangles[i].ea == NOT_VALID_VERTEX) - { - continue; - } - TriangleIndexed& tr = mTesselatedMeshTriangles[i]; - if (tr.userInfo == 0) continue; - - Triangle pTr(localVertices[tr.ea], localVertices[tr.eb], localVertices[tr.ec]); - PxVec3 nrm = pTr.getNormal().getNormalized(); - - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += nrm; - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += nrm; - mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] += nrm; - } - for (uint32_t i = 0; i < mVerticesNormalsSmoothed.size(); ++i) - { - mVerticesNormalsSmoothed[i] = mVerticesNormalsSmoothed[mPositionMappedVrt[i]]; - mVerticesNormalsSmoothed[i].normalize(); - } - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - if (mTesselatedMeshTriangles[i].ea == NOT_VALID_VERTEX) - { - continue; - } - TriangleIndexed& tr = mTesselatedMeshTriangles[i]; - if (tr.userInfo == 0) continue; - - localVertices[tr.ea].n = mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]]; - localVertices[tr.eb].n = mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]]; - localVertices[tr.ec].n = mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]]; - } - - mTesselatedMeshResultTriangles.clear(); - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - if (mTesselatedMeshTriangles[i].ea == NOT_VALID_VERTEX) - { - continue; - } - mTesselatedMeshResultTriangles.push_back(Triangle(localVertices[mTesselatedMeshTriangles[i].ea], localVertices[mTesselatedMeshTriangles[i].eb], localVertices[mTesselatedMeshTriangles[i].ec])); - mTesselatedMeshResultTriangles.back().userInfo = mTesselatedMeshTriangles[i].userInfo; - } - - -} - - -void ChunkPostProcessor::computePositionedMapping() -{ - std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap; - mPositionMappedVrt.clear(); - mPositionMappedVrt.resize(mVertices.size()); - - for (uint32_t i = 0; i < mVertices.size(); ++i) - { - auto it = mPosMap.find(mVertices[i].p); - - if (it == mPosMap.end()) - { - mPosMap[mVertices[i].p] = i; - mPositionMappedVrt[i] = i; - } - else - { - mPositionMappedVrt[i] = it->second; - } - } -} - -void ChunkPostProcessor::computeFalloffAndNormals() -{ - // Map newly created vertices according to positions - computePositionedMapping(); - - mGeometryGraph.resize(mVertices.size()); - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - if (mTrMeshEdToTr[i].c == 0) - { - continue; - } - int32_t v1 = mPositionMappedVrt[mTrMeshEdges[i].s]; - int32_t v2 = mPositionMappedVrt[mTrMeshEdges[i].e]; - - if (std::find(mGeometryGraph[v1].begin(), mGeometryGraph[v1].end(), v2) == mGeometryGraph[v1].end()) - mGeometryGraph[v1].push_back(v2); - if (std::find(mGeometryGraph[v2].begin(), mGeometryGraph[v2].end(), v1) == mGeometryGraph[v2].end()) - mGeometryGraph[v2].push_back(v1); - } - mVerticesDistances.clear(); - mVerticesDistances.resize(mVertices.size(), 10000.0f); - - std::queue<int32_t> que; - - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - if (mTrMeshEdToTr[i].c != 0 && (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == EXTERNAL_BORDER_EDGE)) - { - int32_t v1 = mPositionMappedVrt[mTrMeshEdges[i].s]; - int32_t v2 = mPositionMappedVrt[mTrMeshEdges[i].e]; - mVerticesDistances[v1] = 0.0f; - mVerticesDistances[v2] = 0.0f; - que.push(v1); - que.push(v2); - } - } - while (!que.empty()) - { - int32_t curr = que.front(); - que.pop(); - - for (uint32_t i = 0; i < mGeometryGraph[curr].size(); ++i) - { - int32_t to = mGeometryGraph[curr][i]; - float d = mVerticesDistances[curr] + 0.1f;// (mVertices[to].p - mVertices[curr].p).magnitudeSquared(); - if (d < mVerticesDistances[to]) - { - mVerticesDistances[to] = d; - que.push(to); - } - } - } - - for (uint32_t i = 0; i < mVerticesDistances.size(); ++i) - { - int32_t from = mPositionMappedVrt[i]; - mVerticesDistances[i] = mVerticesDistances[from]; - } -} - -bool edgeOverlapTest(PxVec3& as, PxVec3& ae, PxVec3& bs, PxVec3& be) -{ - //return false; - if (std::max(std::min(as.x, ae.x), std::min(bs.x, be.x)) > std::min(std::max(as.x, ae.x), std::max(bs.x, be.x))) return false; - if (std::max(std::min(as.y, ae.y), std::min(bs.y, be.y)) > std::min(std::max(as.y, ae.y), std::max(bs.y, be.y))) return false; - if (std::max(std::min(as.z, ae.z), std::min(bs.z, be.z)) > std::min(std::max(as.z, ae.z), std::max(bs.z, be.z))) return false; - - return ((bs - as).cross(ae - as)).magnitudeSquared() < 1e-12f && ((be - as).cross(ae - as)).magnitudeSquared() < 1e-12f; } -void ChunkPostProcessor::relax(int32_t iteration, float factor, std::vector<Vertex>& vertices) +void Triangulator::computePositionedMapping() { - std::vector<PxVec3> verticesTemp(vertices.size()); - std::vector<PxVec3> normalsTemp(vertices.size()); - for (int32_t iter = 0; iter < iteration; ++iter) - { - for (uint32_t i = 0; i < vertices.size(); ++i) - { - if (mRestrictionFlag[i]) - { - continue; - } - PxVec3 cps = vertices[i].p; - PxVec3 cns = mVerticesNormalsSmoothed[i]; - PxVec3 averaged(0, 0, 0); - PxVec3 averagedNormal(0, 0, 0); - - for (uint32_t p = 0; p < mGeometryGraph[mPositionMappedVrt[i]].size(); ++p) - { - int32_t to = mGeometryGraph[mPositionMappedVrt[i]][p]; - averaged += vertices[to].p; - averagedNormal += mVerticesNormalsSmoothed[to]; - - } - averaged *= (1.0f / mGeometryGraph[mPositionMappedVrt[i]].size()); - averagedNormal *= (1.0f / mGeometryGraph[mPositionMappedVrt[i]].size()); - verticesTemp[i] = cps + (averaged - cps) * factor; - normalsTemp[i] = cns * (1.0f - factor) + averagedNormal * factor; - } - for (uint32_t i = 0; i < vertices.size(); ++i) - { - if (mRestrictionFlag[i]) - { - continue; - } - vertices[i].p = verticesTemp[i]; - mVerticesNormalsSmoothed[i] = normalsTemp[i].getNormalized(); - - } - } - -} - -void ChunkPostProcessor::prebuildEdgeFlagArray() -{ - mRestrictionFlag.clear(); - mRestrictionFlag.resize(mVertices.size()); - mEdgeFlag.clear(); - mEdgeFlag.resize(mTrMeshEdges.size(), NONE); - std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap; mPositionMappedVrt.clear(); - mPositionMappedVrt.resize(mVertices.size(), 0); + mPositionMappedVrt.resize(mVertices.size()); for (uint32_t i = 0; i < mVertices.size(); ++i) { @@ -1280,159 +583,6 @@ void ChunkPostProcessor::prebuildEdgeFlagArray() mPositionMappedVrt[i] = it->second; } } - - std::map<Edge, int32_t> mPositionEdgeMap; - std::vector<int32_t> mPositionBasedEdges(mTrMeshEdges.size()); - - - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - Edge tmp = Edge(mPositionMappedVrt[mTrMeshEdges[i].s], mPositionMappedVrt[mTrMeshEdges[i].e]); - if (tmp.e < tmp.s) std::swap(tmp.e, tmp.s); - auto it = mPositionEdgeMap.find(tmp); - if (it == mPositionEdgeMap.end()) - { - mPositionEdgeMap[tmp] = i; - mPositionBasedEdges[i] = i; - } - else - { - mPositionBasedEdges[i] = it->second; - } - } - - std::vector<EdgeFlag> shortMarkup(mTrMeshEdges.size(), NONE); - std::vector<int32_t> lastOwner(mTrMeshEdges.size(), 0); - - std::vector<std::vector<int32_t> > edgeOverlap(mTrMeshEdges.size()); - for (auto it1 = mPositionEdgeMap.begin(); it1 != mPositionEdgeMap.end(); ++it1) - { - auto it2 = it1; - it2++; - for (; it2 != mPositionEdgeMap.end(); ++it2) - { - Edge& ed1 = mTrMeshEdges[it1->second]; - Edge& ed2 = mTrMeshEdges[it2->second]; - - if (edgeOverlapTest(mVertices[ed1.s].p, mVertices[ed1.e].p, mVertices[ed2.s].p, mVertices[ed2.e].p)) - { - edgeOverlap[it1->second].push_back(it2->second); - } - } - } - - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - int32_t ui = mTesselatedMeshTriangles[i].userInfo; - int32_t ed = mPositionBasedEdges[findEdge(Edge(mTesselatedMeshTriangles[i].ea, mTesselatedMeshTriangles[i].eb))]; - - - markEdge(ui, ed, shortMarkup, lastOwner); - for (uint32_t ov = 0; ov < edgeOverlap[ed].size(); ++ov) - { - markEdge(ui, edgeOverlap[ed][ov], shortMarkup, lastOwner); - } - - ed = mPositionBasedEdges[findEdge(Edge(mTesselatedMeshTriangles[i].ea, mTesselatedMeshTriangles[i].ec))]; - markEdge(ui, ed, shortMarkup, lastOwner); - for (uint32_t ov = 0; ov < edgeOverlap[ed].size(); ++ov) - { - markEdge(ui, edgeOverlap[ed][ov], shortMarkup, lastOwner); - } - - ed = mPositionBasedEdges[findEdge(Edge(mTesselatedMeshTriangles[i].eb, mTesselatedMeshTriangles[i].ec))]; - markEdge(ui, ed, shortMarkup, lastOwner); - for (uint32_t ov = 0; ov < edgeOverlap[ed].size(); ++ov) - { - markEdge(ui, edgeOverlap[ed][ov], shortMarkup, lastOwner); - } - - } - - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - mEdgeFlag[i] = shortMarkup[mPositionBasedEdges[i]]; - } - - for (uint32_t i = 0; i < mTesselatedMeshTriangles.size(); ++i) - { - if (mTesselatedMeshTriangles[i].userInfo != 0) continue; - - int32_t ed = findEdge(Edge(mTesselatedMeshTriangles[i].ea, mTesselatedMeshTriangles[i].eb)); - mEdgeFlag[ed] = EXTERNAL_EDGE; - ed = findEdge(Edge(mTesselatedMeshTriangles[i].ec, mTesselatedMeshTriangles[i].eb)); - mEdgeFlag[ed] = EXTERNAL_EDGE; - ed = findEdge(Edge(mTesselatedMeshTriangles[i].ea, mTesselatedMeshTriangles[i].ec)); - mEdgeFlag[ed] = EXTERNAL_EDGE; - } -} - - - -void ChunkPostProcessor::tesselateInternalSurface(float maxLenIn) -{ - mTesselatedMeshTriangles = mBaseMeshTriangles; - if (mTesselatedMeshTriangles.empty()) - { - return; - } - - updateEdgeTriangleInfo(); - prebuildEdgeFlagArray(); - mRestrictionFlag.resize(mVertices.size(), 0); - for (uint32_t i = 0; i < mTrMeshEdges.size(); ++i) - { - if (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == EXTERNAL_BORDER_EDGE || mEdgeFlag[i] == INTERNAL_BORDER_EDGE) - { - mRestrictionFlag[mTrMeshEdges[i].s] = 1; - mRestrictionFlag[mTrMeshEdges[i].e] = 1; - } - } - - - float maxLen = std::max(0.1f, maxLenIn); - while (maxLen > maxLenIn) - { - float mlSq = maxLen * maxLen; - float minD = maxLen * 0.5f; - minD = minD * minD; - - for (int32_t iter = 0; iter < 15; ++iter) - { - updateVertEdgeInfo(); - uint32_t oldSize = (uint32_t)mTrMeshEdges.size(); - for (uint32_t i = 0; i < oldSize; ++i) - { - if (mEdgeFlag[i] == EXTERNAL_EDGE || mEdgeFlag[i] == INTERNAL_BORDER_EDGE) - { - continue; - } - if ((mVertices[mTrMeshEdges[i].s].p - mVertices[mTrMeshEdges[i].e].p).magnitudeSquared() < minD) - { - collapseEdge(i); - } - } - - oldSize = (uint32_t)mTrMeshEdges.size(); - updateEdgeTriangleInfo(); - for (uint32_t i = 0; i < oldSize; ++i) - { - if (mEdgeFlag[i] == EXTERNAL_EDGE) - { - continue; - } - if ((mVertices[mTrMeshEdges[i].s].p - mVertices[mTrMeshEdges[i].e].p).magnitudeSquared() > mlSq) - { - divideEdge(i); - } - } - } - maxLen *= 0.3; - maxLen = std::max(maxLen, maxLenIn); - } - computeFalloffAndNormals(); - prebuildTesselatedTriangles(); - isTesselated = true; } } // namespace Blast diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.h index 83942f4..c5cb5b1 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.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 NVBLASTEXTAUTHORINGTRIANGULATOR_H #define NVBLASTEXTAUTHORINGTRIANGULATOR_H @@ -22,95 +40,19 @@ namespace Nv { namespace Blast { -class SimplexNoise; - -/** - Vertex comparator for vertex welding. -*/ -struct VrtComp -{ - bool operator()(const Vertex& a, const Vertex& b) const; -}; - -/** - Vertex comparator for vertex welding (not accounts normal and uv parameters of vertice). -*/ -struct VrtPositionComparator -{ - bool operator()(const physx::PxVec3& a, const physx::PxVec3& b) const; -}; - -/** - Structure used on tesselation stage. Maps edge to two neighboor triangles -*/ -struct EdgeToTriangles -{ - int32_t tr[2]; - int32_t c; - EdgeToTriangles() - { - c = 0; - } - /** - Add triangle to edge. Should not be called more than twice for one edge!!!!. - */ - void add(int32_t t) - { - tr[c] = t; - ++c; - } - /** - Replaces mapping from one triangle to another. - */ - void replace(int32_t from, int32_t to) - { - if (tr[0] == from) - { - tr[0] = to; - } - else - { - if (c == 2 && tr[1] == from) - { - tr[1] = to; - } - } - } - /** - Get triangle which is mapped by this edge and which index is different than provided. - */ - int32_t getNot(int32_t id) - { - if (tr[0] != id) - { - return tr[0]; - } - if (c == 2 && tr[1] != id) - { - return tr[1]; - } - return -1; - } - -}; /** Tool for doing all post processing steps of authoring. */ -class ChunkPostProcessor +class Triangulator { public: /** - Edge flags - */ - enum EdgeFlag{ INTERNAL_EDGE, EXTERNAL_BORDER_EDGE, INTERNAL_BORDER_EDGE, EXTERNAL_EDGE, NONE }; - - /** Triangulates provided mesh and saves result internally. Uses Ear-clipping algorithm. \param[in] mesh Mesh for triangulation */ - void triangulate(Mesh* mesh); + void triangulate(const Mesh* mesh); /** \return Return array of triangles of base mesh. @@ -127,8 +69,6 @@ public: { return mBaseMeshTriangles; } - - /** \return Return mapping from vertices of input Mesh to internal vertices buffer. Used for island detection. */ @@ -143,7 +83,6 @@ public: { return mPositionMappedVrt; }; - /** \return Return internal vertex buffer size. Vertices internally are welded with some threshold. */ @@ -151,44 +90,15 @@ public: { return static_cast<uint32_t>(mVertices.size()); } - /** - Tesselate internal surface. - \param[in] maxLen - maximal length of edge on internal surface. - */ - void tesselateInternalSurface(float maxLen); - - /** - Apply noise to internal surface. Must be called only after tesselation!!! - \param[in] noise - noise generator - \param[in] falloff - damping of noise around of external surface - \param[in] relaxIterations - number of smoothing iterations before applying noise - \param[in] relaxFactor - amount of smooting before applying noise. - */ - void applyNoise(SimplexNoise& noise, float falloff, int32_t relaxIterations, float relaxFactor); - - /** - \return Return array of noised mesh triangles. - */ - std::vector<Triangle>& getNoisyMesh() - { - return mTesselatedMeshResultTriangles; - }; /** - Removes all information about mesh triangulation, tesselation, etc. + Removes all information about mesh triangulation. */ void reset(); private: - - - void collapseEdge(int32_t id); - void divideEdge(int32_t id); - void updateVertEdgeInfo(); - void updateEdgeTriangleInfo(); - - int32_t addVerticeIfNotExist(Vertex& p); + int32_t addVerticeIfNotExist(const Vertex& p); void addEdgeIfValid(EdgeWithParent& ed); /* Data used before triangulation to build polygon loops*/ @@ -198,60 +108,26 @@ private: std::map<Vertex, int32_t, VrtComp> mVertMap; std::map<EdgeWithParent, int32_t, EdgeComparator> mEdgeMap; std::vector<uint32_t> mBaseMapping; - + std::vector<int32_t> mPositionMappedVrt; + /* ------------------------------------------------------------ */ /** Unite all almost similar vertices, update edges according to this changes */ - void prepare(Mesh* mesh); - - /* ------------------------------------------------------------ */ - - /* Triangulation and tesselation stage data */ - bool isTesselated; - - std::map<Edge, int32_t> mTrMeshEdgeMap; - std::vector<Edge> mTrMeshEdges; - std::vector<EdgeToTriangles> mTrMeshEdToTr; - std::vector<int32_t> mVertexValence; - std::vector<std::vector<int32_t> > mVertexToTriangleMap; - - std::vector<bool> mRestrictionFlag; - std::vector<EdgeFlag> mEdgeFlag; - - std::vector<float> mVerticesDistances; - std::vector<physx::PxVec3> mVerticesNormalsSmoothed; - std::vector<int32_t> mPositionMappedVrt; - std::vector<std::vector<int32_t> > mGeometryGraph; - - - int32_t addEdgeTr(const Edge& ed); - int32_t findEdge(const Edge& e); - - void prebuildEdgeFlagArray(); - void computePositionedMapping(); - - void computeFalloffAndNormals(); - + void prepare(const Mesh* mesh); + void triangulatePolygonWithEarClipping(std::vector<uint32_t>& inputPolygon, Vertex* vert, ProjectionDirections dir); - void buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* vertices, int32_t userData); + void buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* vertices, int32_t userData, int32_t materialId, int32_t smoothingGroup); + void computePositionedMapping(); - void relax(int32_t iterations, float factor, std::vector<Vertex>& vertices); - void recalcNoiseDirs(); - - std::vector<TriangleIndexed> mBaseMeshTriangles; - std::vector<TriangleIndexed> mTesselatedMeshTriangles; - + std::vector<TriangleIndexed> mBaseMeshTriangles; /** Final triangles */ - void prebuildTesselatedTriangles(); - std::vector<Triangle> mBaseMeshResultTriangles; - std::vector<Triangle> mTesselatedMeshResultTriangles; }; } // namespace Blast diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringVSA.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringVSA.h index fd0c9c9..62d73c1 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringVSA.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringVSA.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 NVBLASTEXTAUTHORINGVSA_H #define NVBLASTEXTAUTHORINGVSA_H diff --git a/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.cpp b/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.cpp index 3c3e540..0ec4c20 100644 --- a/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.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 "NvBlastExtTriangleProcessor.h" #include "NvBlastExtAuthoringInternalCommon.h" diff --git a/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h b/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h index db9f682..0b32218 100644 --- a/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h +++ b/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.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 NVBLASTEXTTRIANGLEPROCESSOR_H #define NVBLASTEXTTRIANGLEPROCESSOR_H diff --git a/sdk/extensions/common/source/NvBlastExtAllocator.h b/sdk/extensions/common/source/NvBlastExtAllocator.h deleted file mode 100644 index d917cbf..0000000 --- a/sdk/extensions/common/source/NvBlastExtAllocator.h +++ /dev/null @@ -1,127 +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 NVBLASTEXTALLOCATOR_H -#define NVBLASTEXTALLOCATOR_H - -#include "NvBlastTkFramework.h" -#include "PxAllocatorCallback.h" - - -namespace Nv -{ -namespace Blast -{ - -/** -ExtAllocator uses TkFramework allocator -*/ -class ExtAllocator -{ -public: - ExtAllocator(const char* = 0) - { - } - - void* allocate(size_t size, const char* filename, int line) - { - return NvBlastTkFrameworkGet()->getAllocatorCallback().allocate(size, nullptr, filename, line); - } - - void deallocate(void* ptr) - { - NvBlastTkFrameworkGet()->getAllocatorCallback().deallocate(ptr); - } - - - /** - Aligned allocation. - - Example using 16-byte alignment: - - // b will lie on a 16-byte boundary and point to 50 bytes of usable memory - void* b = alignedAlloc<16>(50); - */ - template<int A> - static void* alignedAlloc(size_t size, const char* filename, int line) - { - NV_COMPILE_TIME_ASSERT(A > 0 && A <= 256); - unsigned char* mem = (unsigned char*)ExtAllocator().allocate(size + A, filename, line); - const unsigned char offset = (unsigned char)((uintptr_t)A - (uintptr_t)mem % A - 1); - mem += offset; - *mem++ = offset; - return mem; - } - - template<int A> - static void* alignedAlloc(size_t size) - { - return alignedAlloc<A>(size, __FILE__, __LINE__); - } - - - /** - Version of alignedAlloc specialized 16-byte aligned allocation. - */ - static void* alignedAlloc16(size_t size) - { - return alignedAlloc<16>(size); - } - - - /** - Aligned deallocation. - - Memory freed using this function MUST have been allocated using alignedAlloc. - - Example using free: - - // Using the memory pointer b from the example above (for alignedAlloc) - alignedFree(b); - */ - static void alignedFree(void* block) - { - if (block != nullptr) - { - unsigned char* mem = (unsigned char*)block; - const unsigned char offset = *--mem; - ExtAllocator().deallocate(mem - offset); - } - }; -}; - - -/** -ExtAlignedAllocator uses ExtAllocator -*/ -template<int A> -class ExtAlignedAllocator -{ -public: - ExtAlignedAllocator(const char* = 0) - { - } - - void* allocate(size_t size, const char* filename, int line) - { - return ExtAllocator::alignedAlloc<A>(size, filename, line); - } - - void deallocate(void* ptr) - { - return ExtAllocator::alignedFree(ptr); - } -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTEXTALLOCATOR_H diff --git a/sdk/extensions/common/source/NvBlastExtArray.h b/sdk/extensions/common/source/NvBlastExtArray.h deleted file mode 100644 index 9ea4777..0000000 --- a/sdk/extensions/common/source/NvBlastExtArray.h +++ /dev/null @@ -1,41 +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 NVBLASTEXTARRAY_H -#define NVBLASTEXTARRAY_H - - -#include "NvBlastExtAllocator.h" -#include "PsInlineArray.h" - - -namespace Nv -{ -namespace Blast -{ - -template <class T> -struct ExtArray -{ - typedef physx::shdfnd::Array<T, ExtAllocator> type; -}; - - -template <class T, uint32_t N> -struct ExtInlineArray -{ - typedef physx::shdfnd::InlineArray<T, N, ExtAllocator> type; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTEXTARRAY_H diff --git a/sdk/extensions/common/source/NvBlastExtDefs.h b/sdk/extensions/common/source/NvBlastExtDefs.h deleted file mode 100644 index 72b6c1d..0000000 --- a/sdk/extensions/common/source/NvBlastExtDefs.h +++ /dev/null @@ -1,64 +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 NVBLASTEXTDEFS_H -#define NVBLASTEXTDEFS_H - -#include "NvBlastTkFramework.h" -#include "PxAllocatorCallback.h" -#include <new> - - -//////// Log macros that use the ExtContext log function //////// - -#define NVBLASTEXT_LOG_ERROR(_msg) NVBLAST_LOG_ERROR(NvBlastTkFrameworkGet()->getLogFn(), _msg) -#define NVBLASTEXT_LOG_WARNING(_msg) NVBLAST_LOG_WARNING(NvBlastTkFrameworkGet()->getLogFn(), _msg) -#define NVBLASTEXT_LOG_INFO(_msg) NVBLAST_LOG_INFO(NvBlastTkFrameworkGet()->getLogFn(), _msg) -#define NVBLASTEXT_LOG_DEBUG(_msg) NVBLAST_LOG_DEBUG(NvBlastTkFrameworkGet()->getLogFn(), _msg) - -#define NVBLASTEXT_CHECK(_expr, _messageType, _msg, _onFail) \ - { \ - if(!(_expr)) \ - { \ - (*NvBlastTkFrameworkGet()->getLogFn())(_messageType, _msg, __FILE__, __LINE__); \ - { _onFail; }; \ - } \ - } - -#define NVBLASTEXT_CHECK_ERROR(_expr, _msg, _onFail) NVBLASTEXT_CHECK(_expr, NvBlastMessage::Error, _msg, _onFail) -#define NVBLASTEXT_CHECK_WARNING(_expr, _msg, _onFail) NVBLASTEXT_CHECK(_expr, NvBlastMessage::Warning, _msg, _onFail) -#define NVBLASTEXT_CHECK_INFO(_expr, _msg, _onFail) NVBLASTEXT_CHECK(_expr, NvBlastMessage::Info, _msg, _onFail) -#define NVBLASTEXT_CHECK_DEBUG(_expr, _msg, _onFail) NVBLASTEXT_CHECK(_expr, NvBlastMessage::Debug, _msg, _onFail) - - -//////// Allocator macros //////// - -/** -Placement new with ExtContext allocation. -Example: Foo* foo = NVBLASTEXT_NEW(Foo, context) (params); -*/ -#define NVBLASTEXT_NEW(T) new (NvBlastTkFrameworkGet()->getAllocatorCallback().allocate(sizeof(T), #T, __FILE__, __LINE__)) T - -/** -Respective delete to NVBLASTEXT_NEW -Example: NVBLASTEXT_DELETE(foo, Foo, context); -*/ -#define NVBLASTEXT_DELETE(obj, T) \ - (obj)->~T(); \ - NvBlastTkFrameworkGet()->getAllocatorCallback().deallocate(obj) - - -//////// Util macros //////// - -// Macro to load a uint32_t (or larger) with four characters -#define NVBLASTEXT_FOURCC(_a, _b, _c, _d) ( (uint32_t)(_a) | (uint32_t)(_b)<<8 | (uint32_t)(_c)<<16 | (uint32_t)(_d)<<24 ) - - -#endif // #ifndef NVBLASTEXTDEFS_H diff --git a/sdk/extensions/common/source/NvBlastExtHashMap.h b/sdk/extensions/common/source/NvBlastExtHashMap.h deleted file mode 100644 index 0fa094e..0000000 --- a/sdk/extensions/common/source/NvBlastExtHashMap.h +++ /dev/null @@ -1,34 +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 NVBLASTEXTHASHMAP_H -#define NVBLASTEXTHASHMAP_H - - -#include "NvBlastExtAllocator.h" -#include "PsHashMap.h" - - -namespace Nv -{ -namespace Blast -{ - -template <class Key, class Value, class HashFn = physx::shdfnd::Hash<Key>> -struct ExtHashMap -{ - typedef physx::shdfnd::HashMap<Key, Value, HashFn, ExtAllocator> type; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTEXTHASHMAP_H diff --git a/sdk/extensions/common/source/NvBlastExtHashSet.h b/sdk/extensions/common/source/NvBlastExtHashSet.h deleted file mode 100644 index 97fc0a9..0000000 --- a/sdk/extensions/common/source/NvBlastExtHashSet.h +++ /dev/null @@ -1,33 +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 NVBLASTEXTHASHSET_H -#define NVBLASTEXTHASHSET_H - - -#include "NvBlastExtAllocator.h" -#include "PsHashSet.h" - -namespace Nv -{ -namespace Blast -{ - -template <class Key, class HashFn = physx::shdfnd::Hash<Key>> -struct ExtHashSet -{ - typedef physx::shdfnd::HashSet<Key, HashFn, ExtAllocator> type; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTEXTHASHSET_H diff --git a/sdk/extensions/converter/include/NvBlastExtDataConverter.h b/sdk/extensions/converter/include/NvBlastExtDataConverter.h deleted file mode 100644 index b251518..0000000 --- a/sdk/extensions/converter/include/NvBlastExtDataConverter.h +++ /dev/null @@ -1,40 +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 NVBLASTEXTDATACONVERTER_H -#define NVBLASTEXTDATACONVERTER_H - - -#include "NvBlast.h" -#include <vector> - -namespace Nv -{ -namespace Blast -{ - /** - Generic version conversion function for Blast data blocks. - - Automatically determines block type (one of NvBlastDataBlock::Type) and uses appropriate converter. - - \param[out] outBlock User-supplied memory block to fill with new data. - \param[in] inBlock Data block to convert. - \param[in] outBlockVersion Version to convert too, pass 'nullptr' to convert to the latest version. - - \return true iff conversion was successful. - */ - NVBLAST_API bool convertDataBlock(std::vector<char>& outBlock, const std::vector<char>& inBlock, uint32_t* outBlockVersion = nullptr); - - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTDATACONVERTER_H diff --git a/sdk/extensions/converter/source/conversion/NvBlastExtAssetBlockVersionConverter_v0_v1.h b/sdk/extensions/converter/source/conversion/NvBlastExtAssetBlockVersionConverter_v0_v1.h deleted file mode 100644 index 44a0b54..0000000 --- a/sdk/extensions/converter/source/conversion/NvBlastExtAssetBlockVersionConverter_v0_v1.h +++ /dev/null @@ -1,88 +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 NVBLASTEXTASSETBLOCKVERSIONCONVERTER_V0_V1_H -#define NVBLASTEXTASSETBLOCKVERSIONCONVERTER_V0_V1_H - - -#include "NvBlastExtBinaryBlockConverter.h" - - -namespace Nv -{ -namespace Blast -{ - -/* - WARNING: THIS CLASS IS AN EXAMPLE. - REPLACE WITH ACTUAL CONVERSION CODE ONCE NEEDED. -*/ -class NvBlastAssetBlockVersionConverter_v0_v1 : public BinaryBlockConverter::VersionConverter -{ -public: - virtual uint32_t getVersionFrom() const { return NvBlastAssetDataFormat::Initial; } - - virtual uint32_t getVersionTo() const { return 1/*NvBlastAssetDataFormat::BondCountSwap*/; } - - // remains the same - struct SupportGraph - { - uint32_t m_nodeCount; - uint32_t m_chunkIndicesOffset; - uint32_t m_adjacencyPartitionOffset; - uint32_t m_adjacentNodeIndicesOffset; - uint32_t m_adjacentBondIndicesOffset; - }; - - // prev version - struct AssetDataHeaderPrev - { - uint32_t m_formatVersion; - uint32_t m_size; - NvBlastID m_ID; - uint32_t m_totalChunkCount; - SupportGraph m_graph; - uint32_t m_leafChunkCount; - uint32_t m_firstSubsupportChunkIndex; // 0 - uint32_t m_bondCount; // 1 - }; - - // new version - struct AssetDataHeaderNew - { - uint32_t m_formatVersion; - uint32_t m_size; - NvBlastID m_ID; - uint32_t m_totalChunkCount; - SupportGraph m_graph; - uint32_t m_leafChunkCount; - uint32_t m_bondCount; // 1 - uint32_t m_firstSubsupportChunkIndex; // 0 - }; - - bool convert(const std::vector<char>& from, std::vector<char>& to) const - { - to = from; - - const AssetDataHeaderPrev* headerPrev = reinterpret_cast<const AssetDataHeaderPrev*>(from.data()); - AssetDataHeaderNew* headerNew = reinterpret_cast<AssetDataHeaderNew*>(to.data()); - headerNew->m_bondCount = headerPrev->m_bondCount; - headerNew->m_firstSubsupportChunkIndex = headerPrev->m_firstSubsupportChunkIndex; - headerNew->m_formatVersion = (uint32_t)getVersionTo(); - - return true; - } -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTASSETBLOCKVERSIONCONVERTER_V0_V1_H diff --git a/sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.cpp b/sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.cpp deleted file mode 100644 index a606b70..0000000 --- a/sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.cpp +++ /dev/null @@ -1,152 +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 "NvBlastExtBinaryBlockConverter.h" -#include <iostream> -#include <algorithm> -#include <queue> -#include <limits> - - -namespace Nv -{ -namespace Blast -{ - -bool BinaryBlockConverter::convertBinaryBlock(std::vector<char>& outBlock, const std::vector<VersionConverterPtr>& converters, const std::vector<char>& inBlock, uint32_t outBlockVersion, uint32_t inBlockVersion) -{ - if (inBlock.empty()) - { - std::cerr << "Conversion failed: empty input block." << std::endl; - return false; - } - - // starting version - uint32_t version; - version = inBlockVersion; - std::cout << "Input block version: " << version << std::endl; - - // target version - const uint32_t targetVersion = outBlockVersion; - std::cout << "Target version: " << targetVersion << std::endl; - - // search conversion path - std::vector<VersionConverterPtr> conversionPath; - if (!findShortestPath(conversionPath, converters, version, targetVersion)) - { - std::cerr << "Conversion failed: can't find conversion path." << std::endl; - return false; - } - - // starting convertion loop - std::vector<char> blockFrom(inBlock.begin(), inBlock.end()); - std::vector<char> blockTo(inBlock.size()); - for (const VersionConverterPtr converter : conversionPath) - { - // actual conversion call - std::cout << "Converting from version: " << converter->getVersionFrom() << " -> " << converter->getVersionTo() << " Result: "; - if (!converter->convert(blockFrom, blockTo)) - { - std::cout << "Fail." << std::endl; - std::cerr << "Conversion failed: inside converter for version: " << version << std::endl; - return false; - } - else - { - std::cout << "Success." << std::endl; - blockFrom.swap(blockTo); - version = converter->getVersionTo(); - } - } - - // copy result - outBlock = blockFrom; - - return true; -} - - -/** -Finds shortest path form versionFrom to verstionTo using breadth-first search with DP -*/ -bool BinaryBlockConverter::findShortestPath(std::vector<VersionConverterPtr>& conversionPath, const std::vector<VersionConverterPtr>& converters, uint32_t versionFrom, uint32_t versionTo) -{ - // find max version - uint32_t versionMax = 0; - for (VersionConverterPtr c : converters) - { - versionMax = std::max(versionMax, c->getVersionFrom()); - versionMax = std::max(versionMax, c->getVersionTo()); - } - - // dynamic programming data - struct Node - { - uint32_t distance; - VersionConverterPtr converter; - - Node() : distance(std::numeric_limits<uint32_t>::max()), converter(nullptr) {} - }; - std::vector<Node> nodes(versionMax + 1); - - // initial state (start from versionTo) - std::queue<uint32_t> q; - q.emplace(versionTo); - nodes[versionTo].distance = 0; - nodes[versionTo].converter = nullptr; - - // breadth-first search - bool found = false; - while (!q.empty() && !found) - { - uint32_t v0 = q.front(); - q.pop(); - - for (const VersionConverterPtr c : converters) - { - if (c->getVersionTo() == v0) - { - uint32_t v1 = c->getVersionFrom(); - if (nodes[v1].distance > nodes[v0].distance + 1) - { - nodes[v1].distance = nodes[v0].distance + 1; - nodes[v1].converter = c; - q.emplace(v1); - } - - if (c->getVersionFrom() == versionFrom) - { - found = true; - break; - } - } - } - } - - if (found) - { - // unfold found path to result conversionPath - uint32_t v = versionFrom; - conversionPath.clear(); - while (nodes[v].converter.get() != nullptr) - { - conversionPath.push_back(nodes[v].converter); - v = nodes[v].converter->getVersionTo(); - } - return true; - } - else - { - return false; - } -} - -} // namespace Blast -} // namespace Nv diff --git a/sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.h b/sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.h deleted file mode 100644 index 83eb6b3..0000000 --- a/sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.h +++ /dev/null @@ -1,57 +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 NVBLASTEXTBINARYBLOCKCONVERTER_H -#define NVBLASTEXTBINARYBLOCKCONVERTER_H - - -#include "NvBlast.h" -#include <vector> -#include <memory> - - -namespace Nv -{ -namespace Blast -{ - -/** -Generic binary block converter class. - -BinaryBlockConverter is an abstract class, as well as it's member class VersionConverter. In order to implement your own -binary converter - implement for every version conversion BinaryBlockConverter::VersionConverter. Then implement BinaryBlockConverter -where getVersionConverters() should return all your implemented BinaryBlockConverter::VersionConverter's. - -*/ -class BinaryBlockConverter -{ -public: - class VersionConverter - { - public: - virtual uint32_t getVersionFrom() const = 0; - virtual uint32_t getVersionTo() const = 0; - virtual bool convert(const std::vector<char>& from, std::vector<char>& to) const = 0; - }; - - typedef std::shared_ptr<VersionConverter> VersionConverterPtr; - - static bool convertBinaryBlock(std::vector<char>& outBlock, const std::vector<VersionConverterPtr>& converters, const std::vector<char>& inBlock, uint32_t outBlockVersion, uint32_t inBlockVersion); -protected: - -private: - static bool findShortestPath(std::vector<VersionConverterPtr>& conversionPath, const std::vector<VersionConverterPtr>& converters, uint32_t versionFrom, uint32_t versionTo); -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTBINARYBLOCKCONVERTER_H diff --git a/sdk/extensions/converter/source/conversion/NvBlastExtDataConverter.cpp b/sdk/extensions/converter/source/conversion/NvBlastExtDataConverter.cpp deleted file mode 100644 index fe8c745..0000000 --- a/sdk/extensions/converter/source/conversion/NvBlastExtDataConverter.cpp +++ /dev/null @@ -1,103 +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 "NvBlastExtDataConverter.h" -#include "NvBlastExtBinaryBlockConverter.h" - -#include <iostream> - -// asset converters -#include "NvBlastExtAssetBlockVersionConverter_v0_v1.h" - - -namespace Nv -{ -namespace Blast -{ - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Asset Block Converter -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -NV_INLINE std::vector<BinaryBlockConverter::VersionConverterPtr> getAssetConverters() -{ - /** - +==========================================+ - | HINT: ADD NEW VERSION CONVERTERS THERE | - +==========================================+ - */ - BinaryBlockConverter::VersionConverterPtr converters[] = - { - std::make_shared<NvBlastAssetBlockVersionConverter_v0_v1>() - }; - - return std::vector<BinaryBlockConverter::VersionConverterPtr>(converters, converters + sizeof(converters) / sizeof(converters[0])); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Family Converter -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -NV_INLINE std::vector<BinaryBlockConverter::VersionConverterPtr> getFamilyConverters() -{ - /** - +==========================================+ - | HINT: ADD NEW VERSION CONVERTERS THERE | - +==========================================+ - */ - BinaryBlockConverter::VersionConverterPtr converters[] = - { - nullptr //std::make_shared<NvBlastFamilyVersionConverter_v0_v1>() - }; - - return std::vector<BinaryBlockConverter::VersionConverterPtr>(converters, converters + sizeof(converters) / sizeof(converters[0])); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Generic Block Converter -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool convertDataBlock(std::vector<char>& outBlock, const std::vector<char>& inBlock, uint32_t* outBlockVersion) -{ - // Pick header to determine dataType and version - if (inBlock.size() < sizeof(NvBlastDataBlock)) - { - std::cerr << "Conversion failed: invalid block, passed block is too small." << std::endl; - return false; - } - const NvBlastDataBlock* dataBlock = reinterpret_cast<const NvBlastDataBlock*>(inBlock.data()); - - // Select appropriate converters and version based on dataType - std::vector<BinaryBlockConverter::VersionConverterPtr> converters; - uint32_t version; - switch (dataBlock->dataType) - { - case NvBlastDataBlock::AssetDataBlock: - std::cout << "Input block dataType: NvBlastDataBlock::Asset" << std::endl; - converters = getAssetConverters(); - version = (outBlockVersion == nullptr ? static_cast<uint32_t>(NvBlastAssetDataFormat::Current) : *outBlockVersion); - break; - case NvBlastDataBlock::FamilyDataBlock: - std::cout << "Input block dataType: NvBlastDataBlock::Family" << std::endl; - converters = getFamilyConverters(); - version = (outBlockVersion == nullptr ? static_cast<uint32_t>(NvBlastFamilyDataFormat::Current) : *outBlockVersion); - break; - default: - std::cerr << "Conversion failed: unsupported dataType: " << dataBlock->dataType << std::endl; - return false; - } - - return BinaryBlockConverter::convertBinaryBlock(outBlock, converters, inBlock, version, dataBlock->formatVersion); -} - -} // namespace Blast -} // namespace Nv diff --git a/sdk/extensions/exporter/include/NvBlastExtExporter.h b/sdk/extensions/exporter/include/NvBlastExtExporter.h new file mode 100644 index 0000000..5432ec7 --- /dev/null +++ b/sdk/extensions/exporter/include/NvBlastExtExporter.h @@ -0,0 +1,257 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTER_H +#define NVBLASTEXTEXPORTER_H + +#include "NvBlastTypes.h" + +struct NvBlastAsset; + +namespace physx +{ +class PxVec2; +class PxVec3; +} + +namespace Nv +{ +namespace Blast +{ +struct AuthoringResult; +struct CollisionHull; + +struct ExporterMeshData +{ + NvBlastAsset* asset; //Blast asset + + uint32_t positionsCount; //Number of positions + + uint32_t normalsCount; //Number of normals + + uint32_t uvsCount; //Number of textures uv + + physx::PxVec3* positions; //Array of positions + + physx::PxVec3* normals; //Array of normals + + physx::PxVec2* uvs; //Array of textures uv + + uint32_t meshCount; //Number of meshes (chunks) + + uint32_t submeshCount; //Number of submeshes + + const char** submeshNames; //Equal to material names + + + /** + Indices offsets for posIndex, normIndex and texIndex + First position index: posIndex[submeshOffsets[meshId * submeshCount + submeshId]] + Total number of indices: submeshOffsets[meshCount * submeshCount] + */ + uint32_t* submeshOffsets; + + uint32_t* posIndex; //Array of position indices + + uint32_t* normIndex; //Array of normals indices + + uint32_t* texIndex; //Array of texture indices + + + /** + Hull offsets. Contains meshCount + 1 element. + First hull for i-th mesh: hulls[hullsOffsets[i]] + hullsOffsets[meshCount+1] is total number of hulls + */ + uint32_t* hullsOffsets; + + CollisionHull** hulls; //Array of pointers to hull for all meshes +}; + +/** + An interface for Blast mesh file reader +*/ +class IMeshFileReader +{ +public: + + /** + Delete this object + */ + virtual void release() = 0; + + /* + Load from the specified file path + */ + virtual void loadFromFile(const char* filename) = 0; + + /** + Number of loaded vertices + */ + virtual uint32_t getVerticesCount() const = 0; + + /** + Number of loaded indices + */ + virtual uint32_t getIdicesCount() const = 0; + + /** + Get loaded vertex positions + */ + virtual physx::PxVec3* getPositionArray() = 0; + + /** + Get loaded vertex normals + */ + virtual physx::PxVec3* getNormalsArray() = 0; + + /** + Get loaded vertex uv-coordinates + */ + virtual physx::PxVec2* getUvArray() = 0; + + /** + Get loaded per triangle material ids. + */ + virtual int32_t* getMaterialIds() = 0; + + /** + Get loaded per triangle smoothing groups. + */ + virtual int32_t* getSmoothingGroups() = 0; + + /** + Get material name. + */ + virtual char* getMaterialName(int32_t id) = 0; + + /** + Get material count. + */ + virtual int32_t getMaterialCount() = 0; + + + + /** + Get loaded triangle indices + */ + virtual uint32_t* getIndexArray() = 0; + + + /** + Check whether file contained an collision geometry + */ + virtual bool isCollisionLoaded() = 0; + + /** + Retrieve collision geometry if it exist + \note User should call NVBLAST_FREE for hulls and hullsOffset when it not needed anymore + + \param[out] hullsOffset Array of hull offsets for hulls array. The size is meshCount + 1. + \param[out] hulls Array of hull. The first i-th mesh hull: hulls[hullsOffset[i]]. The size is written to hullsOffset[meshCount] + \return Number of meshes (meshCount) + */ + virtual uint32_t getCollision(uint32_t*& hullsOffset, CollisionHull** hulls) = 0; + +}; + +/** + An interface for fbx file reader +*/ +class IFbxFileReader : public IMeshFileReader +{ +public: + /** + Retrieve bone influence if it exist + \note User should call NVBLAST_FREE for out when it not needed anymore + + \param[out] out Array of bone influences. + \return Number of bones influences (boneCount) + */ + virtual uint32_t getBoneInfluences(uint32_t*& out) = 0; + + /** + Return number of bones in fbx file + */ + virtual uint32_t getBoneCount() = 0; +}; + +/** + An interface for Blast mesh file writer +*/ +class IMeshFileWriter +{ +public: + + /** + Delete this object + */ + virtual void release() = 0; + + /** + Append rendermesh to scene. Meshes constructed from arrays of triangles. + */ + virtual bool appendMesh(const AuthoringResult& aResult, const char* assetName, bool nonSkinned = false) = 0; + + /** + Append rendermesh to scene. Meshes constructed from arrays of vertices and indices + */ + virtual bool appendMesh(const ExporterMeshData& meshData, const char* assetName, bool nonSkinned = false) = 0; + + /** + Save scene to file. + */ + virtual bool saveToFile(const char* assetName, const char* outputPath) = 0; +}; + +} +} + +/** + Creates an instance of IMeshFileReader for reading obj file. +*/ +NVBLAST_API Nv::Blast::IMeshFileReader* NvBlastExtExporterCreateObjFileReader(); + +/** + Creates an instance of IFbxFileReader for reading fbx file. +*/ +NVBLAST_API Nv::Blast::IFbxFileReader* NvBlastExtExporterCreateFbxFileReader(); + +/** + Creates an instance of IMeshFileWriter for writing obj file. +*/ +NVBLAST_API Nv::Blast::IMeshFileWriter* NvBlastExtExporterCreateObjFileWriter(); + +/** + Creates an instance of IMeshFileWriter for writing fbx file. + + \param[in] outputFBXAscii If true writes fbx in ascii format otherwise write in binary. +*/ +NVBLAST_API Nv::Blast::IMeshFileWriter* NvBlastExtExporterCreateFbxFileWriter(bool outputFBXAscii = false); + +#endif //NVBLASTEXTEXPORTER_H
\ No newline at end of file diff --git a/sdk/extensions/exporter/include/NvBlastExtExporterJsonCollision.h b/sdk/extensions/exporter/include/NvBlastExtExporterJsonCollision.h new file mode 100644 index 0000000..5cda025 --- /dev/null +++ b/sdk/extensions/exporter/include/NvBlastExtExporterJsonCollision.h @@ -0,0 +1,62 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTERJSONCOLLISION_H +#define NVBLASTEXTEXPORTERJSONCOLLISION_H + +#include "NvBlastTypes.h" + +namespace Nv +{ +namespace Blast +{ + + +struct CollisionHull; + +/** + Serializes collision geometry to JSON format. +*/ +class JsonCollisionExporter +{ +public: + JsonCollisionExporter(){}; + + /** + Method creates file with given path and serializes given array of arrays of convex hulls to it in JSON format. + \param[in] path Output file path + \param[in] hulls Array of arrays of convex hull descriptors. Each array contain array of convex hulls for chunk (hulls[0] - convexes for chunk 0, etc.) + */ + bool writeCollision(const char* path, uint32_t meshCount, const uint32_t* meshOffsets, const CollisionHull* hulls); +}; + + +} // namespace Blast +} // namespace Nv + +#endif //NVBLASTEXTEXPORTERJSONCOLLISION_H
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporter.cpp new file mode 100644 index 0000000..d74a1ee --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporter.cpp @@ -0,0 +1,58 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtExporter.h" +#include "NvBlastExtExporterFbxReader.h" +#include "NvBlastExtExporterObjReader.h" +#include "NvBlastExtExporterFbxWriter.h" +#include "NvBlastExtExporterObjWriter.h" + +using namespace Nv::Blast; + +IMeshFileReader* NvBlastExtExporterCreateObjFileReader() +{ + return new ObjFileReader; +} + +IFbxFileReader* NvBlastExtExporterCreateFbxFileReader() +{ + return new FbxFileReader; +} + +IMeshFileWriter* NvBlastExtExporterCreateObjFileWriter() +{ + return new ObjFileWriter; +} + +IMeshFileWriter* NvBlastExtExporterCreateFbxFileWriter(bool outputFBXAscii) +{ + auto ret = new FbxFileWriter; + ret->bOutputFBXAscii = outputFBXAscii; + return ret; +} + diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp new file mode 100644 index 0000000..df0500e --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp @@ -0,0 +1,505 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + +#include "NvBlastExtExporterFbxReader.h" +#include "NvBlastExtExporterFbxUtils.h" +#include "NvBlastGlobals.h" +#include "fileio/fbxiosettings.h" +#include "fileio/fbxiosettingspath.h" +#include "core/base/fbxstringlist.h" +#include <iostream> +#include <algorithm> +#include <cctype> +#include <sstream> +#include "scene/geometry/fbxmesh.h" + +#include "PxVec3.h" +#include "PxVec2.h" +#include "NvBlastExtAuthoringMesh.h" +#include "NvBlastExtAuthoringBondGenerator.h" +#include "NvBlastExtAuthoringCollisionBuilder.h" + +using physx::PxVec3; +using physx::PxVec2; + +using namespace Nv::Blast; + +FbxFileReader::FbxFileReader() +{ + mBoneCount = 0; +} + +void FbxFileReader::release() +{ + delete this; +} + +FbxAMatrix FbxFileReader::getTransformForNode(FbxNode* node) +{ + //The geometry transform contains the information about the pivots in the mesh node relative to the node's transform + FbxAMatrix geometryTransform(node->GetGeometricTranslation(FbxNode::eSourcePivot), + node->GetGeometricRotation(FbxNode::eSourcePivot), + node->GetGeometricScaling(FbxNode::eSourcePivot)); + FbxAMatrix nodeTransform = node->EvaluateGlobalTransform(); + + return nodeTransform * geometryTransform; +} + +void FbxFileReader::loadFromFile(const char* filename) +{ + // Wrap in a shared ptr so that when it deallocates we get an auto destroy and all of the other assets created don't leak. + std::shared_ptr<FbxManager> sdkManager = std::shared_ptr<FbxManager>(FbxManager::Create(), [=](FbxManager* manager) + { + std::cout << "Deleting FbxManager" << std::endl; + manager->Destroy(); + }); + + mBoneCount = 0; + mCollisionNodes.clear(); + FbxIOSettings* ios = FbxIOSettings::Create(sdkManager.get(), IOSROOT); + // Set some properties on the io settings + + sdkManager->SetIOSettings(ios); + + + FbxImporter* importer = FbxImporter::Create(sdkManager.get(), ""); + + bool importStatus = importer->Initialize(filename, -1, sdkManager->GetIOSettings()); + + if (!importStatus) + { + std::cerr << "Call to FbxImporter::Initialize failed." << std::endl; + std::cerr << "Error returned: " << importer->GetStatus().GetErrorString() << std::endl; + + return; + } + + FbxScene* scene = FbxScene::Create(sdkManager.get(), "importScene"); + + + + + importStatus = importer->Import(scene); + + if (!importStatus) + { + std::cerr << "Call to FbxImporter::Import failed." << std::endl; + std::cerr << "Error returned: " << importer->GetStatus().GetErrorString() << std::endl; + + return; + } + + int32_t matCount = scene->GetMaterialCount(); + + for (int32_t i = 0; i < matCount; ++i) + { + mMaterialNames.push_back(std::string(scene->GetMaterial(i)->GetName())); + } + + //This removes axis and unit conversion nodes so it converts the entire scene to the header specified axis and units + FbxRootNodeUtility::RemoveAllFbxRoots(scene); + + FbxAxisSystem blastAxisSystem = FbxUtils::getBlastFBXAxisSystem(); + FbxAxisSystem sourceSetup = scene->GetGlobalSettings().GetAxisSystem(); + if (sourceSetup != blastAxisSystem) + { + std::cout << "Converting to Blast coordinates" << std::endl; + std::cout << "Existing axis: " << FbxUtils::FbxAxisSystemToString(sourceSetup) << std::endl; + blastAxisSystem.ConvertScene(scene); + } + + FbxSystemUnit blastUnits = FbxUtils::getBlastFBXUnit(); + FbxSystemUnit sourceUnits = scene->GetGlobalSettings().GetSystemUnit(); + if (sourceUnits != blastUnits) + { + std::cout << "Converting to Blast units" << std::endl; + std::cout << "Existing units: " << FbxUtils::FbxSystemUnitToString(sourceUnits) << std::endl; + blastUnits.ConvertScene(scene); + } + + FbxDisplayLayer* collisionDisplayLayer = scene->FindMember<FbxDisplayLayer>(FbxUtils::getCollisionGeometryLayerName().c_str()); + + // Recurse the fbx tree and find all meshes + std::vector<FbxNode*> meshNodes; + getFbxMeshes(collisionDisplayLayer, scene->GetRootNode(), meshNodes); + + if (isCollisionLoaded()) + { + std::cout << "Collision geometry is found."; + getCollisionInternal(); + } + + std::cout << "Found " << meshNodes.size() << " meshes." << std::endl; + + // Process just 0, because dumb. Fail out if more than 1? + if (meshNodes.size() > 1) + { + std::cerr << "Can't load more that one graphics mesh." << std::endl; + return; + } + + if (meshNodes.empty()) + { + return; + } + + FbxNode* meshNode = meshNodes[0]; + FbxMesh* mesh = meshNode->GetMesh(); + + int polyCount = mesh->GetPolygonCount(); + + + bool bAllTriangles = true; + // Verify that the mesh is triangulated. + for (int i = 0; i < polyCount; i++) + { + if (mesh->GetPolygonSize(i) != 3) + { + bAllTriangles = false; + } + } + + if (!bAllTriangles) + { + std::cerr << "Mesh 0 has " << polyCount << " but not all polygons are triangles. Mesh must be triangulated." << std::endl; + return; + } + + FbxStringList uvSetNames; + + mesh->GetUVSetNames(uvSetNames); + + const char * uvSetName = uvSetNames.GetStringAt(0); + + std::vector<PxVec3> positions; + std::vector<PxVec3> normals; + std::vector<PxVec2> uv; + std::vector<uint32_t> indices; + + int* polyVertices = mesh->GetPolygonVertices(); + + uint32_t vertIndex = 0; + + FbxAMatrix trans = getTransformForNode(meshNode); + FbxVector4 rotation = trans.GetR(); + FbxVector4 scale = trans.GetS(); + FbxAMatrix normalTransf; + normalTransf.SetR(rotation); + normalTransf.SetS(scale); + normalTransf = normalTransf.Inverse().Transpose(); + + int32_t matElements = mesh->GetElementMaterialCount(); + if (matElements > 1) + { + std::cerr << "Mesh has more than 1 material mappings, first one will be used. " << std::endl; + } + auto matLayer = mesh->GetElementMaterial(0); + + + for (int i = 0; i < polyCount; i++) + { + for (int vi = 0; vi < 3; vi++) + { + int polyCPIdx = polyVertices[i*3+vi]; + + FbxVector4 vert = mesh->GetControlPointAt(polyCPIdx); + FbxVector4 normVec; + FbxVector2 uvVec; + + bool bUnmapped; + mesh->GetPolygonVertexNormal(i, vi, normVec); + mesh->GetPolygonVertexUV(i, vi, uvSetName, uvVec, bUnmapped); + vert = trans.MultT(vert); + normVec = normalTransf.MultT(normVec); + + positions.push_back(PxVec3((float) vert[0], (float)vert[1], (float)vert[2])); + normals.push_back(PxVec3((float)normVec[0], (float)normVec[1], (float)normVec[2])); + uv.push_back(PxVec2((float)uvVec[0], (float)uvVec[1])); + indices.push_back(vertIndex++); + } + if (matLayer != nullptr) + { + mMaterialIds.push_back(matLayer->GetIndexArray().GetAt(i)); + } + } + + mVertexPositions = positions; + mVertexNormals = normals; + mVertexUv = uv; + mIndices = indices; + + getBoneInfluencesInternal(mesh); +} + +int32_t FbxFileReader::getMaterialCount() +{ + return mMaterialNames.size(); +} + +void FbxFileReader::getFbxMeshes(FbxDisplayLayer* collisionDisplayLayer, FbxNode* node, std::vector<FbxNode*>& meshNodes) +{ + FbxMesh* mesh = node->GetMesh(); + + if (mesh != nullptr) + { + if (collisionDisplayLayer == nullptr && node->FindProperty("ParentalChunkIndex").IsValid()) + { + //Old-style file + uint32_t chunkIndex = node->FindProperty("ParentalChunkIndex").Get<int32_t>(); + mCollisionNodes.emplace(chunkIndex, node); + } + else if (collisionDisplayLayer != nullptr && collisionDisplayLayer->IsMember(node)) + { + uint32_t chunkIndex = FbxUtils::getChunkIndexForNode(node); + if (chunkIndex != UINT32_MAX) + { + mCollisionNodes.emplace(chunkIndex, node); + } + else + { + std::cerr << "Warning: Not sure what to do about collision geo " << node->GetName() << ". No corresponding chunk." << std::endl; + } + } + else + { + meshNodes.push_back(node); + } + } + int childCount = node->GetChildCount(); + + for (int i = 0; i < childCount; i++) + { + FbxNode * childNode = node->GetChild(i); + + getFbxMeshes(collisionDisplayLayer, childNode, meshNodes); + } +} + +bool FbxFileReader::isCollisionLoaded() +{ + return !mCollisionNodes.empty(); +} + +uint32_t FbxFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls) +{ + if (!isCollisionLoaded()) + { + return 0; + } + hullsOffset = new uint32_t[mMeshCount + 1]; + hulls = new Nv::Blast::CollisionHull*[mMeshCount]; + memcpy(hullsOffset, mHullsOffset.data(), sizeof(uint32_t) * (mMeshCount + 1)); + memcpy(hulls, mHulls.data(), sizeof(Nv::Blast::CollisionHull*) * mMeshCount); + return mMeshCount; +} + +struct CollisionHullImpl : public Nv::Blast::CollisionHull +{ + void release() override + { + + } +}; + +bool FbxFileReader::getCollisionInternal() +{ + for (auto hull : mHulls) + { + hull->release(); + } + int32_t maxParentIndex = 0; + + for (auto p : mCollisionNodes) + { + int32_t parentIndex = p.first; + maxParentIndex = std::max(maxParentIndex, parentIndex); + } + mMeshCount = maxParentIndex + 1; + mHullsOffset.resize(mMeshCount + 1); + mHulls.resize(mCollisionNodes.size()); + mHullsOffset[0] = 0; + + for (auto p : mCollisionNodes) // it should be sorted by chunk id + { + int32_t parentIndex = p.first; + //hulls[parentIndex].push_back(Nv::Blast::CollisionHull()); + mHulls[mHullsOffset[parentIndex]] = new CollisionHullImpl(); + Nv::Blast::CollisionHull& chull = *mHulls[mHullsOffset[parentIndex]]; + FbxMesh* meshNode = p.second->GetMesh(); + + FbxAMatrix nodeTransform = getTransformForNode(p.second); + FbxAMatrix nodeTransformNormal = nodeTransform.Inverse().Transpose(); + + chull.points = new PxVec3[meshNode->GetControlPointsCount()]; + FbxVector4* vpos = meshNode->GetControlPoints(); + /** + Copy control points from FBX. + */ + for (int32_t i = 0; i < meshNode->GetControlPointsCount(); ++i) + { + FbxVector4 worldVPos = nodeTransform.MultT(*vpos); + chull.points[i].x = (float)worldVPos[0]; + chull.points[i].y = (float)worldVPos[1]; + chull.points[i].z = (float)worldVPos[2]; + vpos++; + } + + uint32_t polyCount = meshNode->GetPolygonCount(); + chull.polygonData = new Nv::Blast::CollisionHull::HullPolygon[polyCount]; + FbxGeometryElementNormal* nrm = meshNode->GetElementNormal(); + FbxLayerElementArray& narr = nrm->GetDirectArray(); + + for (uint32_t poly = 0; poly < polyCount; ++poly) + { + int32_t vInPolyCount = meshNode->GetPolygonSize(poly); + auto& pd = chull.polygonData[poly]; + pd.mIndexBase = (uint16_t)chull.indicesCount; + pd.mNbVerts = (uint16_t)vInPolyCount; + int32_t* ind = &meshNode->GetPolygonVertices()[meshNode->GetPolygonVertexIndex(poly)]; + chull.indices = new uint32_t[vInPolyCount]; + memcpy(chull.indices, ind, sizeof(uint32_t) * vInPolyCount); + + FbxVector4 normal; + narr.GetAt(poly, &normal); + + normal = nodeTransformNormal.MultT(normal); + + pd.mPlane[0] = (float)normal[0]; + pd.mPlane[1] = (float)normal[1]; + pd.mPlane[2] = (float)normal[2]; + PxVec3 polyLastVertex = chull.points[chull.indices[vInPolyCount - 1]]; + pd.mPlane[3] = -((float)(polyLastVertex.x * normal[0] + polyLastVertex.y * normal[1] + polyLastVertex.z * normal[2])); + } + mHullsOffset[parentIndex + 1] = mHullsOffset[parentIndex] + 1; + } + + + return false; +} + + +/** + To work properly export tool should give bone names as bone_@chunkIndex (e.g. bone_1, bone_2) +**/ +bool FbxFileReader::getBoneInfluencesInternal(FbxMesh* meshNode) +{ + + if (meshNode->GetDeformerCount() != 1) + { + std::cout << "Can't create bone mapping: There is no mesh deformers...: " << std::endl; + return false; + } + mVertexToParentBoneMap.clear(); + mVertexToParentBoneMap.resize(mVertexPositions.size()); + std::vector<uint32_t> controlToParentBoneMap; + controlToParentBoneMap.resize(meshNode->GetControlPointsCount()); + FbxSkin* def = (FbxSkin *)meshNode->GetDeformer(0, FbxDeformer::EDeformerType::eSkin); + + if (def->GetClusterCount() == 0) + { + std::cout << "Can't create bone mapping: There is no vertex clusters...: " << std::endl; + return false; + } + mBoneCount = def->GetClusterCount(); + for (int32_t i = 0; i < def->GetClusterCount(); ++i) + { + FbxCluster* cls = def->GetCluster(i); + FbxNode* bone = cls->GetLink(); + int32_t parentChunk = atoi(bone->GetName() + 5); + int32_t* cpIndx = cls->GetControlPointIndices(); + for (int32_t j = 0; j < cls->GetControlPointIndicesCount(); ++j) + { + controlToParentBoneMap[*cpIndx] = parentChunk; + ++cpIndx; + } + } + int* polyVertices = meshNode->GetPolygonVertices(); + uint32_t lv = 0; + for (int i = 0; i < meshNode->GetPolygonCount(); i++) + { + for (int vi = 0; vi < 3; vi++) + { + mVertexToParentBoneMap[lv] = controlToParentBoneMap[*polyVertices]; + polyVertices++; + lv++; + } + } + return true; +}; + +physx::PxVec3* FbxFileReader::getPositionArray() +{ + return mVertexPositions.data(); +}; + +physx::PxVec3* FbxFileReader::getNormalsArray() +{ + return mVertexNormals.data(); +}; + +physx::PxVec2* FbxFileReader::getUvArray() +{ + return mVertexUv.data(); +}; + +uint32_t* FbxFileReader::getIndexArray() +{ + return mIndices.data(); +}; + +uint32_t FbxFileReader::getBoneInfluences(uint32_t*& out) +{ + out = static_cast<uint32_t*>(NVBLAST_ALLOC(sizeof(uint32_t) * mVertexToParentBoneMap.size())); + memcpy(out, mVertexToParentBoneMap.data(), sizeof(uint32_t) * mVertexToParentBoneMap.size()); + return mVertexToParentBoneMap.size(); +} + +uint32_t FbxFileReader::getBoneCount() +{ + return mBoneCount; +} + +char* FbxFileReader::getMaterialName(int32_t id) +{ + if (id < int32_t(mMaterialNames.size()) && id >= 0) + { + return &mMaterialNames[id][0]; + } + else + { + return nullptr; + } +} + +int32_t* FbxFileReader::getMaterialIds() +{ + if (mMaterialIds.empty()) + { + return nullptr; + } + return mMaterialIds.data(); +}
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h new file mode 100644 index 0000000..4155b25 --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h @@ -0,0 +1,144 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTERFBXREADER_H +#define NVBLASTEXTEXPORTERFBXREADER_H + +#include <memory> +#include "fbxsdk.h" +#include <vector> +#include <map> +#include "NvBlastExtExporter.h" +#include "NvBlastExtAuthoringTypes.h" + +namespace Nv +{ +namespace Blast +{ +class Mesh; + +class FbxFileReader : public IFbxFileReader +{ +public: + FbxFileReader(); + ~FbxFileReader() = default; + + virtual void release() override; + + /* + Load from the specified file path, returning a mesh or nullptr if failed + */ + virtual void loadFromFile(const char* filename) override; + + virtual uint32_t getVerticesCount() const override + { + return mVertexPositions.size(); + } + + virtual uint32_t getIdicesCount() const override + { + return mIndices.size(); + } + + /** + Check whether file contained an collision geometry + */ + virtual bool isCollisionLoaded() override; + + /** + Retrieve collision geometry if it exist + */ + virtual uint32_t getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls) override; + + virtual uint32_t getBoneInfluences(uint32_t*& out) override; + + virtual uint32_t getBoneCount() override; + + /** + Get loaded vertex positions + */ + virtual physx::PxVec3* getPositionArray() override; + /** + Get loaded vertex normals + */ + virtual physx::PxVec3* getNormalsArray() override; + /** + Get loaded vertex uv-coordinates + */ + virtual physx::PxVec2* getUvArray() override; + /** + Get loaded triangle indices + */ + virtual uint32_t* getIndexArray() override; + + /** + Get loaded per triangle material ids. + */ + int32_t* getMaterialIds() override; + + /** + Get loaded per triangle smoothing groups. Currently not supported. + */ + int32_t* getSmoothingGroups() override { return nullptr; }; + + /** + Get material name. + */ + char* getMaterialName(int32_t id) override; + + + int32_t getMaterialCount() override; + +private: + + uint32_t mMeshCount; + std::vector<uint32_t> mHullsOffset; + std::vector<Nv::Blast::CollisionHull*> mHulls; + std::vector<uint32_t> mVertexToParentBoneMap; + std::multimap<uint32_t, FbxNode*> mCollisionNodes; + std::vector<physx::PxVec3> mVertexPositions; + std::vector<physx::PxVec3> mVertexNormals; + std::vector<physx::PxVec2> mVertexUv; + std::vector<uint32_t> mIndices; + std::vector<int32_t> mSmoothingGroups; + std::vector<int32_t> mMaterialIds; + std::vector<std::string> mMaterialNames; + + uint32_t mBoneCount; + + FbxAMatrix getTransformForNode(FbxNode* node); + void getFbxMeshes(FbxDisplayLayer* collisionDisplayLayer, FbxNode* node, std::vector<FbxNode*>& meshNodes); + bool getCollisionInternal(); + bool getBoneInfluencesInternal(FbxMesh* meshNode); + +}; + +} +} + +#endif
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp new file mode 100644 index 0000000..95a757f --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp @@ -0,0 +1,192 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2017 NVIDIA Corporation. All rights reserved. + + +#include "fbxsdk.h" +#include "NvBlastExtExporterFbxUtils.h" +#include "PxVec3.h" +#include "PxVec2.h" +#include "NvBlastExtAuthoringTypes.h" +#include <sstream> +#include <cctype> + +using physx::PxVec3; +using physx::PxVec2; + + +void FbxUtils::VertexToFbx(const Nv::Blast::Vertex& vert, FbxVector4& outVertex, FbxVector4& outNormal, FbxVector2& outUV) +{ + PxVec3ToFbx(vert.p, outVertex); + PxVec3ToFbx(vert.n, outNormal); + PxVec2ToFbx(vert.uv[0], outUV); +} + +void FbxUtils::PxVec3ToFbx(const physx::PxVec3& inVector, FbxVector4& outVector) +{ + outVector[0] = inVector.x; + outVector[1] = inVector.y; + outVector[2] = inVector.z; + outVector[3] = 0; +} + +void FbxUtils::PxVec2ToFbx(const physx::PxVec2& inVector, FbxVector2& outVector) +{ + outVector[0] = inVector.x; + outVector[1] = inVector.y; +} + +FbxAxisSystem FbxUtils::getBlastFBXAxisSystem() +{ + const FbxAxisSystem::EUpVector upVector = FbxAxisSystem::eZAxis; + //From the documentation: If the up axis is Z, the remain two axes will X And Y, so the ParityEven is X, and the ParityOdd is Y + const FbxAxisSystem::EFrontVector frontVector = FbxAxisSystem::eParityOdd; + const FbxAxisSystem::ECoordSystem rightVector = FbxAxisSystem::eRightHanded; + return FbxAxisSystem(upVector, frontVector, rightVector); +} + +FbxSystemUnit FbxUtils::getBlastFBXUnit() +{ + return FbxSystemUnit::cm; +} + +std::string FbxUtils::FbxAxisSystemToString(const FbxAxisSystem& axisSystem) +{ + std::stringstream ss; + int upSign, frontSign; + FbxAxisSystem::EUpVector upVector = axisSystem.GetUpVector(upSign); + FbxAxisSystem::EFrontVector frontVector = axisSystem.GetFrontVector(frontSign); + FbxAxisSystem::ECoordSystem coordSystem = axisSystem.GetCoorSystem(); + ss << "Predefined Type: "; + if (axisSystem == FbxAxisSystem::MayaZUp) + { + ss << "MayaZUP"; + } + else if (axisSystem == FbxAxisSystem::MayaYUp) + { + ss << "MayaYUp"; + } + else if (axisSystem == FbxAxisSystem::Max) + { + ss << "Max"; + } + else if (axisSystem == FbxAxisSystem::Motionbuilder) + { + ss << "Motionbuilder"; + } + else if (axisSystem == FbxAxisSystem::OpenGL) + { + ss << "OpenGL"; + } + else if (axisSystem == FbxAxisSystem::DirectX) + { + ss << "OpenGL"; + } + else if (axisSystem == FbxAxisSystem::Lightwave) + { + ss << "OpenGL"; + } + else + { + ss << "<Other>"; + } + ss << " UpVector: " << (upSign > 0 ? "+" : "-"); + switch (upVector) + { + case FbxAxisSystem::eXAxis: ss << "eXAxis"; break; + case FbxAxisSystem::eYAxis: ss << "eYAxis"; break; + case FbxAxisSystem::eZAxis: ss << "eZAxis"; break; + default: ss << "<unknown>"; break; + } + + ss << " FrontVector: " << (frontSign > 0 ? "+" : "-"); + switch (frontVector) + { + case FbxAxisSystem::eParityEven: ss << "eParityEven"; break; + case FbxAxisSystem::eParityOdd: ss << "eParityOdd"; break; + default: ss << "<unknown>"; break; + } + + ss << " CoordSystem: "; + switch (coordSystem) + { + case FbxAxisSystem::eLeftHanded: ss << "eLeftHanded"; break; + case FbxAxisSystem::eRightHanded: ss << "eRightHanded"; break; + default: ss << "<unknown>"; break; + } + + return ss.str(); +} + +std::string FbxUtils::FbxSystemUnitToString(const FbxSystemUnit& systemUnit) +{ + return std::string(systemUnit.GetScaleFactorAsString()); +} + +const static std::string chunkPrefix = "chunk_"; + +uint32_t FbxUtils::getChunkIndexForNode(FbxNode* node, bool includeParents /*= true*/) +{ + std::string nodeName(node->GetNameOnly()); + for (char& c : nodeName) + c = (char)std::tolower(c); + + if (nodeName.substr(0, chunkPrefix.size()) == chunkPrefix) + { + std::istringstream iss(nodeName.substr(chunkPrefix.size())); + uint32_t ret = UINT32_MAX; + iss >> ret; + if (!iss.fail()) + { + return ret; + } + } + + if (includeParents && node->GetParent()) + { + return getChunkIndexForNode(node->GetParent(), true); + } + //Found nothing + return UINT32_MAX; +} + +std::string FbxUtils::getChunkNodeName(uint32_t chunkIndex) +{ + //This naming is required for the UE4 plugin to find them + std::ostringstream namestream; + namestream << chunkPrefix << chunkIndex; + return namestream.str(); +} + +std::string FbxUtils::getCollisionGeometryLayerName() +{ + return "Collision"; +} + +std::string FbxUtils::getRenderGeometryLayerName() +{ + return "Render"; +} diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h new file mode 100644 index 0000000..d26a9e9 --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h @@ -0,0 +1,67 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTERFBXUTILS_H +#define NVBLASTEXTEXPORTERFBXUTILS_H + +#include "fbxsdk.h" +#include "PxVec3.h" +#include "PxVec2.h" +#include <string> + +namespace Nv +{ + namespace Blast + { + struct Vertex; + } +} + +class FbxUtils +{ +public: + static void VertexToFbx(const Nv::Blast::Vertex& vert, FbxVector4& outVertex, FbxVector4& outNormal, FbxVector2& outUV); + + static void PxVec3ToFbx(const physx::PxVec3& inVector, FbxVector4& outVector); + static void PxVec2ToFbx(const physx::PxVec2& inVector, FbxVector2& outVector); + + static FbxAxisSystem getBlastFBXAxisSystem(); + static FbxSystemUnit getBlastFBXUnit(); + + static std::string FbxAxisSystemToString(const FbxAxisSystem& axisSystem); + static std::string FbxSystemUnitToString(const FbxSystemUnit& systemUnit); + + //returns UINT32_MAX if not a chunk + static uint32_t getChunkIndexForNode(FbxNode* node, bool includeParents = true); + static std::string getChunkNodeName(uint32_t chunkIndex); + + static std::string getCollisionGeometryLayerName(); + static std::string getRenderGeometryLayerName(); +}; + +#endif //NVBLASTEXTEXPORTERFBXUTILS_H
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp new file mode 100644 index 0000000..b5fd04b --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp @@ -0,0 +1,1095 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "fbxsdk.h" +#include <iostream> +#include <sstream> +#include <iomanip> +#include "NvBlastTypes.h" +#include "NvBlastGlobals.h" +#include "NvBlastTkFramework.h" +#include "NvBlast.h" +#include "PxVec3.h" +#include "NvBlastAssert.h" +#include <unordered_set> +#include <functional> +#include "NvBlastExtExporterFbxWriter.h" +#include "NvBlastExtExporterFbxUtils.h" +#include "NvBlastExtAuthoringCollisionBuilder.h" +#include "NvBlastExtAuthoring.h" +#include "NvBlastExtAuthoringMesh.h" + +using namespace Nv::Blast; + +FbxFileWriter::FbxFileWriter(): + bOutputFBXAscii(false) +{ + // Wrap in a shared ptr so that when it deallocates we get an auto destroy and all of the other assets created don't leak. + sdkManager = std::shared_ptr<FbxManager>(FbxManager::Create(), [=](FbxManager* manager) + { + std::cout << "Deleting FbxManager" << std::endl; + manager->Destroy(); + }); + + mScene = FbxScene::Create(sdkManager.get(), "Export Scene"); + + mScene->GetGlobalSettings().SetAxisSystem(FbxUtils::getBlastFBXAxisSystem()); + mScene->GetGlobalSettings().SetSystemUnit(FbxUtils::getBlastFBXUnit()); + mScene->GetGlobalSettings().SetOriginalUpAxis(FbxUtils::getBlastFBXAxisSystem()); + mScene->GetGlobalSettings().SetOriginalSystemUnit(FbxUtils::getBlastFBXUnit()); + + //We don't actually check for membership in this layer, but it's useful to show and hide the geo to look at the collision geo + mRenderLayer = FbxDisplayLayer::Create(mScene, FbxUtils::getRenderGeometryLayerName().c_str()); + mRenderLayer->Show.Set(true); + mRenderLayer->Color.Set(FbxDouble3(0.0f, 1.0f, 0.0f)); +} + +void FbxFileWriter::release() +{ + //sdkManager->Destroy(); + delete this; +} + +FbxScene* FbxFileWriter::getScene() +{ + return mScene; +} + + +void FbxFileWriter::createMaterials(const ExporterMeshData& aResult) +{ + mMaterials.clear(); + + for (uint32_t i = 0; i < aResult.submeshCount; ++i) + { + FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager.get(), aResult.submeshNames[i]); + material->Diffuse.Set(FbxDouble3(float(rand()) / RAND_MAX , float(rand()) / RAND_MAX, float(rand()) / RAND_MAX)); + material->DiffuseFactor.Set(1.0); + mMaterials.push_back(material); + } +} + +void FbxFileWriter::createMaterials(const AuthoringResult& aResult) +{ + mMaterials.clear(); + for (uint32_t i = 0; i < aResult.materialCount; ++i) + { + FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager.get(), aResult.materialNames[i]); + material->Diffuse.Set(FbxDouble3(float(rand()) / RAND_MAX, float(rand()) / RAND_MAX, float(rand()) / RAND_MAX)); + material->DiffuseFactor.Set(1.0); + mMaterials.push_back(material); + } + if (mMaterials.size() == 0) + { + FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager.get(), "Base_mat"); + material->Diffuse.Set(FbxDouble3(0.3, 1.0, 0)); + material->DiffuseFactor.Set(1.0); + mMaterials.push_back(material); + } + FbxSurfacePhong* interiorMat = FbxSurfacePhong::Create(sdkManager.get(), "Interior_Material"); + interiorMat->Diffuse.Set(FbxDouble3(1.0, 0.0, 0.5)); + interiorMat->DiffuseFactor.Set(1.0); + mMaterials.push_back(interiorMat); +} + + +bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* assetName, bool nonSkinned) +{ + createMaterials(aResult); + + if (nonSkinned) + { + return appendNonSkinnedMesh(aResult, assetName); + } + std::string meshName(assetName); meshName.append("_rendermesh"); + + FbxMesh* mesh = FbxMesh::Create(sdkManager.get(), meshName.c_str()); + + FbxGeometryElementNormal* geNormal = mesh->CreateElementNormal(); + geNormal->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geNormal->SetReferenceMode(FbxGeometryElement::eDirect); + + FbxGeometryElementUV* geUV = mesh->CreateElementUV("diffuseElement"); + geUV->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geUV->SetReferenceMode(FbxGeometryElement::eDirect); + + FbxGeometryElementSmoothing* smElement = nullptr; + size_t triangleCount = aResult.geometryOffset[aResult.chunkCount]; + + for (size_t triangle = 0; triangle < triangleCount; triangle++) + { + if (aResult.geometry[triangle].smoothingGroup >= 0) + { + //Found a valid smoothing group + smElement = mesh->CreateElementSmoothing(); + smElement->SetMappingMode(FbxGeometryElement::eByPolygon); + smElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + break; + } + } + + mesh->InitControlPoints((int)triangleCount * 3); + + + FbxNode* meshNode = FbxNode::Create(mScene, assetName); + meshNode->SetNodeAttribute(mesh); + meshNode->SetShadingMode(FbxNode::eTextureShading); + + mRenderLayer->AddMember(meshNode); + + for (uint32_t i = 0; i < mMaterials.size(); ++i) + { + meshNode->AddMaterial(mMaterials[i]); + } + + FbxNode* lRootNode = mScene->GetRootNode(); + + //In order for Maya to correctly convert the axis of a skinned model there must be a common root node between the skeleton and the model + FbxNode* sceneRootNode = FbxNode::Create(sdkManager.get(), "sceneRoot"); + lRootNode->AddChild(sceneRootNode); + sceneRootNode->AddChild(meshNode); + + //UE4 cannot hide the root bone, so add a dummy chunk so chunk0 is not the root + FbxNode* skelRootNode = FbxNode::Create(sdkManager.get(), "root"); + FbxSkeleton* skelAttrib = FbxSkeleton::Create(sdkManager.get(), "SkelRootAttrib"); + skelAttrib->SetSkeletonType(FbxSkeleton::eRoot); + skelRootNode->SetNodeAttribute(skelAttrib); + + sceneRootNode->AddChild(skelRootNode); + + FbxSkin* skin = FbxSkin::Create(sdkManager.get(), "Skin of the thing"); + skin->SetGeometry(mesh); + mesh->AddDeformer(skin); + + // Add a material otherwise UE4 freaks out on import + + FbxGeometryElementMaterial* matElement = mesh->CreateElementMaterial(); + matElement->SetMappingMode(FbxGeometryElement::eByPolygon); + matElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + + // Now walk the tree and create a skeleton with geometry at the same time + // Find a "root" chunk and walk the tree from there. + uint32_t chunkCount = aResult.chunkCount; + auto chunks = aResult.chunkDescs; + + uint32_t cpIdx = 0; + for (uint32_t i = 0; i < chunkCount; i++) + { + auto& chunk = chunks[i]; + + if (chunk.parentChunkIndex == UINT32_MAX) + { + uint32_t addedCps = createChunkRecursive(cpIdx, i, meshNode, skelRootNode, skin, aResult); + cpIdx += addedCps; + } + } + + if (!smElement) + { + //If no smoothing groups, generate them + FbxGeometryConverter fbxConv(mesh->GetFbxManager()); + if (fbxConv.ComputeEdgeSmoothingFromNormals(mesh)) + { + fbxConv.ComputePolygonSmoothingFromEdgeSmoothing(mesh, 0); + } + } + + if (aResult.collisionHull != nullptr) + { + return appendCollisionMesh(chunkCount, aResult.collisionHullOffset, aResult.collisionHull, assetName); + } + + return true; +}; + + +bool FbxFileWriter::appendNonSkinnedMesh(const AuthoringResult& aResult, const char* assetName) +{ + FbxNode* lRootNode = mScene->GetRootNode(); + + //UE4 cannot hide the root bone, so add a dummy chunk so chunk0 is not the root + FbxNode* skelRootNode = FbxNode::Create(sdkManager.get(), "root"); + //UE4 needs this to be a skeleton node, null node, or mesh node to get used + FbxNull* nullAttr = FbxNull::Create(sdkManager.get(), "SkelRootAttrib"); + skelRootNode->SetNodeAttribute(nullAttr); + lRootNode->AddChild(skelRootNode); + + // Now walk the tree and create a skeleton with geometry at the same time + // Find a "root" chunk and walk the tree from there. + uint32_t chunkCount = aResult.chunkCount; + + auto chunks = aResult.chunkDescs; + + for (uint32_t i = 0; i < chunkCount; i++) + { + auto& chunk = chunks[i]; + + if (chunk.parentChunkIndex == UINT32_MAX) + { + createChunkRecursiveNonSkinned(assetName, i, skelRootNode, mMaterials, aResult); + } + } + + if (aResult.collisionHull != nullptr) + { + return appendCollisionMesh(chunkCount, aResult.collisionHullOffset, aResult.collisionHull, assetName); + } + + return true; +} + + +bool FbxFileWriter::appendNonSkinnedMesh(const ExporterMeshData& meshData, const char* assetName) +{ + FbxNode* lRootNode = mScene->GetRootNode(); + + //UE4 cannot hide the root bone, so add a dummy chunk so chunk0 is not the root + FbxNode* skelRootNode = FbxNode::Create(sdkManager.get(), "root"); + //UE4 needs this to be a skeleton node, null node, or mesh node to get used + FbxNull* nullAttr = FbxNull::Create(sdkManager.get(), "SkelRootAttrib"); + skelRootNode->SetNodeAttribute(nullAttr); + lRootNode->AddChild(skelRootNode); + + // Now walk the tree and create a skeleton with geometry at the same time + // Find a "root" chunk and walk the tree from there. + uint32_t chunkCount = NvBlastAssetGetChunkCount(meshData.asset, Nv::Blast::logLL); + + auto chunks = NvBlastAssetGetChunks(meshData.asset, Nv::Blast::logLL); + + for (uint32_t i = 0; i < chunkCount; i++) + { + const NvBlastChunk* chunk = &chunks[i]; + + if (chunk->parentChunkIndex == UINT32_MAX) + { + createChunkRecursiveNonSkinned("chunk", i, skelRootNode, mMaterials, meshData); + } + } + if (meshData.hulls != nullptr) + { + return appendCollisionMesh(chunkCount, meshData.hullsOffsets, meshData.hulls, assetName); + } + return true; +} + +bool FbxFileWriter::appendCollisionMesh(uint32_t meshCount, uint32_t* offsets, CollisionHull** hulls, const char* assetName) +{ + FbxDisplayLayer* displayLayer = FbxDisplayLayer::Create(mScene, FbxUtils::getCollisionGeometryLayerName().c_str()); + //Hide by default + displayLayer->Show.Set(false); + displayLayer->Color.Set(FbxDouble3(0.0f, 0.0f, 1.0f)); + + // Now walk the tree and create a skeleton with geometry at the same time + // Find a "root" chunk and walk the tree from there. + + for (uint32_t i = 0; i < meshCount; i++) + { + auto findIt = chunkNodes.find(i); + if (findIt == chunkNodes.end()) + { + std::cerr << "Warning: No chunk node for chunk " << i << ". Ignoring collision geo" << std::endl; + continue; + } + addCollisionHulls(i, displayLayer, findIt->second, offsets[i+1] - offsets[i], hulls + offsets[i]); + } + return true; +} + +/* + Recursive method that creates this chunk and all it's children. + + This creates a FbxNode with an FbxCluster, and all of the geometry for this chunk. + + Returns the number of added control points +*/ +uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chunkIndex, FbxNode *meshNode, FbxNode* parentNode, FbxSkin* skin, const AuthoringResult& aResult) +{ + + auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL); + const NvBlastChunk* chunk = &chunks[chunkIndex]; + physx::PxVec3 centroid = physx::PxVec3(chunk->centroid[0], chunk->centroid[1], chunk->centroid[2]); + + //mesh->InitTextureUV(triangles.size() * 3); + + std::string boneName = FbxUtils::getChunkNodeName(chunkIndex); + + FbxSkeleton* skelAttrib = FbxSkeleton::Create(sdkManager.get(), boneName.c_str()); + if (chunk->parentChunkIndex == UINT32_MAX) + { + skelAttrib->SetSkeletonType(FbxSkeleton::eRoot); + + // Change the centroid to origin + centroid = physx::PxVec3(0.0f); + } + else + { + skelAttrib->SetSkeletonType(FbxSkeleton::eLimbNode); + worldChunkPivots[chunkIndex] = centroid; + } + + skelAttrib->Size.Set(1.0); // What's this for? + + + FbxNode* boneNode = FbxNode::Create(sdkManager.get(), boneName.c_str()); + boneNode->SetNodeAttribute(skelAttrib); + + chunkNodes[chunkIndex] = boneNode; + + auto mat = parentNode->EvaluateGlobalTransform().Inverse(); + + FbxVector4 vec(0, 0, 0, 0); + FbxVector4 c2 = mat.MultT(vec); + + boneNode->LclTranslation.Set(c2); + + parentNode->AddChild(boneNode); + + std::ostringstream namestream; + namestream << "cluster_" << std::setw(5) << std::setfill('0') << chunkIndex; + std::string clusterName = namestream.str(); + + FbxCluster* cluster = FbxCluster::Create(sdkManager.get(), clusterName.c_str()); + cluster->SetTransformMatrix(FbxAMatrix()); + cluster->SetLink(boneNode); + cluster->SetLinkMode(FbxCluster::eTotalOne); + + skin->AddCluster(cluster); + + FbxMesh* mesh = static_cast<FbxMesh*>(meshNode->GetNodeAttribute()); + + FbxVector4* controlPoints = mesh->GetControlPoints(); + auto geNormal = mesh->GetElementNormal(); + auto geUV = mesh->GetElementUV("diffuseElement"); + FbxGeometryElementMaterial* matElement = mesh->GetElementMaterial(); + FbxGeometryElementSmoothing* smElement = mesh->GetElementSmoothing(); + + auto addVert = [&](Nv::Blast::Vertex vert, int controlPointIdx) + { + FbxVector4 vertex; + FbxVector4 normal; + FbxVector2 uv; + + FbxUtils::VertexToFbx(vert, vertex, normal, uv); + + controlPoints[controlPointIdx] = vertex; + geNormal->GetDirectArray().Add(normal); + geUV->GetDirectArray().Add(uv); + // Add this control point to the bone with weight 1.0 + cluster->AddControlPointIndex(controlPointIdx, 1.0); + }; + + uint32_t cpIdx = 0; + uint32_t polyCount = mesh->GetPolygonCount(); + for (uint32_t i = aResult.geometryOffset[chunkIndex]; i < aResult.geometryOffset[chunkIndex + 1]; i++) + { + Triangle& tri = aResult.geometry[i]; + addVert(tri.a, currentCpIdx + cpIdx + 0); + addVert(tri.b, currentCpIdx + cpIdx + 1); + addVert(tri.c, currentCpIdx + cpIdx + 2); + + mesh->BeginPolygon(); + mesh->AddPolygon(currentCpIdx + cpIdx + 0); + mesh->AddPolygon(currentCpIdx + cpIdx + 1); + mesh->AddPolygon(currentCpIdx + cpIdx + 2); + mesh->EndPolygon(); + int32_t material = (tri.materialId != MATERIAL_INTERIOR) ? ((tri.materialId < int32_t(mMaterials.size() - 1)) ? tri.materialId : 0) : int32_t(mMaterials.size() - 1); + matElement->GetIndexArray().SetAt(polyCount, material); + if (smElement) + { + if (tri.userData == 0) + { + smElement->GetIndexArray().SetAt(polyCount, tri.smoothingGroup); + } + else + { + smElement->GetIndexArray().SetAt(polyCount, SMOOTHING_GROUP_INTERIOR); + } + } + + polyCount++; + cpIdx += 3; + } + + mat = meshNode->EvaluateGlobalTransform(); + cluster->SetTransformMatrix(mat); + + mat = boneNode->EvaluateGlobalTransform(); + cluster->SetTransformLinkMatrix(mat); + + uint32_t addedCps = static_cast<uint32_t>((aResult.geometryOffset[chunkIndex + 1] - aResult.geometryOffset[chunkIndex]) * 3); + + for (uint32_t i = chunk->firstChildIndex; i < chunk->childIndexStop; i++) + { + addedCps += createChunkRecursive(currentCpIdx + addedCps, i, meshNode, boneNode, skin, aResult); + } + + return addedCps; +} + + +void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, uint32_t chunkIndex, FbxNode* parentNode, + const std::vector<FbxSurfaceMaterial*>& materials, const ExporterMeshData& meshData) +{ + auto chunks = NvBlastAssetGetChunks(meshData.asset, Nv::Blast::logLL); + const NvBlastChunk* chunk = &chunks[chunkIndex]; + physx::PxVec3 centroid = physx::PxVec3(chunk->centroid[0], chunk->centroid[1], chunk->centroid[2]); + + std::string chunkName = FbxUtils::getChunkNodeName(chunkIndex); + + FbxMesh* mesh = FbxMesh::Create(sdkManager.get(), (chunkName + "_mesh").c_str()); + + FbxNode* meshNode = FbxNode::Create(mScene, chunkName.c_str()); + meshNode->SetNodeAttribute(mesh); + meshNode->SetShadingMode(FbxNode::eTextureShading); + mRenderLayer->AddMember(meshNode); + + chunkNodes[chunkIndex] = meshNode; + + auto mat = parentNode->EvaluateGlobalTransform().Inverse(); + + FbxVector4 c2 = mat.MultT(FbxVector4(centroid.x, centroid.y, centroid.z, 1.0f)); + if (chunk->parentChunkIndex != UINT32_MAX) + { + //Don't mess with the root chunk pivot + meshNode->LclTranslation.Set(c2); + worldChunkPivots[chunkIndex] = centroid; + } + + parentNode->AddChild(meshNode); + FbxAMatrix finalXForm = meshNode->EvaluateGlobalTransform(); + + //Set the geo transform to inverse so we can use the world mesh coordinates + FbxAMatrix invFinalXForm = finalXForm.Inverse(); + meshNode->SetGeometricTranslation(FbxNode::eSourcePivot, invFinalXForm.GetT()); + meshNode->SetGeometricRotation(FbxNode::eSourcePivot, invFinalXForm.GetR()); + meshNode->SetGeometricScaling(FbxNode::eSourcePivot, invFinalXForm.GetS()); + + auto geNormal = mesh->CreateElementNormal(); + auto geUV = mesh->CreateElementUV("diffuseElement"); + auto matr = mesh->CreateElementMaterial(); + + uint32_t* firstIdx = meshData.submeshOffsets + chunkIndex * meshData.submeshCount; + uint32_t* lastIdx = meshData.submeshOffsets + (chunkIndex + 1) * meshData.submeshCount; + uint32_t cpCount = *lastIdx - *firstIdx; + mesh->InitControlPoints(cpCount); + + geNormal->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geNormal->SetReferenceMode(FbxGeometryElement::eDirect); + + geUV->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geUV->SetReferenceMode(FbxGeometryElement::eDirect); + + matr->SetMappingMode(FbxGeometryElement::eByPolygon); + matr->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + + for (auto m : materials) + { + meshNode->AddMaterial(m); + } + + uint32_t cPolygCount = 0; + int32_t addedVertices = 0; + + for (uint32_t subMesh = 0; subMesh < meshData.submeshCount; ++subMesh) + { + for (uint32_t tr = *(firstIdx + subMesh); tr < *(firstIdx + subMesh + 1); tr += 3) + { + mesh->BeginPolygon(subMesh); + for (uint32_t k = 0; k < 3; ++k) + { + mesh->AddPolygon(tr - *firstIdx + k); + + FbxVector4 temp; + FbxUtils::PxVec3ToFbx(meshData.positions[meshData.posIndex[tr + k]], temp); + mesh->SetControlPointAt(temp, tr - *firstIdx + k); + + FbxUtils::PxVec3ToFbx(meshData.normals[meshData.normIndex[tr + k]], temp); + geNormal->GetDirectArray().Add(temp); + + FbxVector2 temp2; + FbxUtils::PxVec2ToFbx(meshData.uvs[meshData.texIndex[tr + k]], temp2); + geUV->GetDirectArray().Add(temp2); + } + mesh->EndPolygon(); + cPolygCount++; + addedVertices += 3; + } + } + + if (!mesh->GetElementSmoothing()) + { + //If no smoothing groups, generate them + FbxGeometryConverter fbxConv(mesh->GetFbxManager()); + if (fbxConv.ComputeEdgeSmoothingFromNormals(mesh)) + { + fbxConv.ComputePolygonSmoothingFromEdgeSmoothing(mesh, 0); + } + } + + for (uint32_t i = chunk->firstChildIndex; i < chunk->childIndexStop; i++) + { + createChunkRecursiveNonSkinned(meshName, i, meshNode, materials, meshData); + } +} + + +void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, uint32_t chunkIndex, FbxNode* parentNode, const std::vector<FbxSurfaceMaterial*>& materials, const AuthoringResult& aResult) +{ + auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL); + const NvBlastChunk* chunk = &chunks[chunkIndex]; + physx::PxVec3 centroid = physx::PxVec3(chunk->centroid[0], chunk->centroid[1], chunk->centroid[2]); + + std::string chunkName = FbxUtils::getChunkNodeName(chunkIndex).c_str(); + + FbxMesh* mesh = FbxMesh::Create(sdkManager.get(), (chunkName + "_mesh").c_str()); + + FbxNode* meshNode = FbxNode::Create(mScene, chunkName.c_str()); + meshNode->SetNodeAttribute(mesh); + meshNode->SetShadingMode(FbxNode::eTextureShading); + mRenderLayer->AddMember(meshNode); + + chunkNodes[chunkIndex] = meshNode; + + auto mat = parentNode->EvaluateGlobalTransform().Inverse(); + + FbxVector4 c2 = mat.MultT(FbxVector4(centroid.x, centroid.y, centroid.z, 1.0f)); + + if (chunk->parentChunkIndex != UINT32_MAX) + { + //Don't mess with the root chunk pivot + meshNode->LclTranslation.Set(c2); + worldChunkPivots[chunkIndex] = centroid; + } + + parentNode->AddChild(meshNode); + FbxAMatrix finalXForm = meshNode->EvaluateGlobalTransform(); + + //Set the geo transform to inverse so we can use the world mesh coordinates + FbxAMatrix invFinalXForm = finalXForm.Inverse(); + meshNode->SetGeometricTranslation(FbxNode::eSourcePivot, invFinalXForm.GetT()); + meshNode->SetGeometricRotation(FbxNode::eSourcePivot, invFinalXForm.GetR()); + meshNode->SetGeometricScaling(FbxNode::eSourcePivot, invFinalXForm.GetS()); + + + auto geNormal = mesh->CreateElementNormal(); + auto geUV = mesh->CreateElementUV("diffuseElement"); + auto matr = mesh->CreateElementMaterial(); + + uint32_t firstIdx = aResult.geometryOffset[chunkIndex]; + uint32_t lastIdx = aResult.geometryOffset[chunkIndex + 1]; + + FbxGeometryElementSmoothing* smElement = nullptr; + for (uint32_t triangle = firstIdx; triangle < lastIdx; triangle++) + { + if (aResult.geometry[triangle].smoothingGroup >= 0) + { + //Found a valid smoothing group + smElement = mesh->CreateElementSmoothing(); + smElement->SetMappingMode(FbxGeometryElement::eByPolygon); + smElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + break; + } + } + + mesh->InitControlPoints((int)(lastIdx - firstIdx) * 3); + + geNormal->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geNormal->SetReferenceMode(FbxGeometryElement::eDirect); + + geUV->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geUV->SetReferenceMode(FbxGeometryElement::eDirect); + + matr->SetMappingMode(FbxGeometryElement::eByPolygon); + matr->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + + for (auto m : materials) + { + meshNode->AddMaterial(m); + } + + FbxGeometryElementMaterial* matElement = mesh->GetElementMaterial(); + int32_t polyCount = 0; + for (uint32_t tr = firstIdx; tr < lastIdx; tr++) + { + auto& geo = aResult.geometry[tr]; + const Nv::Blast::Vertex triVerts[3] = { geo.a, geo.b, geo.c }; + mesh->BeginPolygon(); + for (uint32_t k = 0; k < 3; ++k) + { + mesh->AddPolygon(tr * 3 + k); + FbxVector4 v, n; + FbxVector2 uv; + FbxUtils::VertexToFbx(triVerts[k], v, n, uv); + mesh->SetControlPointAt(v, tr * 3 + k); + + geNormal->GetDirectArray().Add(n); + geUV->GetDirectArray().Add(uv); + } + mesh->EndPolygon(); + int32_t material = (geo.materialId != MATERIAL_INTERIOR) ? ((geo.materialId < int32_t(mMaterials.size() - 1))? geo.materialId : 0) : int32_t(mMaterials.size() - 1); + matElement->GetIndexArray().SetAt(polyCount, material); + + if (smElement) + { + if (geo.userData == 0) + { + smElement->GetIndexArray().SetAt(polyCount, geo.smoothingGroup); + } + else + { + smElement->GetIndexArray().SetAt(polyCount, SMOOTHING_GROUP_INTERIOR); + } + } + + polyCount++; + + } + + if (!smElement) + { + //If no smoothing groups, generate them + FbxGeometryConverter fbxConv(mesh->GetFbxManager()); + if (fbxConv.ComputeEdgeSmoothingFromNormals(mesh)) + { + fbxConv.ComputePolygonSmoothingFromEdgeSmoothing(mesh, 0); + } + } + + for (uint32_t i = chunk->firstChildIndex; i < chunk->childIndexStop; i++) + { + createChunkRecursiveNonSkinned(meshName, i, meshNode, materials, aResult); + } +} + +uint32_t FbxFileWriter::addCollisionHulls(uint32_t chunkIndex, FbxDisplayLayer* displayLayer, FbxNode* parentNode, uint32_t hullsCount, CollisionHull** hulls) +{ + for (uint32_t hullId = 0; hullId < hullsCount; ++hullId) + { + std::stringstream namestream; + namestream.clear(); + namestream << "collisionHull_" << chunkIndex << "_" << hullId; + + FbxNode* collisionNode = FbxNode::Create(sdkManager.get(), namestream.str().c_str()); + + displayLayer->AddMember(collisionNode); + + //TODO: Remove this when tools are converted over + FbxProperty::Create(collisionNode, FbxIntDT, "ParentalChunkIndex"); + collisionNode->FindProperty("ParentalChunkIndex").Set(chunkIndex); + // + + namestream.clear(); + namestream << "collisionHullGeom_" << chunkIndex << "_" << hullId; + FbxMesh* meshAttr = FbxMesh::Create(sdkManager.get(), namestream.str().c_str()); + collisionNode->SetNodeAttribute(meshAttr); + parentNode->AddChild(collisionNode); + + auto mat = parentNode->EvaluateGlobalTransform().Inverse(); + auto centroid = worldChunkPivots.find(chunkIndex); + + if (centroid != worldChunkPivots.end()) + { + FbxVector4 c2 = mat.MultT(FbxVector4(centroid->second.x, centroid->second.y, centroid->second.z, 1.0f)); + //Don't mess with the root chunk pivot + collisionNode->LclTranslation.Set(c2); + } + parentNode->AddChild(collisionNode); + FbxAMatrix finalXForm = collisionNode->EvaluateGlobalTransform(); + + //Set the geo transform to inverse so we can use the world mesh coordinates + FbxAMatrix invFinalXForm = finalXForm.Inverse(); + collisionNode->SetGeometricTranslation(FbxNode::eSourcePivot, invFinalXForm.GetT()); + collisionNode->SetGeometricRotation(FbxNode::eSourcePivot, invFinalXForm.GetR()); + collisionNode->SetGeometricScaling(FbxNode::eSourcePivot, invFinalXForm.GetS()); + + + meshAttr->InitControlPoints(hulls[hullId]->pointsCount); + meshAttr->CreateElementNormal(); + FbxVector4* controlPoints = meshAttr->GetControlPoints(); + auto geNormal = meshAttr->GetElementNormal(); + geNormal->SetMappingMode(FbxGeometryElement::eByPolygon); + geNormal->SetReferenceMode(FbxGeometryElement::eDirect); + for (uint32_t i = 0; i < hulls[hullId]->pointsCount; ++i) + { + auto& pnts = hulls[hullId]->points[i]; + controlPoints->Set(pnts.x, pnts.y, pnts.z, 0.0); + controlPoints++; + } + + for (uint32_t i = 0; i < hulls[hullId]->polygonDataCount; ++i) + { + auto& poly = hulls[hullId]->polygonData[i]; + meshAttr->BeginPolygon(); + for (uint32_t j = 0; j < poly.mNbVerts; ++j) + { + meshAttr->AddPolygon(hulls[hullId]->indices[poly.mIndexBase + j]); + } + meshAttr->EndPolygon(); + FbxVector4 plane(poly.mPlane[0], poly.mPlane[1], poly.mPlane[2], 0); + geNormal->GetDirectArray().Add(plane); + } + } + return 1; +} + +uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chunkIndex, FbxNode *meshNode, FbxNode* parentNode, FbxSkin* skin, const ExporterMeshData& meshData) +{ + auto chunks = NvBlastAssetGetChunks(meshData.asset, Nv::Blast::logLL); + const NvBlastChunk* chunk = &chunks[chunkIndex]; + physx::PxVec3 centroid = physx::PxVec3(chunk->centroid[0], chunk->centroid[1], chunk->centroid[2]); + + std::string boneName = FbxUtils::getChunkNodeName(chunkIndex).c_str(); + + FbxSkeleton* skelAttrib = FbxSkeleton::Create(sdkManager.get(), boneName.c_str()); + if (chunk->parentChunkIndex == UINT32_MAX) + { + skelAttrib->SetSkeletonType(FbxSkeleton::eRoot); + + // Change the centroid to origin + centroid = physx::PxVec3(0.0f); + } + else + { + skelAttrib->SetSkeletonType(FbxSkeleton::eLimbNode); + worldChunkPivots[chunkIndex] = centroid; + } + + FbxNode* boneNode = FbxNode::Create(sdkManager.get(), boneName.c_str()); + boneNode->SetNodeAttribute(skelAttrib); + + chunkNodes[chunkIndex] = boneNode; + + auto mat = parentNode->EvaluateGlobalTransform().Inverse(); + + FbxVector4 vec(0, 0, 0, 0); + FbxVector4 c2 = mat.MultT(vec); + + boneNode->LclTranslation.Set(c2); + + parentNode->AddChild(boneNode); + + std::ostringstream namestream; + namestream << "cluster_" << std::setw(5) << std::setfill('0') << chunkIndex; + std::string clusterName = namestream.str(); + + FbxCluster* cluster = FbxCluster::Create(sdkManager.get(), clusterName.c_str()); + cluster->SetTransformMatrix(FbxAMatrix()); + cluster->SetLink(boneNode); + cluster->SetLinkMode(FbxCluster::eTotalOne); + + skin->AddCluster(cluster); + + FbxMesh* mesh = static_cast<FbxMesh*>(meshNode->GetNodeAttribute()); + + auto geNormal = mesh->GetElementNormal(); + auto geUV = mesh->GetElementUV("diffuseElement"); + auto matr = mesh->GetElementMaterial(); + + std::vector<bool> addedVerticesFlag(mesh->GetControlPointsCount(), false); + + uint32_t* firstIdx = meshData.submeshOffsets + chunkIndex * meshData.submeshCount; + uint32_t cPolygCount = mesh->GetPolygonCount(); + int32_t addedVertices = 0; + for (uint32_t subMesh = 0; subMesh < meshData.submeshCount; ++subMesh) + { + for (uint32_t tr = *(firstIdx + subMesh); tr < *(firstIdx + subMesh + 1); tr += 3) + { + mesh->BeginPolygon(subMesh); + mesh->AddPolygon(meshData.posIndex[tr + 0]); + mesh->AddPolygon(meshData.posIndex[tr + 1]); + mesh->AddPolygon(meshData.posIndex[tr + 2]); + mesh->EndPolygon(); + for (uint32_t k = 0; k < 3; ++k) + { + geNormal->GetIndexArray().SetAt(currentCpIdx + addedVertices + k, meshData.normIndex[tr + k]); + geUV->GetIndexArray().SetAt(currentCpIdx + addedVertices + k, meshData.texIndex[tr + k]); + } + if (subMesh == 0) + { + matr->GetIndexArray().SetAt(cPolygCount, 0); + } + else + { + matr->GetIndexArray().SetAt(cPolygCount, 1); + } + cPolygCount++; + addedVertices += 3; + for (uint32_t k = 0; k < 3; ++k) + { + if (!addedVerticesFlag[meshData.posIndex[tr + k]]) + { + cluster->AddControlPointIndex(meshData.posIndex[tr + k], 1.0); + addedVerticesFlag[meshData.posIndex[tr + k]] = true; + } + } + } + } + mat = meshNode->EvaluateGlobalTransform(); + cluster->SetTransformMatrix(mat); + + mat = boneNode->EvaluateGlobalTransform(); + cluster->SetTransformLinkMatrix(mat); + + + for (uint32_t i = chunk->firstChildIndex; i < chunk->childIndexStop; i++) + { + addedVertices += createChunkRecursive(currentCpIdx + addedVertices, i, meshNode, boneNode, skin, meshData); + } + + return addedVertices; + +} + +void FbxFileWriter::addControlPoints(FbxMesh* mesh, const ExporterMeshData& meshData) +{ + std::vector<uint32_t> vertices; + std::cout << "Adding control points" << std::endl; + std::vector<int32_t> mapping(meshData.positionsCount, -1); + for (uint32_t ch = 0; ch < meshData.meshCount; ++ch) + { + mapping.assign(meshData.positionsCount, -1); + for (uint32_t sb = 0; sb < meshData.submeshCount; ++sb) + { + uint32_t* first = meshData.submeshOffsets + ch * meshData.submeshCount + sb; + for (uint32_t pi = *first; pi < *(first+1); ++pi) + { + uint32_t p = meshData.posIndex[pi]; + if (mapping[p] == -1) + { + mapping[p] = (int)vertices.size(); + vertices.push_back(p); + meshData.posIndex[pi] = mapping[p]; + } + else + { + meshData.posIndex[pi] = mapping[p]; + } + } + } + } + mesh->InitControlPoints((int)vertices.size()); + FbxVector4* controlPoints = mesh->GetControlPoints(); + for (auto v : vertices) + { + auto& p = meshData.positions[v]; + *controlPoints = FbxVector4(p.x, p.y, p.z, 0); + ++controlPoints; + } + std::cout << "Adding control points: done" << std::endl; +} + +void FbxFileWriter::addBindPose() +{ + // Store the bind pose + //Just add all the nodes, it doesn't seem to do any harm and it stops Maya complaining about incomplete bind poses + FbxPose* pose = FbxPose::Create(sdkManager.get(), "BindPose"); + pose->SetIsBindPose(true); + + int nodeCount = mScene->GetNodeCount(); + for (int i = 0; i < nodeCount; i++) + { + FbxNode* node = mScene->GetNode(i); + FbxMatrix bindMat = node->EvaluateGlobalTransform(); + + pose->Add(node, bindMat); + } + + mScene->AddPose(pose); +} + +bool FbxFileWriter::saveToFile(const char* assetName, const char* outputPath) +{ + + addBindPose(); + + FbxIOSettings* ios = FbxIOSettings::Create(sdkManager.get(), IOSROOT); + // Set some properties on the io settings + + sdkManager->SetIOSettings(ios); + + sdkManager->GetIOSettings()->SetBoolProp(EXP_ASCIIFBX, bOutputFBXAscii); + + + FbxExporter* exporter = FbxExporter::Create(sdkManager.get(), "Scene Exporter"); + exporter->SetFileExportVersion(FBX_2012_00_COMPATIBLE); + + int lFormat; + + if (bOutputFBXAscii) + { + lFormat = sdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX ascii (*.fbx)"); + } + else + { + lFormat = sdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX binary (*.fbx)"); + } + + auto path = std::string(outputPath) + "\\" + assetName + ".fbx"; + bool exportStatus = exporter->Initialize(path.c_str(), lFormat, sdkManager->GetIOSettings()); + + if (!exportStatus) + { + std::cerr << "Call to FbxExporter::Initialize failed" << std::endl; + std::cerr << "Error returned: " << exporter->GetStatus().GetErrorString() << std::endl; + return false; + } + + exportStatus = exporter->Export(mScene); + + if (!exportStatus) + { + auto fbxStatus = exporter->GetStatus(); + + std::cerr << "Call to FbxExporter::Export failed" << std::endl; + std::cerr << "Error returned: " << fbxStatus.GetErrorString() << std::endl; + return false; + } + return true; +} + + + +bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* assetName, bool nonSkinned) +{ + createMaterials(meshData); + + if (nonSkinned) + { + return appendNonSkinnedMesh(meshData, assetName); + } + + /** + Get polygon count + */ + uint32_t polygCount = meshData.submeshOffsets[meshData.meshCount * meshData.submeshCount] / 3; + + FbxMesh* mesh = FbxMesh::Create(sdkManager.get(), "meshgeo"); + + FbxGeometryElementNormal* geNormal = mesh->CreateElementNormal(); + geNormal->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geNormal->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + + FbxGeometryElementUV* geUV = mesh->CreateElementUV("diffuseElement"); + geUV->SetMappingMode(FbxGeometryElement::eByPolygonVertex); + geUV->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + + + FbxNode* meshNode = FbxNode::Create(mScene, "meshnode"); + meshNode->SetNodeAttribute(mesh); + meshNode->SetShadingMode(FbxNode::eTextureShading); + + FbxNode* lRootNode = mScene->GetRootNode(); + + mRenderLayer->AddMember(meshNode); + + for (uint32_t i = 0; i < mMaterials.size(); ++i) + { + meshNode->AddMaterial(mMaterials[i]); + } + + FbxSkin* skin = FbxSkin::Create(sdkManager.get(), "Skin of the thing"); + skin->SetGeometry(mesh); + + mesh->AddDeformer(skin); + + /** + Create control points, copy data to buffers + */ + addControlPoints(mesh, meshData); + + auto normalsElem = mesh->GetElementNormal(); + for (uint32_t i = 0; i < meshData.normalsCount; ++i) + { + auto& n = meshData.normals[i]; + normalsElem->GetDirectArray().Add(FbxVector4(n.x, n.y, n.z, 0)); + } + auto uvsElem = mesh->GetElementUV("diffuseElement"); + for (uint32_t i = 0; i < meshData.uvsCount; ++i) + { + auto& uvs = meshData.uvs[i]; + uvsElem->GetDirectArray().Add(FbxVector2(uvs.x, uvs.y)); + } + + FbxGeometryElementMaterial* matElement = mesh->CreateElementMaterial(); + matElement->SetMappingMode(FbxGeometryElement::eByPolygon); + matElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect); + + + matElement->GetIndexArray().SetCount(polygCount); + normalsElem->GetIndexArray().SetCount(polygCount * 3); + uvsElem->GetIndexArray().SetCount(polygCount * 3); + + + std::cout << "Create chunks recursive" << std::endl; + + //In order for Maya to correctly convert the axis of a skinned model there must be a common root node between the skeleton and the model + FbxNode* sceneRootNode = FbxNode::Create(sdkManager.get(), "sceneRoot"); + lRootNode->AddChild(sceneRootNode); + sceneRootNode->AddChild(meshNode); + + //UE4 cannot hide the root bone, so add a dummy chunk so chunk0 is not the root + FbxNode* skelRootNode = FbxNode::Create(sdkManager.get(), "root"); + FbxSkeleton* skelAttrib = FbxSkeleton::Create(sdkManager.get(), "SkelRootAttrib"); + skelAttrib->SetSkeletonType(FbxSkeleton::eRoot); + skelRootNode->SetNodeAttribute(skelAttrib); + + sceneRootNode->AddChild(skelRootNode); + + // Now walk the tree and create a skeleton with geometry at the same time + // Find a "root" chunk and walk the tree from there. + uint32_t chunkCount = NvBlastAssetGetChunkCount(meshData.asset, Nv::Blast::logLL); + auto chunks = NvBlastAssetGetChunks(meshData.asset, Nv::Blast::logLL); + uint32_t cpIdx = 0; + for (uint32_t i = 0; i < chunkCount; i++) + { + const NvBlastChunk* chunk = &chunks[i]; + + if (chunk->parentChunkIndex == UINT32_MAX) + { + uint32_t addedCps = createChunkRecursive(cpIdx, i, meshNode, skelRootNode, skin, meshData); + cpIdx += addedCps; + } + } + + if (!mesh->GetElementSmoothing()) + { + //If no smoothing groups, generate them + FbxGeometryConverter fbxConv(mesh->GetFbxManager()); + if (fbxConv.ComputeEdgeSmoothingFromNormals(mesh)) + { + fbxConv.ComputePolygonSmoothingFromEdgeSmoothing(mesh, 0); + } + } + + if (meshData.hulls != nullptr) + { + return appendCollisionMesh(chunkCount, meshData.hullsOffsets, meshData.hulls, assetName); + } + return true; +} + diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h new file mode 100644 index 0000000..985b32c --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h @@ -0,0 +1,134 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTERFBXWRITER_H +#define NVBLASTEXTEXPORTERFBXWRITER_H + +#include "NvBlastExtExporter.h" +#include <memory> +#include <vector> +#include <map> + +namespace fbxsdk +{ + class FbxScene; + class FbxNode; + class FbxMesh; + class FbxSkin; + class FbxManager; + class FbxSurfaceMaterial; + class FbxDisplayLayer; +} + +struct NvBlastAsset; + +namespace Nv +{ +namespace Blast +{ +class Mesh; +struct Triangle; +struct CollisionHull; + +class FbxFileWriter : public IMeshFileWriter +{ +public: + + /** + Initialize FBX sdk and create scene. + */ + FbxFileWriter(); + //~FbxFileWriter() = default; + + virtual void release() override; + + /** + Get current scene; + */ + fbxsdk::FbxScene* getScene(); + + /** + Append rendermesh to scene. Meshes constructed from arrays of triangles. + */ + virtual bool appendMesh(const AuthoringResult& aResult, const char* assetName, bool nonSkinned) override; + + /** + Append rendermesh to scene. Meshes constructed from arrays of vertex data (position, normal, uvs) and indices. + Position, normal and uv has separate index arrays. + */ + virtual bool appendMesh(const ExporterMeshData& meshData, const char* assetName, bool nonSkinned) override; + + /** + Save scene to file. + */ + virtual bool saveToFile(const char* assetName, const char* outputPath) override; + + /** + Set true if FBX should be saved in ASCII mode. + */ + bool bOutputFBXAscii; + +private: + std::vector<fbxsdk::FbxSurfaceMaterial*> mMaterials; + fbxsdk::FbxScene* mScene; + fbxsdk::FbxDisplayLayer* mRenderLayer; + + //TODO we should track for every memory allocation and deallocate it not only for sdkManager + std::shared_ptr<fbxsdk::FbxManager> sdkManager; + std::map<uint32_t, fbxsdk::FbxNode*> chunkNodes; + std::map<uint32_t, physx::PxVec3> worldChunkPivots; + + bool appendNonSkinnedMesh(const AuthoringResult& aResult, const char* assetName); + bool appendNonSkinnedMesh(const ExporterMeshData& meshData, const char* assetName); + void createMaterials(const ExporterMeshData& meshData); + void createMaterials(const AuthoringResult& aResult); + + /** + Append collision geometry to scene. Each node with collision geometry has "ParentalChunkIndex" property, which contain index of chunk + which this collision geometry belongs to. + */ + bool appendCollisionMesh(uint32_t meshCount, uint32_t* offsets, CollisionHull** hulls, const char* assetName); + + uint32_t addCollisionHulls(uint32_t chunkIndex, fbxsdk::FbxDisplayLayer* displayLayer, fbxsdk::FbxNode* parentNode, uint32_t hullsCount, CollisionHull** hulls); + uint32_t createChunkRecursive(uint32_t currentCpIdx, uint32_t chunkIndex, fbxsdk::FbxNode *meshNode, fbxsdk::FbxNode* parentNode, fbxsdk::FbxSkin* skin, const AuthoringResult& aResult); + uint32_t createChunkRecursive(uint32_t currentCpIdx, uint32_t chunkIndex, fbxsdk::FbxNode *meshNode, fbxsdk::FbxNode* parentNode, fbxsdk::FbxSkin* skin, const ExporterMeshData& meshData); + + void createChunkRecursiveNonSkinned(const std::string& meshName, uint32_t chunkIndex, fbxsdk::FbxNode* parentNode, + const std::vector<fbxsdk::FbxSurfaceMaterial*>& materials, const AuthoringResult& aResult); + + void createChunkRecursiveNonSkinned(const std::string& meshName, uint32_t chunkIndex, fbxsdk::FbxNode* parentNode, + const std::vector<fbxsdk::FbxSurfaceMaterial*>& materials, const ExporterMeshData& meshData); + + void addControlPoints(fbxsdk::FbxMesh* mesh, const ExporterMeshData& meshData); + void addBindPose(); +}; + +} +} + +#endif // NVBLASTEXTEXPORTERFBXWRITER_H
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp new file mode 100644 index 0000000..c19c931 --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp @@ -0,0 +1,107 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtExporterJsonCollision.h" +#include "NvBlastExtAuthoringTypes.h" +#include <PxVec3.h> +#include <iostream> +#include <sstream> +#include <fstream> +#include <iomanip> + +#define JS_NAME(name) "\"" << name << "\": " + +using namespace Nv::Blast; + + +void serializaHullPolygon(std::ofstream& stream, const CollisionHull::HullPolygon& p, uint32_t indent) +{ + std::string sindent(indent, '\t'); + std::string bindent(indent + 1, '\t'); + stream << sindent << "{\n" << + bindent << JS_NAME("mIndexBase") << p.mIndexBase << ",\n" << + bindent << JS_NAME("mPlane") << "[" << p.mPlane[0] << ", " << p.mPlane[1] << ", " << p.mPlane[2] << ", " << p.mPlane[3] << "],\n" << + bindent << JS_NAME("mNbVerts") << p.mNbVerts << "\n" << + sindent << "}"; +} +void serializeCollisionHull(std::ofstream& stream, const CollisionHull& hl, uint32_t indent) +{ + std::string sindent(indent, '\t'); + std::string bindent(indent + 1, '\t'); + + stream << sindent << "{\n" << bindent << JS_NAME("indices") << "["; + for (uint32_t i = 0; i < hl.indicesCount; ++i) + { + stream << hl.indices[i]; + if (i < hl.indicesCount - 1) stream << ", "; + } + stream << "],\n"; + stream << bindent << JS_NAME("points") << "["; + for (uint32_t i = 0; i < hl.pointsCount; ++i) + { + auto& p = hl.points[i]; + stream << p.x << ", " << p.y << ", " << p.z; + if (i < hl.pointsCount - 1) stream << ", "; + } + stream << "],\n"; + stream << bindent << JS_NAME("polygonData") << "[\n"; + for (uint32_t i = 0; i < hl.polygonDataCount; ++i) + { + serializaHullPolygon(stream, hl.polygonData[i], indent + 1); + if (i < hl.polygonDataCount - 1) stream << ", "; + stream << "\n"; + } + stream << bindent << "]\n"; + stream << sindent << "}"; +} + +bool JsonCollisionExporter::writeCollision(const char* path, uint32_t meshCount, const uint32_t* meshOffsets, const CollisionHull* hulls) +{ + std::ofstream stream(path, std::ios::out); + stream << std::fixed << std::setprecision(8); + if (!stream.is_open()) + { + std::cout << "Can't open output stream" << std::endl; + return false; + } + + stream << "{\n" << "\t" << JS_NAME("CollisionData") << "[\n"; + for (uint32_t i = 0; i < meshCount; ++i) + { + stream << "\t\t" << "[\n"; + for (uint32_t j = meshOffsets[i]; j < meshOffsets[i + 1]; ++j) + { + serializeCollisionHull(stream, hulls[j], 3); + stream << ((j < meshOffsets[i + 1] - 1) ? ",\n" : "\n"); + } + stream << "\t\t" << ((i < meshCount - 1) ? "], \n" : "]\n"); + } + stream << "\t]\n}"; + stream.close(); + return true; +}; diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp new file mode 100644 index 0000000..95efb3e --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp @@ -0,0 +1,130 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtExporterObjReader.h" + +#pragma warning(push) +#pragma warning(disable:4706) +#pragma warning(disable:4702) +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" +#pragma warning(pop) + + +#include <iostream> +#include "PxVec3.h" +#include "PxVec2.h" +#include "NvBlastExtAuthoringMesh.h" + +using physx::PxVec3; +using physx::PxVec2; +using namespace Nv::Blast; + +ObjFileReader::ObjFileReader() +{ +} + +void ObjFileReader::release() +{ + delete this; +} + +void ObjFileReader::loadFromFile(const char* filename) +{ + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> mats; + std::string err; + std::string mtlPath; + bool ret = tinyobj::LoadObj(shapes, mats, err, filename); + // can't load? + if (!ret) + { + return; + } + if (shapes.size() > 1) + { + std::cout << "Can load only one object per mesh" << std::endl; + } + + mVertexPositions.clear(); + mVertexNormals.clear(); + mVertexUv.clear(); + mIndices.clear(); + + auto& psVec = shapes[0].mesh.positions; + for (uint32_t i = 0; i < psVec.size() / 3; ++i) + { + mVertexPositions.push_back(PxVec3(psVec[i * 3], psVec[i * 3 + 1], psVec[i * 3 + 2])); + } + auto& nmVec = shapes[0].mesh.normals; + for (uint32_t i = 0; i < nmVec.size() / 3; ++i) + { + mVertexNormals.push_back(PxVec3(nmVec[i * 3], nmVec[i * 3 + 1], nmVec[i * 3 + 2])); + } + auto& txVec = shapes[0].mesh.texcoords; + for (uint32_t i = 0; i < txVec.size() / 2; ++i) + { + mVertexUv.push_back(PxVec2(txVec[i * 2], txVec[i * 2 + 1])); + } + + mIndices = shapes[0].mesh.indices; + +} + + +bool ObjFileReader::isCollisionLoaded() +{ + return false; +}; + + +uint32_t ObjFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls) +{ + NV_UNUSED(hulls); + return false; +}; + +physx::PxVec3* ObjFileReader::getPositionArray() +{ + return mVertexPositions.data(); +}; + +physx::PxVec3* ObjFileReader::getNormalsArray() +{ + return mVertexNormals.data(); +}; + +physx::PxVec2* ObjFileReader::getUvArray() +{ + return mVertexUv.data(); +}; + +uint32_t* ObjFileReader::getIndexArray() +{ + return mIndices.data(); +};
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h new file mode 100644 index 0000000..f80f8f9 --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h @@ -0,0 +1,122 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTEROBJREADER_H +#define NVBLASTEXTEXPORTEROBJREADER_H +#include <memory> +#include <string> +#include <vector> +#include "NvBlastExtExporter.h" + +namespace Nv +{ +namespace Blast +{ +class Mesh; + +class ObjFileReader : public IMeshFileReader +{ +public: + ObjFileReader(); + ~ObjFileReader() = default; + + virtual void release() override; + + /* + Load from the specified file path, returning a mesh or nullptr if failed + */ + virtual void loadFromFile(const char* filename) override; + + virtual uint32_t getVerticesCount() const override + { + return mVertexPositions.size(); + } + + virtual uint32_t getIdicesCount() const override + { + return mIndices.size(); + } + + /** + Check whether file contained an collision geometry + */ + virtual bool isCollisionLoaded() override; + + /** + Retrieve collision geometry if it exist + */ + virtual uint32_t getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls) override; + + /** + Get loaded vertex positions + */ + virtual physx::PxVec3* getPositionArray() override; + /** + Get loaded vertex normals + */ + virtual physx::PxVec3* getNormalsArray() override; + /** + Get loaded vertex uv-coordinates + */ + virtual physx::PxVec2* getUvArray() override; + /** + Get loaded triangle indices + */ + virtual uint32_t* getIndexArray() override; + + /** + Get loaded per triangle material ids. Currently not supported by OBJ. + */ + int32_t* getMaterialIds() override { return nullptr; }; + + /** + Get loaded per triangle smoothing groups. Currently not supported by OBJ. + */ + int32_t* getSmoothingGroups() override { return nullptr; }; + + /** + Get material name. Currently not supported by OBJ. + */ + char* getMaterialName(int32_t id) override { return nullptr; } + + /** + Get material count. + */ + int32_t getMaterialCount() { return 0; }; + +private: + std::vector<physx::PxVec3> mVertexPositions; + std::vector<physx::PxVec3> mVertexNormals; + std::vector<physx::PxVec2> mVertexUv; + std::vector<uint32_t> mIndices; +}; + +} +} + +#endif // NVBLASTEXTEXPORTEROBJREADER_H
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp new file mode 100644 index 0000000..a49e28f --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp @@ -0,0 +1,188 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtExporterObjWriter.h" +#include <PxVec3.h> +#include <sstream> +#include "NvBlastExtAuthoringTypes.h" +#include "NvBlastExtAuthoringMesh.h" + + +using namespace physx; +using namespace Nv::Blast; + +char* gTexPath = ""; + +void ObjFileWriter::release() +{ + delete this; +} + +bool ObjFileWriter::appendMesh(const AuthoringResult& aResult, const char* /*assetName*/, bool /*nonSkinned*/) +{ + mMeshData = std::shared_ptr<ExporterMeshData>(new ExporterMeshData(), [](ExporterMeshData* md) + { + //delete[] md->hulls; + //delete[] md->hullsOffsets; + delete[] md->normals; + //delete[] md->normIndex; + delete[] md->posIndex; + delete[] md->positions; + delete[] md->submeshOffsets; + //delete[] md->texIndex; + delete[] md->submeshNames; + delete[] md->uvs; + delete md; + }); + ExporterMeshData& md = *mMeshData.get(); + uint32_t triCount = aResult.geometryOffset[aResult.chunkCount]; + md.meshCount = aResult.chunkCount; + md.submeshOffsets = new uint32_t[md.meshCount + 1]; + for (uint32_t i = 0; i < md.meshCount + 1; i++) + { + md.submeshOffsets[i] = aResult.geometryOffset[i] * 3; + } + //md.submeshOffsets = md.meshOffsets; + md.submeshCount = 1; + //md.indicesCount = triCount * 3; + md.positionsCount = triCount * 3; + md.normalsCount = md.positionsCount; + md.uvsCount = md.positionsCount; + md.positions = new PxVec3[md.positionsCount]; + md.normals = new PxVec3[md.normalsCount]; + md.uvs = new PxVec2[md.uvsCount]; + md.posIndex = new uint32_t[triCount * 3]; + md.normIndex = md.posIndex; + md.texIndex = md.posIndex; + md.submeshNames = new const char*[1]{ gTexPath }; + for (uint32_t vc = 0; vc < triCount; ++vc) + { + Triangle& tri = aResult.geometry[vc]; + uint32_t i = vc * 3; + md.positions[i+0] = tri.a.p; + md.positions[i+1] = tri.b.p; + md.positions[i+2] = tri.c.p; + + md.normals[i+0] = tri.a.n; + md.normals[i+1] = tri.b.n; + md.normals[i+2] = tri.c.n; + + md.uvs[i+0] = tri.a.uv[0]; + md.uvs[i+1] = tri.b.uv[0]; + md.uvs[i+2] = tri.c.uv[0]; + + md.posIndex[i + 0] = i + 0; + md.posIndex[i + 1] = i + 1; + md.posIndex[i + 2] = i + 2; + } + return true; +} + +bool ObjFileWriter::appendMesh(const ExporterMeshData& meshData, const char* /*assetName*/, bool /*nonSkinned*/) +{ + mMeshData = std::shared_ptr<ExporterMeshData>(new ExporterMeshData(meshData)); + return true; +} + +bool ObjFileWriter::saveToFile(const char* assetName, const char* outputPath) +{ + if (mMeshData.get() == nullptr) + { + return false; + } + const ExporterMeshData& md = *mMeshData.get(); + + uint32_t chunkCount = md.meshCount; + + // export materials (mtl file) + { + std::ostringstream mtlFilePath; + mtlFilePath << outputPath << "\\" << assetName << ".mtl"; + FILE* f = fopen(mtlFilePath.str().c_str(), "w"); + if (!f) + return false; + + for (uint32_t submeshIndex = 0; submeshIndex < md.submeshCount; ++submeshIndex) + { + fprintf(f, "newmtl mat%d\n", submeshIndex); + fprintf(f, "\tmap_Kd %s\n", md.submeshNames[submeshIndex]); + fprintf(f, "\n"); + } + + fclose(f); + } + + /// Export geometry to *.obj file + { + std::ostringstream objFilePath; + objFilePath << outputPath << "\\" << assetName << ".obj"; + FILE* f = fopen(objFilePath.str().c_str(), "w"); + if (!f) + return false; + + fprintf(f, "mtllib %s.mtl\n", assetName); + fprintf(f, "o frac \n"); + + + /// Write compressed vertices + for (uint32_t i = 0; i < md.positionsCount; ++i) + { + fprintf(f, "v %.4f %.4f %.4f\n", md.positions[i].x, md.positions[i].y, md.positions[i].z); + } + for (uint32_t i = 0; i < md.normalsCount; ++i) + { + fprintf(f, "vn %.4f %.4f %.4f\n", md.normals[i].x, md.normals[i].y, md.normals[i].z); + } + for (uint32_t i = 0; i < md.uvsCount; ++i) + { + fprintf(f, "vt %.4f %.4f\n", md.uvs[i].x, md.uvs[i].y); + } + + for (uint32_t chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex) + { + for (uint32_t submeshIndex = 0; submeshIndex < md.submeshCount; ++submeshIndex) + { + uint32_t firstIdx = md.submeshOffsets[chunkIndex * md.submeshCount + submeshIndex]; + uint32_t lastIdx = md.submeshOffsets[chunkIndex * md.submeshCount + submeshIndex + 1]; + fprintf(f, "g %d_%d \n", chunkIndex, submeshIndex); + fprintf(f, "usemtl mat%d\n", submeshIndex); + + for (uint32_t i = firstIdx; i < lastIdx; i += 3) + { + fprintf(f, "f %d/%d/%d ", md.posIndex[i] + 1, md.texIndex[i] + 1, md.normIndex[i] + 1); + fprintf(f, "%d/%d/%d ", md.posIndex[i + 1] + 1, md.texIndex[i + 1] + 1, md.normIndex[i + 1] + 1); + fprintf(f, "%d/%d/%d \n", md.posIndex[i + 2] + 1, md.texIndex[i + 2] + 1, md.normIndex[i + 2] + 1); + } + } + } + fclose(f); + } + return true; + +} + diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h new file mode 100644 index 0000000..3152d42 --- /dev/null +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.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) 2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTEXPORTEROBJWRITER_H +#define NVBLASTEXTEXPORTEROBJWRITER_H + +#include "NvBlastExtExporter.h" +#include <memory> +#include <vector> +#include <PxVec2.h> +#include <PxVec3.h> + +struct NvBlastAsset; + +namespace Nv +{ +namespace Blast +{ + +class ObjFileWriter : public IMeshFileWriter +{ +public: + + ObjFileWriter() {}; + ~ObjFileWriter() = default; + + virtual void release() override; + + virtual bool appendMesh(const AuthoringResult& aResult, const char* assetName, bool nonSkinned) override; + + /** + Append rendermesh to scene. Meshes constructed from arrays of vertices and indices + */ + virtual bool appendMesh(const ExporterMeshData& meshData, const char* assetName, bool nonSkinned) override; + + /** + Save scene to file. + */ + virtual bool saveToFile(const char* assetName, const char* outputPath) override; + +private: + std::shared_ptr<ExporterMeshData> mMeshData; +}; + +} +} + +#endif // NVBLASTEXTEXPORTEROBJWRITER_H
\ No newline at end of file diff --git a/sdk/extensions/import/include/NvBlastExtApexImportTool.h b/sdk/extensions/import/include/NvBlastExtApexImportTool.h index bbfcfce..788ec40 100644 --- a/sdk/extensions/import/include/NvBlastExtApexImportTool.h +++ b/sdk/extensions/import/include/NvBlastExtApexImportTool.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 NVBLASTEXTAPEXIMPORTTOOL_H #define NVBLASTEXTAPEXIMPORTTOOL_H @@ -18,8 +36,6 @@ namespace physx { -class PxErrorCallback; -class PxAllocatorCallback; namespace general_PxIOStream2 { class PxFileBuf; @@ -87,9 +103,8 @@ public: /** Constructor should be provided with user defined allocator and massage function: - \param[in] logFn User - supplied message function(see NvBlastLog definition).May be NULL. */ - ApexImportTool(NvBlastLog logFn = NULL); + ApexImportTool(); ~ApexImportTool(); ////////////////////////////////////////////////////////////////////////////// @@ -168,11 +183,12 @@ public: \param[in] apexChunkFlags Chunk flags array \param[out] physicsChunks Chunk physics info output array \param[out] physicsSubchunks Chunk collision geometry and transformation data output array + \param[out] hullsDescs Chunk collision geometry descriptors, can be used to save to some third party format \return If true - success, output arrays are filled. */ bool getCollisionGeometry(const nvidia::apex::DestructibleAsset* apexAsset, uint32_t chunkCount, std::vector<uint32_t>& chunkReorderInvMap, const std::vector<uint32_t>& apexChunkFlags, std::vector<ExtPxAssetDesc::ChunkDesc>& physicsChunks, - std::vector<ExtPxAssetDesc::SubchunkDesc>& physicsSubchunks); + std::vector<ExtPxAssetDesc::SubchunkDesc>& physicsSubchunks, std::vector<std::vector<CollisionHull*> >& hullsDesc); ApexDestruction* m_apexDestruction; ////////////////////////////////////////////////////////////////////////////// @@ -184,9 +200,6 @@ private: protected: - NvBlastLog m_log; - -protected: ApexImportTool(const ApexImportTool&); ApexImportTool& operator=(const ApexImportTool&); }; diff --git a/sdk/extensions/import/source/NvBlastExtApexDestruction.cpp b/sdk/extensions/import/source/NvBlastExtApexDestruction.cpp index 889a8c8..3f8451e 100644 --- a/sdk/extensions/import/source/NvBlastExtApexDestruction.cpp +++ b/sdk/extensions/import/source/NvBlastExtApexDestruction.cpp @@ -1,18 +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. + #include "NvBlastExtApexDestruction.h" #include "PxPhysicsAPI.h" #include "Apex.h" +#include "NvBlastPxCallbacks.h" #include <ModuleDestructible.h> #include <DestructibleAsset.h> #include "NullRenderer.h" @@ -23,8 +42,6 @@ using namespace apex; ////////////////////////////////////////////////////////////////////////////// -PxDefaultAllocator gPxAllocator; -PxDefaultErrorCallback gErrorCallback; NullRenderResourceManager gNullRenderer; ///////////////////////////////////////////////////////////////////////////// @@ -74,7 +91,7 @@ bool ApexDestruction::initialize() ////////////////////////////////////////////////////////////////////////////// - m_Foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, gPxAllocator, gErrorCallback)); + m_Foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, NvBlastGetPxAllocatorCallback(), NvBlastGetPxErrorCallback())); if (!m_Foundation) { if (m_log) diff --git a/sdk/extensions/import/source/NvBlastExtApexDestruction.h b/sdk/extensions/import/source/NvBlastExtApexDestruction.h index 6560aed..3a3b313 100644 --- a/sdk/extensions/import/source/NvBlastExtApexDestruction.h +++ b/sdk/extensions/import/source/NvBlastExtApexDestruction.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 NVBLASTEXTAPEXDESTRUCTION_H #define NVBLASTEXTAPEXDESTRUCTION_H diff --git a/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp b/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp index d2def6f..e0fe7bd 100644 --- a/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp +++ b/sdk/extensions/import/source/NvBlastExtApexImportTool.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 "NvBlastExtApexImportTool.h" @@ -16,19 +34,21 @@ #endif #include "PxFoundation.h" -#include "PxErrorCallback.h" -#include "PxAllocatorCallback.h" #include "NvBlastIndexFns.h" +#include "NvBlastGlobals.h" #include "DestructibleAsset.h" #include "NvBlastExtApexDestruction.h" #include <PxConvexMesh.h> #include "PxPhysics.h" #include "NvBlastExtAuthoringCollisionBuilder.h" #include "NvBlastExtPxAsset.h" -#include "NvBlastExtAuthoringTypes.h" +#include "NvBlastExtAuthoring.h" #include "NvBlastExtAuthoringBondGenerator.h" +#include <algorithm> +#include <memory> + using namespace nvidia; using namespace apex; @@ -59,8 +79,8 @@ namespace ApexImporter } }; -ApexImportTool::ApexImportTool(NvBlastLog log) - : m_apexDestruction(NULL), m_log(log) +ApexImportTool::ApexImportTool() + : m_apexDestruction(NULL) { } @@ -77,8 +97,8 @@ bool ApexImportTool::initialize() { return true; } - m_log(NvBlastMessage::Info, "APEX initialization \n", __FILE__, __LINE__); - m_apexDestruction = new ApexDestruction(m_log); + NVBLAST_LOG_INFO("APEX initialization"); + m_apexDestruction = new ApexDestruction(); return isValid(); } @@ -89,8 +109,8 @@ bool ApexImportTool::initialize(nvidia::apex::ApexSDK* apexSdk, nvidia::apex::Mo { return true; } - m_log(NvBlastMessage::Info, "APEX initialization \n", __FILE__, __LINE__); - m_apexDestruction = new ApexDestruction(apexSdk, moduleDestructible, m_log); + NVBLAST_LOG_INFO("APEX initialization"); + m_apexDestruction = new ApexDestruction(apexSdk, moduleDestructible); return isValid(); } @@ -102,12 +122,15 @@ DestructibleAsset* ApexImportTool::loadAssetFromFile(physx::PxFileBuf* stream) bool ApexImportTool::getCollisionGeometry(const nvidia::apex::DestructibleAsset* apexAsset, uint32_t chunkCount, std::vector<uint32_t>& chunkReorderInvMap, const std::vector<uint32_t>& apexChunkFlags, std::vector<ExtPxAssetDesc::ChunkDesc>& physicsChunks, - std::vector<ExtPxAssetDesc::SubchunkDesc>& physicsSubchunks) + std::vector<ExtPxAssetDesc::SubchunkDesc>& physicsSubchunks, std::vector<std::vector<CollisionHull*> >& hullsDesc) { physicsChunks.clear(); physicsChunks.resize(chunkCount); // prepare physics asset desc (convexes, transforms) - ConvexMeshBuilder collisionBuilder(m_apexDestruction->cooking(), &m_apexDestruction->apexSDK()->getPhysXSDK()->getPhysicsInsertionCallback()); + std::shared_ptr<ConvexMeshBuilder> collisionBuilder( + NvBlastExtAuthoringCreateConvexMeshBuilder(m_apexDestruction->cooking(), &m_apexDestruction->apexSDK()->getPhysXSDK()->getPhysicsInsertionCallback()), + [](ConvexMeshBuilder* cmb) { cmb->release(); }); + int32_t apexHullCount = 0; const uint32_t apexChunkCount = apexAsset->getChunkCount(); for (uint32_t chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex) @@ -121,6 +144,8 @@ bool ApexImportTool::getCollisionGeometry(const nvidia::apex::DestructibleAsset* } physicsSubchunks.reserve(chunkCount); { + hullsDesc.clear(); + hullsDesc.resize(chunkCount); for (uint32_t chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex) { uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex]; @@ -138,9 +163,10 @@ bool ApexImportTool::getCollisionGeometry(const nvidia::apex::DestructibleAsset* paramHandle.getArraySize(verticesCount); std::vector<PxVec3> vertexData(verticesCount); paramHandle.getParamVec3Array(vertexData.data(), verticesCount); - - PxConvexMesh* convexMesh = collisionBuilder.buildConvexMesh(vertexData); - + hullsDesc[chunkIndex].push_back(nullptr); + hullsDesc[chunkIndex].back() = collisionBuilder.get()->buildCollisionGeometry(verticesCount, vertexData.data()); + PxConvexMesh* convexMesh = collisionBuilder.get()->buildConvexMesh(verticesCount, vertexData.data()); + const ExtPxAssetDesc::SubchunkDesc subchunk = { PxTransform(PxIdentity), @@ -155,8 +181,7 @@ bool ApexImportTool::getCollisionGeometry(const nvidia::apex::DestructibleAsset* } else { - // this is earth chunk - physicsChunks[chunkIndex].isStatic = true; + NVBLAST_LOG_ERROR("Error: chunk index is invalid."); } } } @@ -164,7 +189,7 @@ bool ApexImportTool::getCollisionGeometry(const nvidia::apex::DestructibleAsset* // check that vector didn't grow if (static_cast<int32_t>(physicsSubchunks.size()) > apexHullCount) { - m_log(NvBlastMessage::Error, "Error: sub chunk count seems to be wrong. \n", __FILE__, __LINE__); + NVBLAST_LOG_ERROR("Error: sub chunk count seems to be wrong."); return false; } return true; @@ -189,13 +214,14 @@ void gatherChunkHullPoints(const DestructibleAsset* apexAsset, std::vector<std:: } } } -PxBounds3 gatherChunkTriangles(const DestructibleAsset* apexAsset, std::vector<std::vector<Nv::Blast::Triangle> >& chunkTriangles, int32_t posBufferIndex, float scale, PxVec3 offset ) +PxBounds3 gatherChunkTriangles(const DestructibleAsset* apexAsset, std::vector<uint32_t>& chunkTrianglesOffsets, std::vector<Nv::Blast::Triangle>& chunkTriangles, int32_t posBufferIndex, float scale, PxVec3 offset ) { PxBounds3 bnd; bnd.setEmpty(); - chunkTriangles.clear(); - chunkTriangles.resize(apexAsset->getChunkCount()); + chunkTrianglesOffsets.clear(); + chunkTrianglesOffsets.resize(apexAsset->getChunkCount() + 1); + chunkTrianglesOffsets[0] = 0; for (uint32_t chunkIndex = 0; chunkIndex < apexAsset->getChunkCount(); ++chunkIndex) { uint32_t part = apexAsset->getPartIndex(chunkIndex); @@ -223,9 +249,10 @@ PxBounds3 gatherChunkTriangles(const DestructibleAsset* apexAsset, std::vector<s a.p *= scale; b.p *= scale; c.p *= scale; - chunkTriangles[chunkIndex].push_back(Nv::Blast::Triangle(a, b, c)); + chunkTriangles.push_back(Nv::Blast::Triangle(a, b, c)); } } + chunkTrianglesOffsets[chunkIndex + 1] = chunkTriangles.size(); } return bnd; } @@ -252,10 +279,7 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder if (!apexAsset) { - if (m_log != NULL) - { - m_log(NvBlastMessage::Error, "Error: attempting to import NULL Apex asset.\n", __FILE__, __LINE__); - } + NVBLAST_LOG_ERROR("Error: attempting to import NULL Apex asset."); return false; } @@ -339,14 +363,18 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder bondsDescriptors.clear(); bondsDescriptors.resize(overlapsBuffer.size()); - Nv::Blast::BlastBondGenerator bondGenTool(GetApexSDK()->getCookingInterface(), &GetApexSDK()->getPhysXSDK()->getPhysicsInsertionCallback()); - std::vector<std::vector<Nv::Blast::Triangle> > chunkTriangles; + std::shared_ptr<Nv::Blast::BlastBondGenerator> bondGenTool( + NvBlastExtAuthoringCreateBondGenerator(GetApexSDK()->getCookingInterface(), &GetApexSDK()->getPhysXSDK()->getPhysicsInsertionCallback()), + [](Nv::Blast::BlastBondGenerator* bg) {bg->release(); }); + + std::vector<uint32_t> chunkTrianglesOffsets; + std::vector<Nv::Blast::Triangle> chunkTriangles; PxBounds3 bnds = apexAsset->getRenderMeshAsset()->getBounds(); PxVec3 offset = bnds.getCenter(); float scale = 1.0f / PxMax(PxAbs(bnds.getExtents(0)), PxMax(PxAbs(bnds.getExtents(1)), PxAbs(bnds.getExtents(2)))); - bnds = gatherChunkTriangles(apexAsset, chunkTriangles, 0, scale, offset); + bnds = gatherChunkTriangles(apexAsset, chunkTrianglesOffsets, chunkTriangles, 0, scale, offset); BondGenerationConfig cf; @@ -355,9 +383,17 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder { cf.bondMode = BondGenerationConfig::EXACT; } - - bondGenTool.createBondBetweenMeshes(chunkTriangles, bondsDescriptors, overlapsBuffer, cf); - + NvBlastBondDesc* bondsDesc; + std::vector<uint32_t> overlapsA, overlapsB; + for (auto it : overlapsBuffer) + { + overlapsA.push_back(it.first); + overlapsB.push_back(it.second); + } + bondGenTool.get()->createBondBetweenMeshes(chunkTrianglesOffsets.size() - 1, chunkTrianglesOffsets.data(), chunkTriangles.data(), + overlapsBuffer.size(), overlapsA.data(), overlapsB.data(), bondsDesc, cf); + memcpy(bondsDescriptors.data(), bondsDesc, sizeof(NvBlastBondDesc) * bondsDescriptors.size()); + delete[] bondsDesc; float inverScale = 1.0f / scale; @@ -392,16 +428,8 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder apexChunkFlags.clear(); apexChunkFlags.resize(chunkDescriptors.size()); - // special 'earth chunk' + // externally supported chunks { - uint32_t earthChunkIndex = (uint32_t)chunkDescriptors.size(); - NvBlastChunkDesc earthChunk; - memset(earthChunk.centroid, 0, 3 * sizeof(float)); - earthChunk.volume = 0.0f; - earthChunk.parentChunkIndex = rootChunkIndex; - earthChunk.flags = NvBlastChunkDesc::SupportFlag; - earthChunk.userData = earthChunkIndex; - uint32_t chunksConnectedToEarth = 0; for (uint32_t i = 0; i < chunkDescriptors.size(); i++) { uint32_t chunkID = i; @@ -420,29 +448,24 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder { NvBlastBondDesc bond; bond.chunkIndices[0] = i; - bond.chunkIndices[1] = earthChunkIndex; + bond.chunkIndices[1] = UINT32_MAX; // invalid index for "world" bond.bond.area = 0.1f; // ??? PxVec3 center = apexAsset->getChunkActorLocalBounds(chunkID).getCenter(); memcpy(&bond.bond.centroid, ¢er.x, sizeof(PxVec3)); PxVec3 normal = PxVec3(0, 0, 1); memcpy(&bond.bond.normal, &normal.x, sizeof(PxVec3)); bondsDescriptors.push_back(bond); - chunksConnectedToEarth++; } } - if (chunksConnectedToEarth > 0) - { - chunkDescriptors.push_back(earthChunk); - } } const uint32_t chunkCount = static_cast<uint32_t>(chunkDescriptors.size()); const uint32_t bondCount = static_cast<uint32_t>(bondsDescriptors.size()); std::vector<uint32_t> chunkReorderMap(chunkCount); std::vector<NvBlastChunkDesc> scratch(chunkCount); - NvBlastEnsureAssetExactSupportCoverage(chunkDescriptors.data(), chunkCount, scratch.data(), m_log); - NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDescriptors.data(), chunkCount, scratch.data(), m_log); - NvBlastApplyAssetDescChunkReorderMapInplace(chunkDescriptors.data(), chunkCount, bondsDescriptors.data(), bondCount, chunkReorderMap.data(), scratch.data(), m_log); + NvBlastEnsureAssetExactSupportCoverage(chunkDescriptors.data(), chunkCount, scratch.data(), logLL); + NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDescriptors.data(), chunkCount, scratch.data(), logLL); + NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDescriptors.data(), chunkCount, bondsDescriptors.data(), bondCount, chunkReorderMap.data(), true, scratch.data(), logLL); chunkReorderInvMap.resize(chunkReorderMap.size()); Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(), static_cast<uint32_t>(chunkReorderMap.size())); return true; @@ -453,28 +476,19 @@ bool ApexImportTool::saveAsset(const NvBlastAsset* asset, PxFileBuf* stream) { if (!asset) { - if (m_log != NULL) - { - m_log(NvBlastMessage::Error, "Error: attempting to serialize NULL asset.\n", __FILE__, __LINE__); - } + NVBLAST_LOG_ERROR("Error: attempting to serialize NULL asset."); return false; } if (!stream) { - if (m_log != NULL) - { - m_log(NvBlastMessage::Error, "Error: bad output stream.\n", __FILE__, __LINE__); - } + NVBLAST_LOG_ERROR("Error: bad output stream."); return false; } const void* assetData = asset; - uint32_t assetDataSize = NvBlastAssetGetSize(asset, m_log); + uint32_t assetDataSize = NvBlastAssetGetSize(asset, logLL); stream->write(assetData, assetDataSize); stream->close(); - if (m_log != NULL) - { - m_log(NvBlastMessage::Info, "Saving finished... \n", __FILE__, __LINE__); - } + NVBLAST_LOG_INFO("Saving finished."); return true; } diff --git a/sdk/extensions/import/source/NvBlastExtScopedResource.cpp b/sdk/extensions/import/source/NvBlastExtScopedResource.cpp index 7cf7492..4f16b36 100644 --- a/sdk/extensions/import/source/NvBlastExtScopedResource.cpp +++ b/sdk/extensions/import/source/NvBlastExtScopedResource.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 "NvBlastExtScopedResource.h" diff --git a/sdk/extensions/import/source/NvBlastExtScopedResource.h b/sdk/extensions/import/source/NvBlastExtScopedResource.h index e0d35b7..6ab2980 100644 --- a/sdk/extensions/import/source/NvBlastExtScopedResource.h +++ b/sdk/extensions/import/source/NvBlastExtScopedResource.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 NVBLASTEXTSCOPEDRESOURCE_H #define NVBLASTEXTSCOPEDRESOURCE_H 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.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(); } diff --git a/sdk/extensions/serialization/include/NvBlastExtLlSerialization.h b/sdk/extensions/serialization/include/NvBlastExtLlSerialization.h new file mode 100644 index 0000000..db90a1a --- /dev/null +++ b/sdk/extensions/serialization/include/NvBlastExtLlSerialization.h @@ -0,0 +1,113 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastGlobals.h" + + +/** +Blast Low-level serialization support. Contains serializers which can be used by the ExtSerialization manager. +*/ + + +// Forward declarations +struct NvBlastAsset; +struct NvBlastFamily; + + +namespace Nv +{ +namespace Blast +{ + +// Forward declarations +class ExtSerialization; + + +/** Standard Object Type IDs */ +struct LlObjectTypeID +{ + enum Enum + { + Asset = NVBLAST_FOURCC('L', 'L', 'A', 'S'), + Family = NVBLAST_FOURCC('L', 'L', 'F', 'A'), + }; +}; + +} // namespace Blast +} // namespace Nv + + +/** +Load all low-level serializers into the ExtSerialization manager. *N.B.* This is done automatically when +the ExtSerialization manager is created via NvBlastExtSerializationCreate(), so currently this public function +is unnecessary. Note also that other modules' serializers (ExtTkSerialization and ExtPxSerialization) are +_not_ loaded automatically, and need to be explicitly loaded by the user using their respective load functions. + +It does no harm to call this function more than once; serializers already loaded will not be loaded again. + +\param[in] serialization Serialization manager into which to load serializers. + +\return the number of serializers loaded. +*/ +NVBLAST_API size_t NvBlastExtLlSerializerLoadSet(Nv::Blast::ExtSerialization& serialization); + + +/** +Utility wrapper function to serialize an NvBlastAsset. Allocates the buffer internally using the +callack set in ExtSerialization::setBufferProvider. + +Equivalent to: + + serialization.serializeIntoBuffer(buffer, asset, Nv::Blast::LlObjectTypeID::Asset); + +\param[out] buffer Pointer to the buffer created. +\param[in] serialization Serialization manager. +\param[in] asset Pointer to the NvBlastAsset to serialize. + +\return the number of bytes serialized into the buffer (zero if unsuccessful). +*/ +NVBLAST_API uint64_t NvBlastExtSerializationSerializeAssetIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const NvBlastAsset* asset); + + +/** +Utility wrapper function to serialize an NvBlastFamily. Allocates the buffer internally using the +callack set in ExtSerialization::setBufferProvider. + +Equivalent to: + + serialization.serializeIntoBuffer(buffer, family, Nv::Blast::LlObjectTypeID::Family); + +\param[out] buffer Pointer to the buffer created. +\param[in] serialization Serialization manager. +\param[in] family Pointer to the NvBlastFamily to serialize. + +\return the number of bytes serialized into the buffer (zero if unsuccessful). +*/ +NVBLAST_API uint64_t NvBlastExtSerializationSerializeFamilyIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const NvBlastFamily* family); diff --git a/sdk/extensions/serialization/include/NvBlastExtPxSerialization.h b/sdk/extensions/serialization/include/NvBlastExtPxSerialization.h new file mode 100644 index 0000000..d3457ab --- /dev/null +++ b/sdk/extensions/serialization/include/NvBlastExtPxSerialization.h @@ -0,0 +1,99 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastGlobals.h" + + +/** +Blast serialization support for the ExtPhysX extension. Contains serializers which can be used by the ExtSerialization manager. +*/ + + +namespace Nv +{ +namespace Blast +{ + +// Forward declarations +class TkFramework; +class ExtSerialization; +class ExtPxAsset; + + +/** Standard Object Type IDs */ +struct ExtPxObjectTypeID +{ + enum Enum + { + Asset = NVBLAST_FOURCC('P', 'X', 'A', 'S'), + }; +}; + +} // namespace Blast +} // namespace Nv + + +namespace physx +{ + +// Forward declarations +class PxPhysics; +class PxCooking; + +} // namespace physx + + +/** +Load all ExtPhysX extension serializers into the ExtSerialization manager. + +It does no harm to call this function more than once; serializers already loaded will not be loaded again. + +\param[in] serialization Serialization manager into which to load serializers. + +\return the number of serializers loaded. +*/ +NVBLAST_API size_t NvBlastExtPxSerializerLoadSet(Nv::Blast::TkFramework& framework, physx::PxPhysics& physics, physx::PxCooking& cooking, Nv::Blast::ExtSerialization& serialization); + + +/** +Utility wrapper function to serialize an ExtPxAsset. Allocates the buffer internally using the +callack set in ExtSerialization::setBufferProvider. + +Equivalent to: + + serialization.serializeIntoBuffer(buffer, asset, Nv::Blast::ExtPxObjectTypeID::Asset); + +\param[out] buffer Pointer to the buffer created. +\param[in] serialization Serialization manager. +\param[in] asset Pointer to the ExtPxAsset to serialize. + +\return the number of bytes serialized into the buffer (zero if unsuccessful). +*/ +NVBLAST_API uint64_t NvBlastExtSerializationSerializeExtPxAssetIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const Nv::Blast::ExtPxAsset* asset); diff --git a/sdk/extensions/serialization/include/NvBlastExtSerialization.h b/sdk/extensions/serialization/include/NvBlastExtSerialization.h new file mode 100644 index 0000000..4225625 --- /dev/null +++ b/sdk/extensions/serialization/include/NvBlastExtSerialization.h @@ -0,0 +1,156 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastGlobals.h" + + +namespace Nv +{ +namespace Blast +{ + +/** + Serialization manager interface +*/ +class ExtSerialization +{ +public: + /** Standard Encoding IDs */ + struct EncodingID + { + enum Enum + { + CapnProtoBinary = NVBLAST_FOURCC('C', 'P', 'N', 'B'), + RawBinary = NVBLAST_FOURCC('R', 'A', 'W', ' '), + }; + }; + + /** Buffer provider API, used to request a buffer for serialization. */ + class BufferProvider + { + public: + virtual void* requestBuffer(size_t size) = 0; + }; + + /** + Set the serialization encoding to use. (See EncodingID.) + + \return true iff successful. + */ + virtual bool setSerializationEncoding(uint32_t encodingID) = 0; + + /** + Retrieve the current serialization encoding being used. Note, by default this is set to the encoding of the first + serializer registered by a module. Currently this is done automatically by the NvBlastExtLlExtension module. + + \return the current serialization encoding (zero if none is set). + */ + virtual uint32_t getSerializationEncoding() const = 0; + + /** + Set the buffer provider callback to use. (See BufferProvider.) If not set, a default provider using NVBLAST_ALLOC (see + NvBlastGlobals.h) is used, which may be freed using NvBLAST_FREE. + + \param[in] bufferProvider Buffer provider callback to use. If NULL, uses the default provider using the allocator given + in NvBlastGlobals. + */ + virtual void setBufferProvider(BufferProvider* bufferProvider) = 0; + + /** + Reads information from a buffer, returning the contained object type ID, encoding ID, and data size. + \param[out] objectTypeID If not NULL, the object type ID is written to *objectTypeID. + \param[out] encodingID If not NULL, the encoding ID is written to *encodingID. + \param[out] dataSize If not NULL, the data size is written to *dataSize. (Does not include the size of the header.) + \param[in] buffer Pointer to the buffer to read. + \param[in] bufferSize Size of the buffer to read. + + \return true iff the header is successfully read. + */ + virtual bool peekHeader(uint32_t* objectTypeID, uint32_t* encodingID, uint64_t* dataSize, const void* buffer, uint64_t bufferSize) = 0; + + /** + Determines the current object in the buffer and returns the position in the buffer immediately after the object. + + \param[in, out] bufferSize Size of the buffer to read on input, on output the remaining buffer size given the return buffer value. + \param[in] buffer Pointer to the buffer to read. + + \return a pointer to the new position in the buffer after the skipped object if successful, NULL otherwise. The bufferSize field is only updated if a valid pointer is returned. + */ + virtual const void* skipObject(uint64_t& bufferSize, const void* buffer) = 0; + + /** + Deserialize from a buffer into a newly allocated object. + + \param[in] buffer Pointer to the buffer to read. + \param[in] bufferSize Size of the buffer to read. + \param[out] objectTypeIDPtr Optional, if not NULL then *objectTypeIDPtr will be filled with the deserialized object's + type ID if deserialization is successful, or 0 if unsuccessful. + + \return object pointer; returns null if failed to deserialize. + */ + virtual void* deserializeFromBuffer(const void* buffer, uint64_t bufferSize, uint32_t* objectTypeIDPtr = nullptr) = 0; + + /** + Serialize into a buffer. Allocates the buffer internally using the callack set in setBufferProvider. + + \param[out] buffer Pointer to the buffer created. + \param[in] object Object pointer. + \param[in] objectTypeID Object type ID. + + \return the number of bytes serialized into the buffer (zero if unsuccessful). + */ + virtual uint64_t serializeIntoBuffer(void*& buffer, const void* object, uint32_t objectTypeID) = 0; + + /** + Release the serialization manager and all contained objects. + */ + virtual void release() = 0; + +protected: + /** + Destructor is virtual and not public - use the release() method instead of explicitly deleting the serialization manager + */ + virtual ~ExtSerialization() {} +}; + +} // namespace Blast +} // namespace Nv + + +//////// Global API to create serialization //////// + +/** +Create a new serialization manager. To release it, use its release() method. + +This uses the global allocator set in NvBlastGlobals.h. + +\return a new serialization manager. +*/ +NVBLAST_API Nv::Blast::ExtSerialization* NvBlastExtSerializationCreate(); diff --git a/sdk/extensions/serialization/include/NvBlastExtSerializationInterface.h b/sdk/extensions/serialization/include/NvBlastExtSerializationInterface.h deleted file mode 100644 index e4f27e0..0000000 --- a/sdk/extensions/serialization/include/NvBlastExtSerializationInterface.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* Copyright (c) 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 this file to get the C interface to serialization for all asset types (LL, Tk and Ext) -*/ -#pragma once -#include <ostream> -#include "NvBlastTkAsset.h" -#include "NvBlastExtPxAsset.h" - -#include "NvBlastExtSerializationLLInterface.h" - -namespace physx -{ - class PxPhysics; -} - -NVBLAST_API void setPhysXSDK(physx::PxPhysics* physXSDK); - -NVBLAST_API Nv::Blast::TkAsset* deserializeTkAsset(const unsigned char* input, uint32_t size); -NVBLAST_API Nv::Blast::TkAsset* deserializeTkAssetFromStream(std::istream &inputStream); -NVBLAST_API bool serializeTkAssetIntoStream(const Nv::Blast::TkAsset *asset, std::ostream &outputStream); -NVBLAST_API bool serializeTkAssetIntoNewBuffer(const Nv::Blast::TkAsset *asset, unsigned char **outBuffer, uint32_t &outSize); -NVBLAST_API bool serializeTkAssetIntoExistingBuffer(const Nv::Blast::TkAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize); - -NVBLAST_API Nv::Blast::ExtPxAsset* deserializeExtPxAsset(const unsigned char* input, uint32_t size); -NVBLAST_API Nv::Blast::ExtPxAsset* deserializeExtPxAssetFromStream(std::istream &inputStream); -NVBLAST_API bool serializeExtPxAssetIntoStream(const Nv::Blast::ExtPxAsset *asset, std::ostream &outputStream); -NVBLAST_API bool serializeExtPxAssetIntoNewBuffer(const Nv::Blast::ExtPxAsset *asset, unsigned char **outBuffer, uint32_t &outSize); -NVBLAST_API bool serializeExtPxAssetIntoExistingBuffer(const Nv::Blast::ExtPxAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize); diff --git a/sdk/extensions/serialization/include/NvBlastExtSerializationLLInterface.h b/sdk/extensions/serialization/include/NvBlastExtSerializationLLInterface.h deleted file mode 100644 index d21c7ca..0000000 --- a/sdk/extensions/serialization/include/NvBlastExtSerializationLLInterface.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* Copyright (c) 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 this file to access the C API for serialization, for Low Level assets only. - -For Serialization of Tk and Ext assets, include only NvBlastExtSerializationInterface.h, which will include this file as well. - -*/ -#pragma once -#include <ostream> -#include "NvBlastPreprocessor.h" -#include "NvBlastTypes.h" - -#include "NvBlastExtGlobals.h" - -/* - Set a global NvBlastAlloc signature allocation function that the deserialization will use when required. - - NOTE: This will NOT be used when using the combined serialization library, as it will use the TkFramework's allocation and logging -*/ -NVBLAST_API void setAllocator(NvBlastExtAlloc alloc); - -/* - Set a global NvBlastLog signature allocation function that the library will use when required. - - NOTE: This will NOT be used when using the combined serialization library, as it will use the TkFramework's allocation and logging -*/ -NVBLAST_API void setLog(NvBlastLog log); - - -NVBLAST_API NvBlastAsset* deserializeAsset(const unsigned char* input, uint32_t size); -NVBLAST_API NvBlastAsset* deserializeAssetFromStream(std::istream &inputStream); -NVBLAST_API bool serializeAssetIntoStream(const NvBlastAsset *asset, std::ostream &outputStream); -NVBLAST_API bool serializeAssetIntoNewBuffer(const NvBlastAsset *asset, unsigned char **outBuffer, uint32_t &outSize); -NVBLAST_API bool serializeAssetIntoExistingBuffer(const NvBlastAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize); diff --git a/sdk/extensions/serialization/include/NvBlastExtTkSerialization.h b/sdk/extensions/serialization/include/NvBlastExtTkSerialization.h new file mode 100644 index 0000000..2db4f4f --- /dev/null +++ b/sdk/extensions/serialization/include/NvBlastExtTkSerialization.h @@ -0,0 +1,89 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastGlobals.h" + + +/** +Blast High-level serialization support. Contains serializers which can be used by the ExtSerialization manager. +*/ + + +namespace Nv +{ +namespace Blast +{ + +// Forward declarations +class ExtSerialization; +class TkFramework; +class TkAsset; + + +/** Standard Object Type IDs */ +struct TkObjectTypeID +{ + enum Enum + { + Asset = NVBLAST_FOURCC('T', 'K', 'A', 'S'), + }; +}; + +} // namespace Blast +} // namespace Nv + + +/** +Load all high-level serializers into the ExtSerialization manager. + +It does no harm to call this function more than once; serializers already loaded will not be loaded again. + +\param[in] serialization Serialization manager into which to load serializers. + +\return the number of serializers loaded. +*/ +NVBLAST_API size_t NvBlastExtTkSerializerLoadSet(Nv::Blast::TkFramework& framework, Nv::Blast::ExtSerialization& serialization); + + +/** +Utility wrapper function to serialize a TkAsset. Allocates the buffer internally using the +callack set in ExtSerialization::setBufferProvider. + +Equivalent to: + + serialization.serializeIntoBuffer(buffer, asset, Nv::Blast::TkObjectTypeID::Asset); + +\param[out] buffer Pointer to the buffer created. +\param[in] serialization Serialization manager. +\param[in] asset Pointer to the TkAsset to serialize. + +\return the number of bytes serialized into the buffer (zero if unsuccessful). +*/ +NVBLAST_API uint64_t NvBlastExtSerializationSerializeTkAssetIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const Nv::Blast::TkAsset* asset); diff --git a/sdk/extensions/serialization/source/BlastSerialization.capn b/sdk/extensions/serialization/source/BlastSerialization.capn deleted file mode 100644 index 49b1dbb..0000000 --- a/sdk/extensions/serialization/source/BlastSerialization.capn +++ /dev/null @@ -1,162 +0,0 @@ -@0xaffe4498f275ee58; - -using Cxx = import "/capnp/c++.capnp"; - -$Cxx.namespace("Nv::Blast::Serialization"); - -struct Asset -{ - header @0 :NvBlastDataBlock; - - iD @1 :UUID; - - chunkCount @2 :UInt32; - - graph @3 :NvBlastSupportGraph; - - leafChunkCount @4 :UInt32; - - firstSubsupportChunkIndex @5 :UInt32; - - bondCount @6 :UInt32; - - chunks @7: List(NvBlastChunk); - - bonds @8: List(NvBlastBond); - - subtreeLeafChunkCounts @9: List(UInt32); - - chunkToGraphNodeMap @10: List(UInt32); -} - -struct TkAsset -{ - assetLL @0 :Asset; - - jointDescs @1 :List(TkAssetJointDesc); - -} - -struct ExtPxAsset -{ - asset @0 :TkAsset; - chunks @1 :List(ExtPxChunk); - subchunks @2 :List(ExtPxSubchunk); -} - -struct ExtPxChunk -{ - firstSubchunkIndex @0 :UInt32; - subchunkCount @1 :UInt32; - isStatic @2 :Bool; -} - -struct ExtPxSubchunk -{ - transform @0 :PxTransform; - geometry @1 :PxConvexMeshGeometry; -} - -struct PxConvexMeshGeometry -{ - scale @0 :PxMeshScale; - convexMesh @1 :Data; - meshFlags @2 :UInt8; - - enum Type - { - eSPHERE @0; - ePLANE @1; - eCAPSULE @2; - eBOX @3; - eCONVEXMESH @4; - eTRIANGLEMESH @5; - eHEIGHTFIELD @6; - } - - type @3 :Type; -} - -struct NvBlastDataBlock -{ - enum Type - { - assetDataBlock @0; - instanceDataBlock @1; - } - - dataType @0 :Type; - - formatVersion @1 :UInt32; - - size @2 :UInt32; -} - -struct NvBlastChunk -{ - centroid @0 :List(Float32); - - volume @1 :Float32; - - parentChunkIndex @2 :UInt32; - firstChildIndex @3 :UInt32; - childIndexStop @4 :UInt32; - userData @5 :UInt32; -} - -struct NvBlastBond -{ - normal @0 :List(Float32); - area @1 :Float32; - centroid @2 :List(Float32); - userData @3 :UInt32; -} - -struct TkAssetJointDesc -{ - nodeIndices @0 :List(UInt32); - attachPositions @1 :List(PxVec3); -} - -struct PxVec3 -{ - x @0 :Float32; - y @1 :Float32; - z @2 :Float32; -} - -struct PxQuat -{ - x @0 :Float32; - y @1 :Float32; - z @2 :Float32; - w @3 :Float32; -} - -struct PxMeshScale -{ - scale @0 :PxVec3; - rotation @1 :PxQuat; -} - -struct PxTransform -{ - q @0 :PxQuat; - p @1 :PxVec3; -} - -struct NvBlastSupportGraph -{ - nodeCount @0 : UInt32; - - chunkIndices @1 : List(UInt32); - adjacencyPartition @2 : List(UInt32); - adjacentNodeIndices @3 : List(UInt32); - adjacentBondIndices @4 : List(UInt32); -} - -struct UUID -{ - value @0 : Data; -} - diff --git a/sdk/extensions/serialization/source/DTO/AssetDTO.cpp b/sdk/extensions/serialization/source/DTO/AssetDTO.cpp index 8d035fc..b500fe6 100644 --- a/sdk/extensions/serialization/source/DTO/AssetDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/AssetDTO.cpp @@ -1,187 +1,202 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "AssetDTO.h" +#include "NvBlastGlobals.h" #include "NvBlastIDDTO.h" #include "NvBlastChunkDTO.h" #include "NvBlastBondDTO.h" #include "NvBlastAsset.h" -#include "NvBlastExtSerializationLLImpl.h" -#include "NvBlastExtGlobals.h" -#if !defined(BLAST_LL_ALLOC) -#include "NvBlastExtAllocator.h" -#endif namespace Nv { - namespace Blast +namespace Blast +{ + +bool AssetDTO::serialize(Nv::Blast::Serialization::Asset::Builder builder, const Nv::Blast::Asset * poco) +{ + NvBlastIDDTO::serialize(builder.initID(), &poco->m_ID); + + builder.setLeafChunkCount(poco->m_leafChunkCount); + + builder.setFirstSubsupportChunkIndex(poco->m_firstSubsupportChunkIndex); + + capnp::List<Nv::Blast::Serialization::NvBlastChunk>::Builder chunks = builder.initChunks(poco->m_chunkCount); + + builder.setChunkCount(poco->m_chunkCount); + + NVBLAST_ASSERT_WITH_MESSAGE(builder.getChunkCount() == poco->m_chunkCount, "WTF"); + + for (uint32_t i = 0; i < poco->m_chunkCount; i++) + { + NvBlastChunk& chunk = poco->getChunks()[i]; + + NvBlastChunkDTO::serialize(chunks[i], &chunk); + } + + NVBLAST_ASSERT_WITH_MESSAGE(builder.getChunkCount() == poco->m_chunkCount, "WTF"); + + capnp::List<Nv::Blast::Serialization::NvBlastBond>::Builder bonds = builder.initBonds(poco->m_bondCount); + + builder.setBondCount(poco->m_bondCount); + + for (uint32_t i = 0; i < poco->m_bondCount; i++) + { + NvBlastBond& bond = poco->getBonds()[i]; + + NvBlastBondDTO::serialize(bonds[i], &bond); + } + + kj::ArrayPtr<uint32_t> stlcArray(poco->getSubtreeLeafChunkCounts(), poco->m_chunkCount); + builder.initSubtreeLeafChunkCounts(poco->m_chunkCount); + builder.setSubtreeLeafChunkCounts(stlcArray); + + kj::ArrayPtr<uint32_t> ctgnArray(poco->getChunkToGraphNodeMap(), poco->m_chunkCount); + builder.setChunkToGraphNodeMap(ctgnArray); + + Nv::Blast::Serialization::NvBlastSupportGraph::Builder graphBulder = builder.initGraph(); + + graphBulder.setNodeCount(poco->m_graph.m_nodeCount); + + uint32_t* ciPtr = poco->m_graph.getChunkIndices(); + + kj::ArrayPtr<const uint32_t> ciArray(ciPtr, poco->m_graph.m_nodeCount); + graphBulder.setChunkIndices(ciArray); + + kj::ArrayPtr<const uint32_t> adjPart(poco->m_graph.getAdjacencyPartition(), poco->m_graph.m_nodeCount + 1); + graphBulder.setAdjacencyPartition(adjPart); + + NVBLAST_ASSERT(graphBulder.getAdjacencyPartition().size() == poco->m_graph.m_nodeCount + 1); + + kj::ArrayPtr<const uint32_t> nodeIndices(poco->m_graph.getAdjacentNodeIndices(), poco->m_bondCount * 2); + graphBulder.setAdjacentNodeIndices(nodeIndices); + + NVBLAST_ASSERT(graphBulder.getAdjacentNodeIndices().size() == poco->m_bondCount * 2); + + kj::ArrayPtr<const uint32_t> bondIndices(poco->m_graph.getAdjacentBondIndices(), poco->m_bondCount * 2); + graphBulder.setAdjacentBondIndices(bondIndices); + + return true; +} + + +Nv::Blast::Asset* AssetDTO::deserialize(Nv::Blast::Serialization::Asset::Reader reader) +{ + NvBlastID EmptyId; + memset(EmptyId.data, 0, sizeof(NvBlastID)); + + void* mem = NVBLAST_ALLOC(reader.totalSize().wordCount * sizeof(uint64_t)); + + auto asset = Nv::Blast::initializeAsset(mem, EmptyId, reader.getChunkCount(), reader.getGraph().getNodeCount(), reader.getLeafChunkCount(), reader.getFirstSubsupportChunkIndex(), reader.getBondCount(), logLL); + + bool result = deserializeInto(reader, asset); + + return result ? asset : nullptr; +} + + +bool AssetDTO::deserializeInto(Nv::Blast::Serialization::Asset::Reader reader, Nv::Blast::Asset * poco) +{ + NvBlastIDDTO::deserializeInto(reader.getID(), &poco->m_ID); + + NvBlastBond* bonds = poco->getBonds(); + + uint32_t bondCount = reader.getBondCount(); + auto readerBonds = reader.getBonds(); + for (uint32_t i = 0; i < bondCount; i++) + { + auto bondReader = readerBonds[i]; + + NvBlastBondDTO::deserializeInto(bondReader, &bonds[i]); + } + + NvBlastChunk* chunks = poco->getChunks(); + + uint32_t chunkCount = reader.getChunkCount(); + auto readerChunks = reader.getChunks(); + for (uint32_t i = 0; i < chunkCount; i++) + { + auto chunkReader = readerChunks[i]; + + NvBlastChunkDTO::deserializeInto(chunkReader, &chunks[i]); + } + + poco->m_graph.m_nodeCount = reader.getGraph().getNodeCount(); + + NVBLAST_ASSERT(reader.getSubtreeLeafChunkCounts().size() == poco->m_chunkCount); + auto readerSubtreeLeafChunkCounts = reader.getSubtreeLeafChunkCounts(); + for (uint32_t i = 0; i < poco->m_chunkCount; i++) { - bool AssetDTO::serialize(Nv::Blast::Serialization::Asset::Builder builder, const Nv::Blast::Asset * poco) - { - NvBlastIDDTO::serialize(builder.initID(), &poco->m_ID); - - builder.setLeafChunkCount(poco->m_leafChunkCount); - - builder.setFirstSubsupportChunkIndex(poco->m_firstSubsupportChunkIndex); - - capnp::List<Nv::Blast::Serialization::NvBlastChunk>::Builder chunks = builder.initChunks(poco->m_chunkCount); - - builder.setChunkCount(poco->m_chunkCount); - - NVBLAST_ASSERT_WITH_MESSAGE(builder.getChunkCount() == poco->m_chunkCount, "WTF"); - - for (uint32_t i = 0; i < poco->m_chunkCount; i++) - { - NvBlastChunk& chunk = poco->getChunks()[i]; - - NvBlastChunkDTO::serialize(chunks[i], &chunk); - } - - NVBLAST_ASSERT_WITH_MESSAGE(builder.getChunkCount() == poco->m_chunkCount, "WTF"); - - capnp::List<Nv::Blast::Serialization::NvBlastBond>::Builder bonds = builder.initBonds(poco->m_bondCount); - - builder.setBondCount(poco->m_bondCount); - - for (uint32_t i = 0; i < poco->m_bondCount; i++) - { - NvBlastBond& bond = poco->getBonds()[i]; - - NvBlastBondDTO::serialize(bonds[i], &bond); - } - - kj::ArrayPtr<uint32_t> stlcArray(poco->getSubtreeLeafChunkCounts(), poco->m_chunkCount); - builder.initSubtreeLeafChunkCounts(poco->m_chunkCount); - builder.setSubtreeLeafChunkCounts(stlcArray); - - kj::ArrayPtr<uint32_t> ctgnArray(poco->getChunkToGraphNodeMap(), poco->m_chunkCount); - builder.setChunkToGraphNodeMap(ctgnArray); - - Nv::Blast::Serialization::NvBlastSupportGraph::Builder graphBulder = builder.initGraph(); - - graphBulder.setNodeCount(poco->m_graph.m_nodeCount); - - uint32_t* ciPtr = poco->m_graph.getChunkIndices(); - - kj::ArrayPtr<const uint32_t> ciArray(ciPtr, poco->m_graph.m_nodeCount); - graphBulder.setChunkIndices(ciArray); - - kj::ArrayPtr<const uint32_t> adjPart(poco->m_graph.getAdjacencyPartition(), poco->m_graph.m_nodeCount + 1); - graphBulder.setAdjacencyPartition(adjPart); - - NVBLAST_ASSERT(graphBulder.getAdjacencyPartition().size() == poco->m_graph.m_nodeCount + 1); - - kj::ArrayPtr<const uint32_t> nodeIndices(poco->m_graph.getAdjacentNodeIndices(), poco->m_bondCount * 2); - graphBulder.setAdjacentNodeIndices(nodeIndices); - - NVBLAST_ASSERT(graphBulder.getAdjacentNodeIndices().size() == poco->m_bondCount * 2); - - kj::ArrayPtr<const uint32_t> bondIndices(poco->m_graph.getAdjacentBondIndices(), poco->m_bondCount * 2); - graphBulder.setAdjacentBondIndices(bondIndices); - - return true; - } - - Nv::Blast::Asset* AssetDTO::deserialize(Nv::Blast::Serialization::Asset::Reader reader) - { - NvBlastID EmptyId = {}; - - NvBlastExtAlloc allocFn = gAlloc; - NvBlastLog logFn = gLog; - -#if !defined(BLAST_LL_ALLOC) - allocFn = ExtAllocator::alignedAlloc16; - logFn = NvBlastTkFrameworkGet()->getLogFn(); -#endif - - void* mem = allocFn(reader.totalSize().wordCount * sizeof(uint64_t)); - - auto asset = Nv::Blast::initializeAsset(mem, EmptyId, reader.getChunkCount(), reader.getGraph().getNodeCount(), reader.getLeafChunkCount(), reader.getFirstSubsupportChunkIndex(), reader.getBondCount(), - logFn); - - bool result = deserializeInto(reader, asset); - - return result ? asset : nullptr; - } - - bool AssetDTO::deserializeInto(Nv::Blast::Serialization::Asset::Reader reader, Nv::Blast::Asset * poco) - { - NvBlastIDDTO::deserializeInto(reader.getID(), &poco->m_ID); - - NvBlastBond* bonds = poco->getBonds(); - - uint32_t bondCount = reader.getBondCount(); - for (uint32_t i = 0; i < bondCount; i++) - { - auto bondReader = reader.getBonds()[i]; - - NvBlastBondDTO::deserializeInto(bondReader, &bonds[i]); - } - - NvBlastChunk* chunks = poco->getChunks(); - - uint32_t chunkCount = reader.getChunkCount(); - for (uint32_t i = 0; i < chunkCount; i++) - { - auto chunkReader = reader.getChunks()[i]; - - NvBlastChunkDTO::deserializeInto(chunkReader, &chunks[i]); - } - - poco->m_graph.m_nodeCount = reader.getGraph().getNodeCount(); - - NVBLAST_ASSERT(reader.getSubtreeLeafChunkCounts().size() == poco->m_chunkCount); - for (uint32_t i = 0; i < poco->m_chunkCount; i++) - { - poco->getSubtreeLeafChunkCounts()[i] = reader.getSubtreeLeafChunkCounts()[i]; - } - - for (uint32_t i = 0; i < chunkCount; i++) - { - poco->getChunkToGraphNodeMap()[i] = reader.getChunkToGraphNodeMap()[i]; - } - - uint32_t* ciPtr = poco->m_graph.getChunkIndices(); - - NVBLAST_ASSERT(reader.getGraph().getChunkIndices().size() == poco->m_graph.m_nodeCount); - for (uint32_t i = 0; i < poco->m_graph.m_nodeCount; i++) - { - ciPtr[i] = reader.getGraph().getChunkIndices()[i]; - } - - uint32_t* adjPartition = poco->m_graph.getAdjacencyPartition(); - uint32_t idx = 0; - - for (uint32_t adjPartIndex : reader.getGraph().getAdjacencyPartition()) - { - adjPartition[idx++] = adjPartIndex; - } - - uint32_t* adjNodes = poco->m_graph.getAdjacentNodeIndices(); - idx = 0; - - for (uint32_t adjNodeIndex : reader.getGraph().getAdjacentNodeIndices()) - { - adjNodes[idx++] = adjNodeIndex; - } - - uint32_t* adjBonds = poco->m_graph.getAdjacentBondIndices(); - idx = 0; - - for (uint32_t adjBondIndex : reader.getGraph().getAdjacentBondIndices()) - { - adjBonds[idx++] = adjBondIndex; - } - - return true; - } + poco->getSubtreeLeafChunkCounts()[i] = readerSubtreeLeafChunkCounts[i]; } + + auto readerChunkToGraphNodeMap = reader.getChunkToGraphNodeMap(); + for (uint32_t i = 0; i < chunkCount; i++) + { + poco->getChunkToGraphNodeMap()[i] = readerChunkToGraphNodeMap[i]; + } + + uint32_t* ciPtr = poco->m_graph.getChunkIndices(); + + NVBLAST_ASSERT(reader.getGraph().getChunkIndices().size() == poco->m_graph.m_nodeCount); + auto readerGraphChunkIndices = reader.getGraph().getChunkIndices(); + for (uint32_t i = 0; i < poco->m_graph.m_nodeCount; i++) + { + ciPtr[i] = readerGraphChunkIndices[i]; + } + + uint32_t* adjPartition = poco->m_graph.getAdjacencyPartition(); + const uint32_t graphAdjacencyPartitionSize = reader.getGraph().getAdjacencyPartition().size(); + auto readerGraphAdjacencyPartition = reader.getGraph().getAdjacencyPartition(); + for (uint32_t i = 0; i < graphAdjacencyPartitionSize; ++i) + { + adjPartition[i] = readerGraphAdjacencyPartition[i]; + } + + uint32_t* adjNodes = poco->m_graph.getAdjacentNodeIndices(); + const uint32_t graphAdjacentNodeIndicesSize = reader.getGraph().getAdjacentNodeIndices().size(); + auto readerGraphAdjacentNodeIndices = reader.getGraph().getAdjacentNodeIndices(); + for (uint32_t i = 0; i < graphAdjacentNodeIndicesSize; ++i) + { + adjNodes[i] = readerGraphAdjacentNodeIndices[i]; + } + + uint32_t* adjBonds = poco->m_graph.getAdjacentBondIndices(); + const uint32_t graphAdjacentBondIndicesSize = reader.getGraph().getAdjacentBondIndices().size(); + auto readerGraphAdjacentBondIndices = reader.getGraph().getAdjacentBondIndices(); + for (uint32_t i = 0; i < graphAdjacentBondIndicesSize; ++i) + { + adjBonds[i] = readerGraphAdjacentBondIndices[i]; + } + + return true; } + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/AssetDTO.h b/sdk/extensions/serialization/source/DTO/AssetDTO.h index c090b5f..492e847 100644 --- a/sdk/extensions/serialization/source/DTO/AssetDTO.h +++ b/sdk/extensions/serialization/source/DTO/AssetDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "NvBlastAsset.h" -#include "generated/NvBlastExtSerializationLL.capn.h" +#include "generated/NvBlastExtLlSerialization.capn.h" -DTO_CLASS_LL(Asset, Nv::Blast::Asset, Nv::Blast::Serialization::Asset) +DTO_CLASS(Asset, Nv::Blast::Asset, Nv::Blast::Serialization::Asset) diff --git a/sdk/extensions/serialization/source/DTO/DTOMacros.h b/sdk/extensions/serialization/source/DTO/DTOMacros.h index a234aec..b3b71ef 100644 --- a/sdk/extensions/serialization/source/DTO/DTOMacros.h +++ b/sdk/extensions/serialization/source/DTO/DTOMacros.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once @@ -16,29 +34,10 @@ namespace Blast { \ class _NAME ## DTO \ { \ public: \ - static class physx::PxCooking* Cooking; \ - static class physx::PxPhysics* Physics; \ - \ - static bool serialize(_SERIALIZER::Builder builder, const _POCO * poco); \ - static _POCO* deserialize(_SERIALIZER::Reader reader); \ - static bool deserializeInto(_SERIALIZER::Reader reader, _POCO * poco); \ -}; \ -} \ -} \ - \ - -#define DTO_CLASS_LL(_NAME, _POCO, _SERIALIZER) \ -namespace Nv { \ -namespace Blast { \ -class _NAME ## DTO \ -{ \ -public: \ \ static bool serialize(_SERIALIZER::Builder builder, const _POCO * poco); \ static _POCO* deserialize(_SERIALIZER::Reader reader); \ static bool deserializeInto(_SERIALIZER::Reader reader, _POCO * poco); \ }; \ } \ -} \ - \ - +} diff --git a/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp b/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp index cf4cadc..865f141 100644 --- a/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "ExtPxAssetDTO.h" #include "TkAssetDTO.h" @@ -14,65 +32,127 @@ #include "ExtPxSubchunkDTO.h" #include "physics/NvBlastExtPxAssetImpl.h" #include "NvBlastAssert.h" +#include "NvBlast.h" + namespace Nv { - namespace Blast +namespace Blast +{ + +bool ExtPxAssetDTO::serialize(Nv::Blast::Serialization::ExtPxAsset::Builder builder, const Nv::Blast::ExtPxAsset * poco) +{ + TkAssetDTO::serialize(builder.getAsset(), &poco->getTkAsset()); + + auto chunks = builder.initChunks(poco->getChunkCount()); + + for (uint32_t i = 0; i <poco->getChunkCount(); i++) { - bool ExtPxAssetDTO::serialize(Nv::Blast::Serialization::ExtPxAsset::Builder builder, const Nv::Blast::ExtPxAsset * poco) - { - TkAssetDTO::serialize(builder.getAsset(), &poco->getTkAsset()); - - auto chunks = builder.initChunks(poco->getChunkCount()); - - for (uint32_t i = 0; i <poco->getChunkCount(); i++) - { - ExtPxChunkDTO::serialize(chunks[i], &poco->getChunks()[i]); - } - - auto subchunks = builder.initSubchunks(poco->getSubchunkCount()); - - for (uint32_t i = 0; i < poco->getSubchunkCount(); i++) - { - ExtPxSubchunkDTO::serialize(subchunks[i], &poco->getSubchunks()[i]); - } - - return true; - } - - Nv::Blast::ExtPxAsset* ExtPxAssetDTO::deserialize(Nv::Blast::Serialization::ExtPxAsset::Reader reader) + ExtPxChunkDTO::serialize(chunks[i], &poco->getChunks()[i]); + } + + auto subchunks = builder.initSubchunks(poco->getSubchunkCount()); + + for (uint32_t i = 0; i < poco->getSubchunkCount(); i++) + { + ExtPxSubchunkDTO::serialize(subchunks[i], &poco->getSubchunks()[i]); + } + + const NvBlastActorDesc& actorDesc = poco->getDefaultActorDesc(); + + builder.setUniformInitialBondHealth(actorDesc.uniformInitialBondHealth); + + if (actorDesc.initialBondHealths != nullptr) + { + const uint32_t bondCount = poco->getTkAsset().getBondCount(); + kj::ArrayPtr<const float> bondHealthArray(actorDesc.initialBondHealths, bondCount); + builder.initBondHealths(bondCount); + builder.setBondHealths(bondHealthArray); + } + + builder.setUniformInitialLowerSupportChunkHealth(actorDesc.uniformInitialLowerSupportChunkHealth); + + if (actorDesc.initialSupportChunkHealths != nullptr) + { + const uint32_t supportChunkCount = NvBlastAssetGetSupportChunkCount(poco->getTkAsset().getAssetLL(), logLL); + kj::ArrayPtr<const float> supportChunkHealthArray(actorDesc.initialSupportChunkHealths, supportChunkCount); + builder.initSupportChunkHealths(supportChunkCount); + builder.setSupportChunkHealths(supportChunkHealthArray); + } + + return true; +} + + +Nv::Blast::ExtPxAsset* ExtPxAssetDTO::deserialize(Nv::Blast::Serialization::ExtPxAsset::Reader reader) +{ + auto tkAsset = TkAssetDTO::deserialize(reader.getAsset()); + + Nv::Blast::ExtPxAssetImpl* asset = reinterpret_cast<Nv::Blast::ExtPxAssetImpl*>(Nv::Blast::ExtPxAsset::create(tkAsset)); + + NVBLAST_ASSERT(asset != nullptr); + + auto& chunks = asset->getChunksArray(); + const uint32_t chunkCount = reader.getChunks().size(); + chunks.resize(chunkCount); + auto readerChunks = reader.getChunks(); + for (uint32_t i = 0; i < chunkCount; i++) + { + ExtPxChunkDTO::deserializeInto(readerChunks[i], &chunks[i]); + } + + auto& subchunks = asset->getSubchunksArray(); + const uint32_t subChunkCount = reader.getSubchunks().size(); + subchunks.resize(subChunkCount); + auto readerSubchunks = reader.getSubchunks(); + for (uint32_t i = 0; i < subChunkCount; i++) + { + ExtPxSubchunkDTO::deserializeInto(readerSubchunks[i], &subchunks[i]); + } + + NvBlastActorDesc& actorDesc = asset->getDefaultActorDesc(); + + actorDesc.uniformInitialBondHealth = reader.getUniformInitialBondHealth(); + + actorDesc.initialBondHealths = nullptr; + if (reader.hasBondHealths()) + { + const uint32_t bondCount = asset->getTkAsset().getBondCount(); + Nv::Blast::Array<float>::type& bondHealths = asset->getBondHealthsArray(); + bondHealths.resize(bondCount); + auto readerBondHealths = reader.getBondHealths(); + for (uint32_t i = 0; i < bondCount; ++i) { - auto tkAsset = TkAssetDTO::deserialize(reader.getAsset()); - - Nv::Blast::ExtPxAssetImpl* asset = reinterpret_cast<Nv::Blast::ExtPxAssetImpl*>(Nv::Blast::ExtPxAsset::create(tkAsset)); - - NVBLAST_ASSERT(asset != nullptr); - - auto chunks = asset->getChunksArray(); - - chunks.resize(reader.getChunks().size()); - for (uint32_t i = 0; i < reader.getChunks().size(); i++) - { - ExtPxChunkDTO::deserializeInto(reader.getChunks()[i], &chunks[i]); - } - - auto subchunks = asset->getSubchunksArray(); - - subchunks.resize(reader.getSubchunks().size()); - for (uint32_t i = 0; i < reader.getSubchunks().size(); i++) - { - ExtPxSubchunkDTO::deserializeInto(reader.getSubchunks()[i], &subchunks[i]); - } - - return asset; + bondHealths[i] = readerBondHealths[i]; } - - bool ExtPxAssetDTO::deserializeInto(Nv::Blast::Serialization::ExtPxAsset::Reader reader, Nv::Blast::ExtPxAsset * poco) + } + + actorDesc.uniformInitialLowerSupportChunkHealth = reader.getUniformInitialLowerSupportChunkHealth(); + + actorDesc.initialSupportChunkHealths = nullptr; + if (reader.hasSupportChunkHealths()) + { + const uint32_t supportChunkCount = NvBlastAssetGetSupportChunkCount(asset->getTkAsset().getAssetLL(), logLL); + Nv::Blast::Array<float>::type& supportChunkHealths = asset->getSupportChunkHealthsArray(); + supportChunkHealths.resize(supportChunkCount); + auto readerSupportChunkHealths = reader.getSupportChunkHealths(); + for (uint32_t i = 0; i < supportChunkCount; ++i) { - reader = reader; - poco = nullptr; - //NOTE: Because of the way this is structured, can't do this. - return false; + supportChunkHealths[i] = readerSupportChunkHealths[i]; } } + + return asset; +} + + +bool ExtPxAssetDTO::deserializeInto(Nv::Blast::Serialization::ExtPxAsset::Reader reader, Nv::Blast::ExtPxAsset * poco) +{ + reader = reader; + poco = nullptr; + //NOTE: Because of the way this is structured, can't do this. + return false; } + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.h b/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.h index a35d38a..9729ec9 100644 --- a/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.h +++ b/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "NvBlastBondDTO.h" #include "NvBlastExtPxAsset.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" DTO_CLASS(ExtPxAsset, Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset) diff --git a/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp b/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp index e096bc1..74333b6 100644 --- a/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp @@ -1,43 +1,65 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "ExtPxChunkDTO.h" namespace Nv { - namespace Blast - { - bool ExtPxChunkDTO::serialize(Nv::Blast::Serialization::ExtPxChunk::Builder builder, const Nv::Blast::ExtPxChunk * poco) - { - builder.setFirstSubchunkIndex(poco->firstSubchunkIndex); - builder.setSubchunkCount(poco->subchunkCount); - builder.setIsStatic(poco->isStatic); - - return true; - } - - Nv::Blast::ExtPxChunk* ExtPxChunkDTO::deserialize(Nv::Blast::Serialization::ExtPxChunk::Reader reader) - { - reader = reader; - //TODO: Allocate with ExtContext and return - - return nullptr; - } - - bool ExtPxChunkDTO::deserializeInto(Nv::Blast::Serialization::ExtPxChunk::Reader reader, Nv::Blast::ExtPxChunk * poco) - { - poco->firstSubchunkIndex = reader.getFirstSubchunkIndex(); - poco->subchunkCount = reader.getSubchunkCount(); - poco->isStatic = reader.getIsStatic(); - - return true; - } - } -}
\ No newline at end of file +namespace Blast +{ + +bool ExtPxChunkDTO::serialize(Nv::Blast::Serialization::ExtPxChunk::Builder builder, const Nv::Blast::ExtPxChunk * poco) +{ + builder.setFirstSubchunkIndex(poco->firstSubchunkIndex); + builder.setSubchunkCount(poco->subchunkCount); + builder.setIsStatic(poco->isStatic); + + return true; +} + + +Nv::Blast::ExtPxChunk* ExtPxChunkDTO::deserialize(Nv::Blast::Serialization::ExtPxChunk::Reader reader) +{ + reader = reader; + //TODO: Allocate with ExtContext and return + + return nullptr; +} + + +bool ExtPxChunkDTO::deserializeInto(Nv::Blast::Serialization::ExtPxChunk::Reader reader, Nv::Blast::ExtPxChunk * poco) +{ + poco->firstSubchunkIndex = reader.getFirstSubchunkIndex(); + poco->subchunkCount = reader.getSubchunkCount(); + poco->isStatic = reader.getIsStatic(); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.h b/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.h index 1ff36df..e9935c3 100644 --- a/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.h +++ b/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "NvBlastExtPxAsset.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" DTO_CLASS(ExtPxChunk, Nv::Blast::ExtPxChunk, Nv::Blast::Serialization::ExtPxChunk) diff --git a/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp b/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp index cc2be96..c3e290b 100644 --- a/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp @@ -1,43 +1,66 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "ExtPxSubchunkDTO.h" #include "PxTransformDTO.h" #include "PxConvexMeshGeometryDTO.h" + namespace Nv { - namespace Blast - { - bool ExtPxSubchunkDTO::serialize(Nv::Blast::Serialization::ExtPxSubchunk::Builder builder, const Nv::Blast::ExtPxSubchunk * poco) - { - PxTransformDTO::serialize(builder.getTransform(), &poco->transform); - PxConvexMeshGeometryDTO::serialize(builder.getGeometry(), &poco->geometry); - - return true; - } - - Nv::Blast::ExtPxSubchunk* ExtPxSubchunkDTO::deserialize(Nv::Blast::Serialization::ExtPxSubchunk::Reader reader) - { - reader = reader; - //TODO: Allocate with ExtContext and return - - return nullptr; - } - - bool ExtPxSubchunkDTO::deserializeInto(Nv::Blast::Serialization::ExtPxSubchunk::Reader reader, Nv::Blast::ExtPxSubchunk * poco) - { - PxTransformDTO::deserializeInto(reader.getTransform(), &poco->transform); - - return true; - } - - } +namespace Blast +{ + +bool ExtPxSubchunkDTO::serialize(Nv::Blast::Serialization::ExtPxSubchunk::Builder builder, const Nv::Blast::ExtPxSubchunk * poco) +{ + PxTransformDTO::serialize(builder.getTransform(), &poco->transform); + PxConvexMeshGeometryDTO::serialize(builder.getGeometry(), &poco->geometry); + + return true; } + + +Nv::Blast::ExtPxSubchunk* ExtPxSubchunkDTO::deserialize(Nv::Blast::Serialization::ExtPxSubchunk::Reader reader) +{ + reader = reader; + //TODO: Allocate with ExtContext and return + + return nullptr; +} + + +bool ExtPxSubchunkDTO::deserializeInto(Nv::Blast::Serialization::ExtPxSubchunk::Reader reader, Nv::Blast::ExtPxSubchunk * poco) +{ + PxTransformDTO::deserializeInto(reader.getTransform(), &poco->transform); + PxConvexMeshGeometryDTO::deserializeInto(reader.getGeometry(), &poco->geometry); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.h b/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.h index 91f78e0..72b6c24 100644 --- a/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.h +++ b/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "NvBlastExtPxAsset.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" #include "DTOMacros.h" DTO_CLASS(ExtPxSubchunk, Nv::Blast::ExtPxSubchunk, Nv::Blast::Serialization::ExtPxSubchunk) diff --git a/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp b/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp index 27cbb11..7865eb3 100644 --- a/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp @@ -1,63 +1,86 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastBondDTO.h" #include "NvBlastAssert.h" namespace Nv { - namespace Blast - { - - bool NvBlastBondDTO::serialize(Nv::Blast::Serialization::NvBlastBond::Builder builder, const NvBlastBond * poco) - { - NVBLAST_ASSERT(poco != nullptr); - - kj::ArrayPtr<const float> normArray(poco->normal, 3); - - builder.setNormal(normArray); - - builder.setArea(poco->area); - - kj::ArrayPtr<const float> centArray(poco->centroid, 3); - - builder.setCentroid(centArray); - - builder.setUserData(poco->userData); - - return true; - } - - NvBlastBond* NvBlastBondDTO::deserialize(Nv::Blast::Serialization::NvBlastBond::Reader reader) - { - //FIXME - reader = reader; - //TODO: Allocate with ExtContext and return - return nullptr; - } - - bool NvBlastBondDTO::deserializeInto(Nv::Blast::Serialization::NvBlastBond::Reader reader, NvBlastBond * poco) - { - poco->area = reader.getArea(); - - poco->centroid[0] = reader.getCentroid()[0]; - poco->centroid[1] = reader.getCentroid()[1]; - poco->centroid[2] = reader.getCentroid()[2]; - - poco->normal[0] = reader.getNormal()[0]; - poco->normal[1] = reader.getNormal()[1]; - poco->normal[2] = reader.getNormal()[2]; - - poco->userData = reader.getUserData(); - - return true; - } - } +namespace Blast +{ + +bool NvBlastBondDTO::serialize(Nv::Blast::Serialization::NvBlastBond::Builder builder, const NvBlastBond * poco) +{ + NVBLAST_ASSERT(poco != nullptr); + + kj::ArrayPtr<const float> normArray(poco->normal, 3); + + builder.setNormal(normArray); + + builder.setArea(poco->area); + + kj::ArrayPtr<const float> centArray(poco->centroid, 3); + + builder.setCentroid(centArray); + + builder.setUserData(poco->userData); + + return true; +} + + +NvBlastBond* NvBlastBondDTO::deserialize(Nv::Blast::Serialization::NvBlastBond::Reader reader) +{ + //FIXME + reader = reader; + //TODO: Allocate with ExtContext and return + return nullptr; +} + + +bool NvBlastBondDTO::deserializeInto(Nv::Blast::Serialization::NvBlastBond::Reader reader, NvBlastBond * poco) +{ + poco->area = reader.getArea(); + + auto readerCentroid = reader.getCentroid(); + poco->centroid[0] = readerCentroid[0]; + poco->centroid[1] = readerCentroid[1]; + poco->centroid[2] = readerCentroid[2]; + + auto readerNormal = reader.getNormal(); + poco->normal[0] = readerNormal[0]; + poco->normal[1] = readerNormal[1]; + poco->normal[2] = readerNormal[2]; + + poco->userData = reader.getUserData(); + + return true; } + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.h b/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.h index 8b67bd7..3a8e0d1 100644 --- a/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.h +++ b/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "NvBlastTypes.h" -#include "generated/NvBlastExtSerializationLL.capn.h" +#include "generated/NvBlastExtLlSerialization.capn.h" -DTO_CLASS_LL(NvBlastBond, NvBlastBond, Nv::Blast::Serialization::NvBlastBond) +DTO_CLASS(NvBlastBond, NvBlastBond, Nv::Blast::Serialization::NvBlastBond) diff --git a/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp b/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp index 38814ed..71924f3 100644 --- a/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp @@ -1,60 +1,83 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastChunkDTO.h" #include "NvBlastAssert.h" namespace Nv { - namespace Blast - { - bool NvBlastChunkDTO::serialize(Nv::Blast::Serialization::NvBlastChunk::Builder builder, const NvBlastChunk* poco) - { - NVBLAST_ASSERT(poco != nullptr); - - kj::ArrayPtr<const float> centArray(poco->centroid, 3); - builder.setCentroid(centArray); - - builder.setVolume(poco->volume); - - builder.setParentChunkIndex(poco->parentChunkIndex); - builder.setFirstChildIndex(poco->firstChildIndex); - builder.setChildIndexStop(poco->childIndexStop); - builder.setUserData(poco->userData); - - return true; - } - - NvBlastChunk* NvBlastChunkDTO::deserialize(Nv::Blast::Serialization::NvBlastChunk::Reader reader) - { - //FIXME - reader = reader; - - return nullptr; - } - - bool NvBlastChunkDTO::deserializeInto(Nv::Blast::Serialization::NvBlastChunk::Reader reader, NvBlastChunk* target) - { - NVBLAST_ASSERT(target != nullptr); - - target->centroid[0] = reader.getCentroid()[0]; - target->centroid[1] = reader.getCentroid()[1]; - target->centroid[2] = reader.getCentroid()[2]; - - target->childIndexStop = reader.getChildIndexStop(); - target->firstChildIndex = reader.getFirstChildIndex(); - target->parentChunkIndex = reader.getParentChunkIndex(); - target->userData = reader.getUserData(); - target->volume = reader.getVolume(); - - return true; - } - } +namespace Blast +{ + +bool NvBlastChunkDTO::serialize(Nv::Blast::Serialization::NvBlastChunk::Builder builder, const NvBlastChunk* poco) +{ + NVBLAST_ASSERT(poco != nullptr); + + kj::ArrayPtr<const float> centArray(poco->centroid, 3); + builder.setCentroid(centArray); + + builder.setVolume(poco->volume); + + builder.setParentChunkIndex(poco->parentChunkIndex); + builder.setFirstChildIndex(poco->firstChildIndex); + builder.setChildIndexStop(poco->childIndexStop); + builder.setUserData(poco->userData); + + return true; } + + +NvBlastChunk* NvBlastChunkDTO::deserialize(Nv::Blast::Serialization::NvBlastChunk::Reader reader) +{ + //FIXME + reader = reader; + + return nullptr; +} + + +bool NvBlastChunkDTO::deserializeInto(Nv::Blast::Serialization::NvBlastChunk::Reader reader, NvBlastChunk* target) +{ + NVBLAST_ASSERT(target != nullptr); + + auto readerCentroid = reader.getCentroid(); + target->centroid[0] = readerCentroid[0]; + target->centroid[1] = readerCentroid[1]; + target->centroid[2] = readerCentroid[2]; + + target->childIndexStop = reader.getChildIndexStop(); + target->firstChildIndex = reader.getFirstChildIndex(); + target->parentChunkIndex = reader.getParentChunkIndex(); + target->userData = reader.getUserData(); + target->volume = reader.getVolume(); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.h b/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.h index 5fec498..e4c3f1f 100644 --- a/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.h +++ b/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.h @@ -1,18 +1,36 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "NvBlastTypes.h" -#include "generated/NvBlastExtSerializationLL.capn.h" +#include "generated/NvBlastExtLlSerialization.capn.h" -DTO_CLASS_LL(NvBlastChunk, NvBlastChunk, Nv::Blast::Serialization::NvBlastChunk) +DTO_CLASS(NvBlastChunk, NvBlastChunk, Nv::Blast::Serialization::NvBlastChunk) diff --git a/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp b/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp index e540cd8..0be5863 100644 --- a/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp @@ -1,48 +1,70 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastIDDTO.h" #include "NvBlastTypes.h" #include "NvBlastAssert.h" -#include "generated/NvBlastExtSerializationLL.capn.h" +#include "generated/NvBlastExtLlSerialization.capn.h" namespace Nv { - namespace Blast - { - - bool NvBlastIDDTO::serialize(Nv::Blast::Serialization::UUID::Builder builder, const NvBlastID * poco) - { - capnp::Data::Reader idArrayReader((unsigned char *)poco->data, 16); - builder.setValue(idArrayReader); - - return true; - } - - NvBlastID* NvBlastIDDTO::deserialize(Nv::Blast::Serialization::UUID::Reader reader) - { - //FIXME - reader = reader; - //TODO: Allocate with ExtContext and return - - return nullptr; - } - - bool NvBlastIDDTO::deserializeInto(Nv::Blast::Serialization::UUID::Reader reader, NvBlastID * poco) - { - NVBLAST_ASSERT_WITH_MESSAGE(reader.getValue().size() == 16, "BlastID must be 16 bytes"); - - memcpy(poco, reader.getValue().begin(), 16); - - return true; - } - } -}
\ No newline at end of file +namespace Blast +{ + + +bool NvBlastIDDTO::serialize(Nv::Blast::Serialization::UUID::Builder builder, const NvBlastID * poco) +{ + capnp::Data::Reader idArrayReader((unsigned char *)poco->data, 16); + builder.setValue(idArrayReader); + + return true; +} + + +NvBlastID* NvBlastIDDTO::deserialize(Nv::Blast::Serialization::UUID::Reader reader) +{ + //FIXME + reader = reader; + //TODO: Allocate with ExtContext and return + + return nullptr; +} + + +bool NvBlastIDDTO::deserializeInto(Nv::Blast::Serialization::UUID::Reader reader, NvBlastID * poco) +{ + NVBLAST_ASSERT_WITH_MESSAGE(reader.getValue().size() == 16, "BlastID must be 16 bytes"); + + memcpy(poco, reader.getValue().begin(), 16); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.h b/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.h index afe6cf0..ac4b1c0 100644 --- a/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.h +++ b/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "NvBlastTypes.h" -#include "generated/NvBlastExtSerializationLL.capn.h" +#include "generated/NvBlastExtLlSerialization.capn.h" #include "DTOMacros.h" -DTO_CLASS_LL(NvBlastID, NvBlastID, ::Nv::Blast::Serialization::UUID) +DTO_CLASS(NvBlastID, NvBlastID, ::Nv::Blast::Serialization::UUID) diff --git a/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp b/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp index 1c46f9e..099e458 100644 --- a/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "PxConvexMeshGeometryDTO.h" #include "PxMeshScaleDTO.h" @@ -17,111 +35,108 @@ #include "NvBlastExtSerialization.h" #include "PxVec3.h" #include <algorithm> +#include <vector> #include "PxPhysics.h" +#include "NvBlastPxCallbacks.h" +#include "PxDefaultStreams.h" namespace Nv { - namespace Blast - { - physx::PxCooking* PxConvexMeshGeometryDTO::Cooking = nullptr; - physx::PxPhysics* PxConvexMeshGeometryDTO::Physics = nullptr; +namespace Blast +{ + +extern physx::PxPhysics* sExtPxSerializerPhysics; +extern physx::PxCooking* sExtPxSerializerCooking; + + +bool PxConvexMeshGeometryDTO::serialize(Nv::Blast::Serialization::PxConvexMeshGeometry::Builder builder, const physx::PxConvexMeshGeometry * poco) +{ + NVBLAST_ASSERT(sExtPxSerializerCooking != nullptr); + + PxMeshScaleDTO::serialize(builder.getScale(), &poco->scale); + + //TODO: Use cooking.cookConvexMesh to cook the mesh to a stream - then get that backing buffer and put it into the Data field - bool PxConvexMeshGeometryDTO::serialize(Nv::Blast::Serialization::PxConvexMeshGeometry::Builder builder, const physx::PxConvexMeshGeometry * poco) + physx::PxConvexMeshDesc desc; + desc.points.data = poco->convexMesh->getVertices(); + desc.points.count = poco->convexMesh->getNbVertices(); + desc.points.stride = sizeof(physx::PxVec3); + + std::vector<uint32_t> indicesScratch; + std::vector<physx::PxHullPolygon> hullPolygonsScratch; + + hullPolygonsScratch.resize(poco->convexMesh->getNbPolygons()); + + uint32_t indexCount = 0; + for (uint32_t i = 0; i < hullPolygonsScratch.size(); i++) + { + physx::PxHullPolygon polygon; + poco->convexMesh->getPolygonData(i, polygon); + if (polygon.mNbVerts) { - PxMeshScaleDTO::serialize(builder.getScale(), &poco->scale); - - //TODO: Use cooking.cookConvexMesh to cook the mesh to a stream - then get that backing buffer and put it into the Data field - - physx::PxConvexMeshDesc desc; - desc.points.data = poco->convexMesh->getVertices(); - desc.points.count = poco->convexMesh->getNbVertices(); - desc.points.stride = sizeof(physx::PxVec3); - - std::vector<uint32_t> indicesScratch; - std::vector<physx::PxHullPolygon> hullPolygonsScratch; - - hullPolygonsScratch.resize(poco->convexMesh->getNbPolygons()); - - uint32_t indexCount = 0; - for (uint32_t i = 0; i < hullPolygonsScratch.size(); i++) - { - physx::PxHullPolygon polygon; - poco->convexMesh->getPolygonData(i, polygon); - if (polygon.mNbVerts) - { - indexCount = std::max<uint32_t>(indexCount, polygon.mIndexBase + polygon.mNbVerts); - } - } - indicesScratch.resize(indexCount); - - for (uint32_t i = 0; i < hullPolygonsScratch.size(); i++) - { - physx::PxHullPolygon polygon; - poco->convexMesh->getPolygonData(i, polygon); - for (uint32_t j = 0; j < polygon.mNbVerts; j++) - { - indicesScratch[polygon.mIndexBase + j] = poco->convexMesh->getIndexBuffer()[polygon.mIndexBase + j]; - } - - hullPolygonsScratch[i] = polygon; - } - - desc.indices.count = indexCount; - desc.indices.data = indicesScratch.data(); - desc.indices.stride = sizeof(uint32_t); - - desc.polygons.count = poco->convexMesh->getNbPolygons(); - desc.polygons.data = hullPolygonsScratch.data(); - desc.polygons.stride = sizeof(physx::PxHullPolygon); - - - std::vector<unsigned char> buffer; - buffer.resize(16 * 1024 * 1024); // No idea how much memory is needed! Allocate 16MB - kj::ArrayPtr<unsigned char> bufferArray(buffer.data(), buffer.size()); - - Nv::Blast::ExtKJPxOutputStream outputStream(bufferArray); - - bool cookResult = Cooking->cookConvexMesh(desc, outputStream); - - if (!cookResult) - { - return false; - } - - kj::ArrayPtr<unsigned char> cookedBuffer(outputStream.getBuffer().begin(), outputStream.getWrittenBytes()); - - builder.setConvexMesh(cookedBuffer); - - // builder.getConvexMesh(). - - return true; + indexCount = std::max<uint32_t>(indexCount, polygon.mIndexBase + polygon.mNbVerts); } - - physx::PxConvexMeshGeometry* PxConvexMeshGeometryDTO::deserialize(Nv::Blast::Serialization::PxConvexMeshGeometry::Reader reader) - { - NVBLAST_ASSERT(PxConvexMeshGeometryDTO::Cooking != nullptr); - - reader = reader; - - return nullptr; - } - - bool PxConvexMeshGeometryDTO::deserializeInto(Nv::Blast::Serialization::PxConvexMeshGeometry::Reader reader, physx::PxConvexMeshGeometry * poco) + } + indicesScratch.resize(indexCount); + + for (uint32_t i = 0; i < hullPolygonsScratch.size(); i++) + { + physx::PxHullPolygon polygon; + poco->convexMesh->getPolygonData(i, polygon); + for (uint32_t j = 0; j < polygon.mNbVerts; j++) { - NVBLAST_ASSERT(PxConvexMeshGeometryDTO::Cooking != nullptr); - - PxMeshScaleDTO::deserializeInto(reader.getScale(), &poco->scale); - - Nv::Blast::ExtKJPxInputStream inputStream(reader.getConvexMesh()); - - //NOTE: Naive approach, no shared convex hulls - poco->convexMesh = Physics->createConvexMesh(inputStream); - - return false; + indicesScratch[polygon.mIndexBase + j] = poco->convexMesh->getIndexBuffer()[polygon.mIndexBase + j]; } + + hullPolygonsScratch[i] = polygon; + } + + desc.indices.count = indexCount; + desc.indices.data = indicesScratch.data(); + desc.indices.stride = sizeof(uint32_t); + + desc.polygons.count = poco->convexMesh->getNbPolygons(); + desc.polygons.data = hullPolygonsScratch.data(); + desc.polygons.stride = sizeof(physx::PxHullPolygon); - - + physx::PxDefaultMemoryOutputStream outStream(NvBlastGetPxAllocatorCallback()); + if (!sExtPxSerializerCooking->cookConvexMesh(desc, outStream)) + { + return false; } + + kj::ArrayPtr<unsigned char> cookedBuffer(outStream.getData(), outStream.getSize()); + + builder.setConvexMesh(cookedBuffer); + + return true; } + + +physx::PxConvexMeshGeometry* PxConvexMeshGeometryDTO::deserialize(Nv::Blast::Serialization::PxConvexMeshGeometry::Reader reader) +{ + NVBLAST_ASSERT(sExtPxSerializerCooking != nullptr); + + reader = reader; + + return nullptr; +} + + +bool PxConvexMeshGeometryDTO::deserializeInto(Nv::Blast::Serialization::PxConvexMeshGeometry::Reader reader, physx::PxConvexMeshGeometry * poco) +{ + NVBLAST_ASSERT(sExtPxSerializerPhysics != nullptr); + + PxMeshScaleDTO::deserializeInto(reader.getScale(), &poco->scale); + + Nv::Blast::ExtKJPxInputStream inputStream(reader.getConvexMesh()); + + //NOTE: Naive approach, no shared convex hulls + poco->convexMesh = sExtPxSerializerPhysics->createConvexMesh(inputStream); + + return poco->convexMesh != nullptr; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.h b/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.h index 27b3754..0628518 100644 --- a/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.h +++ b/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.h @@ -1,16 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" #include "PxConvexMeshGeometry.h" #include "PxCooking.h" diff --git a/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp b/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp index 8fee6ad..76f0d90 100644 --- a/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp @@ -1,42 +1,64 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "PxMeshScaleDTO.h" #include "PxVec3DTO.h" #include "PxQuatDTO.h" + namespace Nv { - namespace Blast - { - bool PxMeshScaleDTO::serialize(Nv::Blast::Serialization::PxMeshScale::Builder builder, const physx::PxMeshScale * poco) - { - PxVec3DTO::serialize(builder.getScale(), &poco->scale); - PxQuatDTO::serialize(builder.getRotation(), &poco->rotation); - - return true; - } - - physx::PxMeshScale* PxMeshScaleDTO::deserialize(Nv::Blast::Serialization::PxMeshScale::Reader reader) - { - reader = reader; - return nullptr; - } - - bool PxMeshScaleDTO::deserializeInto(Nv::Blast::Serialization::PxMeshScale::Reader reader, physx::PxMeshScale * poco) - { - PxVec3DTO::deserializeInto(reader.getScale(), &poco->scale); - PxQuatDTO::deserializeInto(reader.getRotation(), &poco->rotation); - - return true; - } - } +namespace Blast +{ + +bool PxMeshScaleDTO::serialize(Nv::Blast::Serialization::PxMeshScale::Builder builder, const physx::PxMeshScale * poco) +{ + PxVec3DTO::serialize(builder.getScale(), &poco->scale); + PxQuatDTO::serialize(builder.getRotation(), &poco->rotation); + + return true; +} + + +physx::PxMeshScale* PxMeshScaleDTO::deserialize(Nv::Blast::Serialization::PxMeshScale::Reader reader) +{ + reader = reader; + return nullptr; +} + + +bool PxMeshScaleDTO::deserializeInto(Nv::Blast::Serialization::PxMeshScale::Reader reader, physx::PxMeshScale * poco) +{ + PxVec3DTO::deserializeInto(reader.getScale(), &poco->scale); + PxQuatDTO::deserializeInto(reader.getRotation(), &poco->rotation); + + return true; } +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.h b/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.h index 7b758c8..bf3c521 100644 --- a/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.h +++ b/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.h @@ -1,17 +1,35 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "PxMeshScale.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" #include "PxCooking.h" DTO_CLASS(PxMeshScale, physx::PxMeshScale, Nv::Blast::Serialization::PxMeshScale) diff --git a/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp b/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp index 8faeaa6..05490af 100644 --- a/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp @@ -1,45 +1,65 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "PxQuatDTO.h" namespace Nv { - namespace Blast - { - - bool PxQuatDTO::serialize(Nv::Blast::Serialization::PxQuat::Builder builder, const physx::PxQuat * poco) - { - builder.setX(poco->x); - builder.setY(poco->y); - builder.setZ(poco->z); - builder.setW(poco->w); - - return true; - } - - physx::PxQuat* PxQuatDTO::deserialize(Nv::Blast::Serialization::PxQuat::Reader reader) - { - reader = reader; - return nullptr; - } - - bool PxQuatDTO::deserializeInto(Nv::Blast::Serialization::PxQuat::Reader reader, physx::PxQuat * poco) - { - poco->x = reader.getX(); - poco->y = reader.getY(); - poco->z = reader.getZ(); - poco->w = reader.getW(); - - return true; - } - - } +namespace Blast +{ + +bool PxQuatDTO::serialize(Nv::Blast::Serialization::PxQuat::Builder builder, const physx::PxQuat * poco) +{ + builder.setX(poco->x); + builder.setY(poco->y); + builder.setZ(poco->z); + builder.setW(poco->w); + + return true; } + + +physx::PxQuat* PxQuatDTO::deserialize(Nv::Blast::Serialization::PxQuat::Reader reader) +{ + reader = reader; + return nullptr; +} + + +bool PxQuatDTO::deserializeInto(Nv::Blast::Serialization::PxQuat::Reader reader, physx::PxQuat * poco) +{ + poco->x = reader.getX(); + poco->y = reader.getY(); + poco->z = reader.getZ(); + poco->w = reader.getW(); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/PxQuatDTO.h b/sdk/extensions/serialization/source/DTO/PxQuatDTO.h index 460d6c5..b7d15b9 100644 --- a/sdk/extensions/serialization/source/DTO/PxQuatDTO.h +++ b/sdk/extensions/serialization/source/DTO/PxQuatDTO.h @@ -1,17 +1,35 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "PxQuat.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" #include "PxCooking.h" DTO_CLASS(PxQuat, physx::PxQuat, Nv::Blast::Serialization::PxQuat) diff --git a/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp b/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp index 20a7cbb..0b1a240 100644 --- a/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "PxTransformDTO.h" #include "PxQuatDTO.h" @@ -14,29 +32,32 @@ namespace Nv { - namespace Blast - { - - bool PxTransformDTO::serialize(Nv::Blast::Serialization::PxTransform::Builder builder, const physx::PxTransform * poco) - { - PxQuatDTO::serialize(builder.getQ(), &poco->q); - PxVec3DTO::serialize(builder.getP(), &poco->p); - - return true; - } - - physx::PxTransform* PxTransformDTO::deserialize(Nv::Blast::Serialization::PxTransform::Reader reader) - { - reader = reader; - return nullptr; - } - - bool PxTransformDTO::deserializeInto(Nv::Blast::Serialization::PxTransform::Reader reader, physx::PxTransform * poco) - { - PxQuatDTO::deserializeInto(reader.getQ(), &poco->q); - PxVec3DTO::deserializeInto(reader.getP(), &poco->p); +namespace Blast +{ - return true; - } - } +bool PxTransformDTO::serialize(Nv::Blast::Serialization::PxTransform::Builder builder, const physx::PxTransform * poco) +{ + PxQuatDTO::serialize(builder.getQ(), &poco->q); + PxVec3DTO::serialize(builder.getP(), &poco->p); + + return true; +} + + +physx::PxTransform* PxTransformDTO::deserialize(Nv::Blast::Serialization::PxTransform::Reader reader) +{ + reader = reader; + return nullptr; } + + +bool PxTransformDTO::deserializeInto(Nv::Blast::Serialization::PxTransform::Reader reader, physx::PxTransform * poco) +{ + PxQuatDTO::deserializeInto(reader.getQ(), &poco->q); + PxVec3DTO::deserializeInto(reader.getP(), &poco->p); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/PxTransformDTO.h b/sdk/extensions/serialization/source/DTO/PxTransformDTO.h index 49a6b73..3523375 100644 --- a/sdk/extensions/serialization/source/DTO/PxTransformDTO.h +++ b/sdk/extensions/serialization/source/DTO/PxTransformDTO.h @@ -1,17 +1,35 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "PxTransform.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" #include "PxCooking.h" DTO_CLASS(PxTransform, physx::PxTransform, Nv::Blast::Serialization::PxTransform) diff --git a/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp b/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp index 9827cd0..995bb44 100644 --- a/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp @@ -1,45 +1,65 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "PxVec3DTO.h" #include "NvBlastAssert.h" namespace Nv { - namespace Blast - { - bool PxVec3DTO::serialize(Nv::Blast::Serialization::PxVec3::Builder builder, const physx::PxVec3 * poco) - { - NVBLAST_ASSERT(poco != nullptr); - - builder.setX(poco->x); - builder.setY(poco->y); - builder.setZ(poco->z); - - return true; - } - - physx::PxVec3* PxVec3DTO::deserialize(Nv::Blast::Serialization::PxVec3::Reader reader) - { - //TODO: Allocate using ExtContext and return - reader = reader; - return nullptr; - } - - bool PxVec3DTO::deserializeInto(Nv::Blast::Serialization::PxVec3::Reader reader, physx::PxVec3* target) - { - target->x = reader.getX(); - target->y = reader.getY(); - target->z = reader.getZ(); - - return true; - } - } +namespace Blast +{ + +bool PxVec3DTO::serialize(Nv::Blast::Serialization::PxVec3::Builder builder, const physx::PxVec3 * poco) +{ + NVBLAST_ASSERT(poco != nullptr); + + builder.setX(poco->x); + builder.setY(poco->y); + builder.setZ(poco->z); + + return true; +} + +physx::PxVec3* PxVec3DTO::deserialize(Nv::Blast::Serialization::PxVec3::Reader reader) +{ + //TODO: Allocate using ExtContext and return + reader = reader; + return nullptr; } + +bool PxVec3DTO::deserializeInto(Nv::Blast::Serialization::PxVec3::Reader reader, physx::PxVec3* target) +{ + target->x = reader.getX(); + target->y = reader.getY(); + target->z = reader.getZ(); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/PxVec3DTO.h b/sdk/extensions/serialization/source/DTO/PxVec3DTO.h index 8a04c8b..84fce39 100644 --- a/sdk/extensions/serialization/source/DTO/PxVec3DTO.h +++ b/sdk/extensions/serialization/source/DTO/PxVec3DTO.h @@ -1,17 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtTkSerialization.capn.h" #include "PxVec3.h" -#include "PxCooking.h" DTO_CLASS(PxVec3, physx::PxVec3, Nv::Blast::Serialization::PxVec3) diff --git a/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp b/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp index acc55ba..7ba6d4f 100644 --- a/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp @@ -1,67 +1,94 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "TkAssetDTO.h" #include "AssetDTO.h" #include "TkAssetJointDescDTO.h" #include <vector> #include "NvBlastTkFramework.h" - +#include "NvBlastGlobals.h" namespace Nv { - namespace Blast +namespace Blast +{ + +extern TkFramework* sExtTkSerializerFramework; + + +bool TkAssetDTO::serialize(Nv::Blast::Serialization::TkAsset::Builder builder, const Nv::Blast::TkAsset * poco) +{ + const Asset* assetLL = reinterpret_cast<const Nv::Blast::Asset*>(poco->getAssetLL()); + + Nv::Blast::AssetDTO::serialize(builder.getAssetLL(), assetLL); + + uint32_t jointDescCount = poco->getJointDescCount(); + + capnp::List<Nv::Blast::Serialization::TkAssetJointDesc>::Builder jointDescs = builder.initJointDescs(jointDescCount); + + for (uint32_t i = 0; i < jointDescCount; i++) { - bool TkAssetDTO::serialize(Nv::Blast::Serialization::TkAsset::Builder builder, const Nv::Blast::TkAsset * poco) - { - const Asset* assetLL = reinterpret_cast<const Nv::Blast::Asset*>(poco->getAssetLL()); - - Nv::Blast::AssetDTO::serialize(builder.getAssetLL(), assetLL); - - uint32_t jointDescCount = poco->getJointDescCount(); - - capnp::List<Nv::Blast::Serialization::TkAssetJointDesc>::Builder jointDescs = builder.initJointDescs(jointDescCount); - - for (uint32_t i = 0; i < jointDescCount; i++) - { - TkAssetJointDescDTO::serialize(jointDescs[i], &poco->getJointDescs()[i]); - } - - return true; - } - - Nv::Blast::TkAsset* TkAssetDTO::deserialize(Nv::Blast::Serialization::TkAsset::Reader reader) - { - const NvBlastAsset* assetLL = reinterpret_cast<const NvBlastAsset*>(AssetDTO::deserialize(reader.getAssetLL())); - - std::vector<Nv::Blast::TkAssetJointDesc> jointDescs; - jointDescs.resize(reader.getJointDescs().size()); - - for (uint32_t i = 0; i < jointDescs.size(); i++) - { - TkAssetJointDescDTO::deserializeInto(reader.getJointDescs()[i], &jointDescs[i]); - } - - // Make sure to set ownsAsset to true - this is serialization and no one else owns it. - Nv::Blast::TkAsset* asset = NvBlastTkFrameworkGet()->createAsset(assetLL, jointDescs.data(), jointDescs.size(), true); - - return asset; - } - - bool TkAssetDTO::deserializeInto(Nv::Blast::Serialization::TkAsset::Reader reader, Nv::Blast::TkAsset * poco) - { - reader = reader; - poco = nullptr; - // NOTE: Because of the way TkAsset is currently structured, this won't work. - return false; - } + TkAssetJointDescDTO::serialize(jointDescs[i], &poco->getJointDescs()[i]); } + + return true; } + + +Nv::Blast::TkAsset* TkAssetDTO::deserialize(Nv::Blast::Serialization::TkAsset::Reader reader) +{ + const NvBlastAsset* assetLL = reinterpret_cast<const NvBlastAsset*>(AssetDTO::deserialize(reader.getAssetLL())); + + std::vector<Nv::Blast::TkAssetJointDesc> jointDescs; + + const uint32_t jointDescCount = reader.getJointDescs().size(); + jointDescs.resize(jointDescCount); + auto readerJointDescs = reader.getJointDescs(); + for (uint32_t i = 0; i < jointDescCount; i++) + { + TkAssetJointDescDTO::deserializeInto(readerJointDescs[i], &jointDescs[i]); + } + + // Make sure to set ownsAsset to true - this is serialization and no one else owns it. + Nv::Blast::TkAsset* asset = NvBlastTkFrameworkGet()->createAsset(assetLL, jointDescs.data(), jointDescCount, true); + + return asset; +} + + +bool TkAssetDTO::deserializeInto(Nv::Blast::Serialization::TkAsset::Reader reader, Nv::Blast::TkAsset * poco) +{ + reader = reader; + poco = nullptr; + // NOTE: Because of the way TkAsset is currently structured, this won't work. + return false; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/TkAssetDTO.h b/sdk/extensions/serialization/source/DTO/TkAssetDTO.h index 1b21eba..d0eceea 100644 --- a/sdk/extensions/serialization/source/DTO/TkAssetDTO.h +++ b/sdk/extensions/serialization/source/DTO/TkAssetDTO.h @@ -1,17 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "NvBlastTkAsset.h" -#include "generated/NvBlastExtSerialization.capn.h" -#include "PxCooking.h" +#include "generated/NvBlastExtTkSerialization.capn.h" DTO_CLASS(TkAsset, Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset) diff --git a/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp b/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp index 9118d19..cbc1ef8 100644 --- a/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "TkAssetJointDescDTO.h" #include "PxVec3DTO.h" @@ -14,40 +32,45 @@ namespace Nv { - namespace Blast +namespace Blast +{ + +bool TkAssetJointDescDTO::serialize(Nv::Blast::Serialization::TkAssetJointDesc::Builder builder, const Nv::Blast::TkAssetJointDesc * poco) +{ + kj::ArrayPtr<const uint32_t> nodeIndices(poco->nodeIndices, 2); + builder.setNodeIndices(nodeIndices); + + for (int i = 0; i < 2; i++) { - - bool TkAssetJointDescDTO::serialize(Nv::Blast::Serialization::TkAssetJointDesc::Builder builder, const Nv::Blast::TkAssetJointDesc * poco) - { - kj::ArrayPtr<const uint32_t> nodeIndices(poco->nodeIndices, 2); - builder.setNodeIndices(nodeIndices); - - for (int i = 0; i < 2; i++) - { - PxVec3DTO::serialize(builder.getAttachPositions()[i], &poco->attachPositions[i]); - } - - return true; - } - - Nv::Blast::TkAssetJointDesc* TkAssetJointDescDTO::deserialize(Nv::Blast::Serialization::TkAssetJointDesc::Reader reader) - { - //TODO: Allocate with ExtContent and return - - reader = reader; - - return nullptr; - } - - bool TkAssetJointDescDTO::deserializeInto(Nv::Blast::Serialization::TkAssetJointDesc::Reader reader, Nv::Blast::TkAssetJointDesc * poco) - { - PxVec3DTO::deserializeInto(reader.getAttachPositions()[0], &poco->attachPositions[0]); - PxVec3DTO::deserializeInto(reader.getAttachPositions()[1], &poco->attachPositions[1]); - - poco->nodeIndices[0] = reader.getNodeIndices()[0]; - poco->nodeIndices[1] = reader.getNodeIndices()[1]; - - return true; - } + PxVec3DTO::serialize(builder.getAttachPositions()[i], &poco->attachPositions[i]); } -}
\ No newline at end of file + + return true; +} + + +Nv::Blast::TkAssetJointDesc* TkAssetJointDescDTO::deserialize(Nv::Blast::Serialization::TkAssetJointDesc::Reader reader) +{ + //TODO: Allocate with ExtContent and return + + reader = reader; + + return nullptr; +} + + +bool TkAssetJointDescDTO::deserializeInto(Nv::Blast::Serialization::TkAssetJointDesc::Reader reader, Nv::Blast::TkAssetJointDesc * poco) +{ + auto readerAttachPositions = reader.getAttachPositions(); + PxVec3DTO::deserializeInto(readerAttachPositions[0], &poco->attachPositions[0]); + PxVec3DTO::deserializeInto(readerAttachPositions[1], &poco->attachPositions[1]); + + auto readerNodeIndices = reader.getNodeIndices(); + poco->nodeIndices[0] = readerNodeIndices[0]; + poco->nodeIndices[1] = readerNodeIndices[1]; + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.h b/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.h index 88364bd..1dca2f9 100644 --- a/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.h +++ b/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.h @@ -1,17 +1,34 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "DTOMacros.h" #include "NvBlastTkAsset.h" -#include "generated/NvBlastExtSerialization.capn.h" -#include "PxCooking.h" +#include "generated/NvBlastExtTkSerialization.capn.h" DTO_CLASS(TkAssetJointDesc, Nv::Blast::TkAssetJointDesc, Nv::Blast::Serialization::TkAssetJointDesc) diff --git a/sdk/extensions/serialization/source/NvBlastExtGlobals.h b/sdk/extensions/serialization/source/NvBlastExtGlobals.h deleted file mode 100644 index dd50afd..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtGlobals.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -/** -Function pointer type for allocation - has same signature as stdlib malloc. -*/ -typedef void* (*NvBlastExtAlloc)(size_t size); - -extern NvBlastExtAlloc gAlloc; -extern NvBlastLog gLog; - diff --git a/sdk/extensions/serialization/source/NvBlastExtInputStream.cpp b/sdk/extensions/serialization/source/NvBlastExtInputStream.cpp index 7ef9b62..805990d 100644 --- a/sdk/extensions/serialization/source/NvBlastExtInputStream.cpp +++ b/sdk/extensions/serialization/source/NvBlastExtInputStream.cpp @@ -1,17 +1,35 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtInputStream.h" -Nv::Blast::ExtInputStream::ExtInputStream(std::istream &inputStream): +Nv::Blast::ExtInputStream::ExtInputStream(std::istream &inputStream) : m_inputStream(inputStream) { @@ -25,13 +43,13 @@ size_t Nv::Blast::ExtInputStream::tryRead(void* buffer, size_t /*minBytes*/, siz if (m_inputStream.fail()) { // Throw exception, log error -// NVBLASTEXT_LOG_ERROR("Failure when reading from stream"); +// NVBLAST_LOG_ERROR("Failure when reading from stream"); } // Since we're using a blocking read above, if we don't have maxBytes we're probably done if ((size_t) m_inputStream.gcount() < maxBytes) { -// NVBLASTEXT_LOG_ERROR("Failed to read requested number of bytes during blocking read."); +// NVBLAST_LOG_ERROR("Failed to read requested number of bytes during blocking read."); } return m_inputStream.gcount(); diff --git a/sdk/extensions/serialization/source/NvBlastExtInputStream.h b/sdk/extensions/serialization/source/NvBlastExtInputStream.h index 9b19d9c..cd36e9e 100644 --- a/sdk/extensions/serialization/source/NvBlastExtInputStream.h +++ b/sdk/extensions/serialization/source/NvBlastExtInputStream.h @@ -1,32 +1,53 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "kj/io.h" #include <istream> + namespace Nv { - namespace Blast - { - class ExtInputStream : public kj::InputStream - { - public: - ExtInputStream() = delete; - ExtInputStream(std::istream &inputStream); - - // Returns a read of maxBytes. This is supposed to be happy doing partial reads, but currently isn't. - virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - - private: - std::istream &m_inputStream; - }; - } -}
\ No newline at end of file +namespace Blast +{ + +class ExtInputStream : public kj::InputStream +{ +public: + ExtInputStream() = delete; + ExtInputStream(std::istream &inputStream); + + // Returns a read of maxBytes. This is supposed to be happy doing partial reads, but currently isn't. + virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + +private: + std::istream &m_inputStream; +}; + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.cpp b/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.cpp index 9af13a9..cc73e6b 100644 --- a/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.cpp +++ b/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.cpp @@ -1,32 +1,53 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtKJPxInputStream.h" namespace Nv { - namespace Blast - { - ExtKJPxInputStream::ExtKJPxInputStream(capnp::Data::Reader inReader) : - dataReader(inReader), - inputStream(nullptr) - { - kj::ArrayPtr<const unsigned char> buffer(inReader.begin(), inReader.size()); - - inputStream = std::make_shared<kj::ArrayInputStream>(buffer); - } - - uint32_t ExtKJPxInputStream::read(void* dest, uint32_t count) - { - return inputStream->tryRead(dest, count, count); - } - } +namespace Blast +{ + +ExtKJPxInputStream::ExtKJPxInputStream(capnp::Data::Reader inReader) : +dataReader(inReader), +inputStream(nullptr) +{ + kj::ArrayPtr<const unsigned char> buffer(inReader.begin(), inReader.size()); + + inputStream = std::make_shared<kj::ArrayInputStream>(buffer); +} + + +uint32_t ExtKJPxInputStream::read(void* dest, uint32_t count) +{ + return inputStream->tryRead(dest, count, count); } +} // namespace Blast +} // namespace Nv + diff --git a/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.h b/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.h index 452892d..bc0074a 100644 --- a/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.h +++ b/sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.h @@ -1,41 +1,62 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "PxIO.h" #include "capnp/common.h" #include "kj/io.h" #include <memory> -#include "generated/NvBlastExtSerialization.capn.h" +#include "generated/NvBlastExtPxSerialization.capn.h" + namespace Nv { - namespace Blast - { - /* - A wrapper around a Capn Proto Data reader. - - Since it needs to behave like a stream, it's internally wrapped in a stream. - - */ - class ExtKJPxInputStream : public physx::PxInputStream - { - public: - ExtKJPxInputStream(capnp::Data::Reader inReader); - ~ExtKJPxInputStream() = default; - - virtual uint32_t read(void* dest, uint32_t count) override; - - private: - capnp::Data::Reader dataReader; - std::shared_ptr<kj::ArrayInputStream> inputStream; - }; - } -} +namespace Blast +{ + +/* +A wrapper around a Capn Proto Data reader. + +Since it needs to behave like a stream, it's internally wrapped in a stream. + +*/ +class ExtKJPxInputStream : public physx::PxInputStream +{ +public: + ExtKJPxInputStream(capnp::Data::Reader inReader); + ~ExtKJPxInputStream() = default; + + virtual uint32_t read(void* dest, uint32_t count) override; + +private: + capnp::Data::Reader dataReader; + std::shared_ptr<kj::ArrayInputStream> inputStream; +}; + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.cpp b/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.cpp index 0f17a01..d1ea822 100644 --- a/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.cpp +++ b/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.cpp @@ -1,35 +1,55 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #include "NvBlastExtKJPxOutputStream.h" namespace Nv { - namespace Blast - { - ExtKJPxOutputStream::ExtKJPxOutputStream(kj::ArrayPtr<unsigned char> inBuffer) : - writtenBytes(0), - Buffer(inBuffer), - outputStream(nullptr) - { - outputStream = std::make_shared<kj::ArrayOutputStream>(inBuffer); - } - - uint32_t ExtKJPxOutputStream::write(const void* src, uint32_t count) - { - outputStream->write(src, count); - - writtenBytes += count; - - return count; - } - } +namespace Blast +{ + +ExtKJPxOutputStream::ExtKJPxOutputStream(kj::ArrayPtr<unsigned char> inBuffer) : +writtenBytes(0), +Buffer(inBuffer), +outputStream(nullptr) +{ + outputStream = std::make_shared<kj::ArrayOutputStream>(inBuffer); +} + + +uint32_t ExtKJPxOutputStream::write(const void* src, uint32_t count) +{ + outputStream->write(src, count); + + writtenBytes += count; + + return count; } +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.h b/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.h index 0ed563f..325a65a 100644 --- a/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.h +++ b/sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "PxIO.h" @@ -14,27 +32,30 @@ #include <memory> #include "kj/io.h" + namespace Nv { - namespace Blast - { - class ExtKJPxOutputStream : public physx::PxOutputStream - { - public: - ExtKJPxOutputStream(kj::ArrayPtr<unsigned char> inBuffer); - ~ExtKJPxOutputStream() = default; +namespace Blast +{ + +class ExtKJPxOutputStream : public physx::PxOutputStream +{ +public: + ExtKJPxOutputStream(kj::ArrayPtr<unsigned char> inBuffer); + ~ExtKJPxOutputStream() = default; + + virtual uint32_t write(const void* src, uint32_t count) override; - virtual uint32_t write(const void* src, uint32_t count) override; + uint32_t getWrittenBytes() { return writtenBytes; } - uint32_t getWrittenBytes() { return writtenBytes; } + kj::ArrayPtr<unsigned char> getBuffer() { return Buffer; } - kj::ArrayPtr<unsigned char> getBuffer() { return Buffer; } +private: + uint32_t writtenBytes; - private: - uint32_t writtenBytes; + kj::ArrayPtr<unsigned char> Buffer; + std::shared_ptr<kj::ArrayOutputStream> outputStream; +}; - kj::ArrayPtr<unsigned char> Buffer; - std::shared_ptr<kj::ArrayOutputStream> outputStream; - }; - } -} +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtLlSerialization.capn b/sdk/extensions/serialization/source/NvBlastExtLlSerialization.capn new file mode 100644 index 0000000..31c1db4 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtLlSerialization.capn @@ -0,0 +1,108 @@ +# 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) 2017 NVIDIA Corporation. All rights reserved. + + +@0x9a4a58fac38375e0; + +using Cxx = import "/capnp/c++.capnp"; + +$Cxx.namespace("Nv::Blast::Serialization"); + +struct Asset +{ + header @0 :NvBlastDataBlock; + + iD @1 :UUID; + + chunkCount @2 :UInt32; + + graph @3 :NvBlastSupportGraph; + + leafChunkCount @4 :UInt32; + + firstSubsupportChunkIndex @5 :UInt32; + + bondCount @6 :UInt32; + + chunks @7: List(NvBlastChunk); + + bonds @8: List(NvBlastBond); + + subtreeLeafChunkCounts @9: List(UInt32); + + chunkToGraphNodeMap @10: List(UInt32); +} + +struct NvBlastDataBlock +{ + enum Type + { + assetDataBlock @0; + instanceDataBlock @1; + } + + dataType @0 :Type; + + formatVersion @1 :UInt32; + + size @2 :UInt32; +} + +struct NvBlastChunk +{ + centroid @0 :List(Float32); + + volume @1 :Float32; + + parentChunkIndex @2 :UInt32; + firstChildIndex @3 :UInt32; + childIndexStop @4 :UInt32; + userData @5 :UInt32; +} + +struct NvBlastBond +{ + normal @0 :List(Float32); + area @1 :Float32; + centroid @2 :List(Float32); + userData @3 :UInt32; +} + +struct NvBlastSupportGraph +{ + nodeCount @0 : UInt32; + + chunkIndices @1 : List(UInt32); + adjacencyPartition @2 : List(UInt32); + adjacentNodeIndices @3 : List(UInt32); + adjacentBondIndices @4 : List(UInt32); +} + +struct UUID +{ + value @0 : Data; +} diff --git a/sdk/extensions/serialization/source/NvBlastExtLlSerialization.cpp b/sdk/extensions/serialization/source/NvBlastExtLlSerialization.cpp new file mode 100644 index 0000000..b9c261b --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtLlSerialization.cpp @@ -0,0 +1,136 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtSerializationInternal.h" +#include "NvBlastExtLlSerialization.h" +#include "NvBlastExtLlSerializerCAPN.h" + + +namespace Nv +{ +namespace Blast +{ + +class ExtLlSerializerAsset_CPNB : public ExtSerializer +{ +public: + ExtSerializerBoilerplate("LLAsset_CPNB", "Blast low-level asset (NvBlastAsset) serialization using Cap'n Proto binary format.", LlObjectTypeID::Asset, ExtSerialization::EncodingID::CapnProtoBinary); + ExtSerializerDefaultFactoryAndRelease(ExtLlSerializerAsset_CPNB); + + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) override + { + return ExtSerializationCAPN<Asset, Serialization::Asset::Reader, Serialization::Asset::Builder>::deserializeFromBuffer(reinterpret_cast<const unsigned char*>(buffer), size); + } + + virtual uint64_t serializeIntoBuffer(void*& buffer, ExtSerialization::BufferProvider& bufferProvider, const void* object, uint64_t offset = 0) override + { + uint64_t usedSize; + if (!ExtSerializationCAPN<Asset, Serialization::Asset::Reader, Serialization::Asset::Builder>::serializeIntoBuffer(reinterpret_cast<const Asset*>(object), + reinterpret_cast<unsigned char*&>(buffer), usedSize, &bufferProvider, offset)) + { + return 0; + } + return usedSize; + } +}; + + +class ExtLlSerializerObject_RAW : public ExtSerializer +{ +public: + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) override + { + const NvBlastDataBlock* block = reinterpret_cast<const NvBlastDataBlock*>(buffer); + if (static_cast<uint64_t>(block->size) > size) + { + return nullptr; + } + void* llobject = NVBLAST_ALLOC(block->size); + return memcpy(llobject, block, block->size); + } + + virtual uint64_t serializeIntoBuffer(void*& buffer, ExtSerialization::BufferProvider& bufferProvider, const void* object, uint64_t offset = 0) override + { + const NvBlastDataBlock* block = reinterpret_cast<const NvBlastDataBlock*>(object); + const uint64_t size = block->size + offset; + buffer = bufferProvider.requestBuffer(size); + if (buffer == nullptr) + { + return 0; + } + memcpy(static_cast<char*>(buffer) + offset, object, block->size); + return size; + } +}; + + +class ExtLlSerializerAsset_RAW : public ExtLlSerializerObject_RAW +{ +public: + ExtSerializerBoilerplate("LLAsset_RAW", "Blast low-level asset (NvBlastAsset) serialization using raw memory format.", LlObjectTypeID::Asset, ExtSerialization::EncodingID::RawBinary); + ExtSerializerDefaultFactoryAndRelease(ExtLlSerializerAsset_RAW); +}; + + +class ExtLlSerializerFamily_RAW : public ExtLlSerializerObject_RAW +{ +public: + ExtSerializerBoilerplate("LLFamily_RAW", "Blast low-level family (NvBlastFamily) serialization using raw memory format.", LlObjectTypeID::Family, ExtSerialization::EncodingID::RawBinary); + ExtSerializerDefaultFactoryAndRelease(ExtLlSerializerFamily_RAW); +}; + +} // namespace Blast +} // namespace Nv + + +/////////////////////////////////////// + + +size_t NvBlastExtLlSerializerLoadSet(Nv::Blast::ExtSerialization& serialization) +{ + Nv::Blast::ExtSerializer* (*factories[])() = + { + Nv::Blast::ExtLlSerializerAsset_CPNB::create, + Nv::Blast::ExtLlSerializerAsset_RAW::create, + Nv::Blast::ExtLlSerializerFamily_RAW::create + }; + + return Nv::Blast::ExtSerializationLoadSet(static_cast<Nv::Blast::ExtSerializationInternal&>(serialization), factories); +} + + +uint64_t NvBlastExtSerializationSerializeAssetIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const NvBlastAsset* asset) +{ + return serialization.serializeIntoBuffer(buffer, asset, Nv::Blast::LlObjectTypeID::Asset); +} + + +uint64_t NvBlastExtSerializationSerializeFamilyIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const NvBlastFamily* family) +{ + return serialization.serializeIntoBuffer(buffer, family, Nv::Blast::LlObjectTypeID::Family); +} diff --git a/sdk/extensions/serialization/source/NvBlastExtLlSerializerCAPN.h b/sdk/extensions/serialization/source/NvBlastExtLlSerializerCAPN.h new file mode 100644 index 0000000..1e4bbc2 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtLlSerializerCAPN.h @@ -0,0 +1,72 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastExtSerializationCAPN.h" +#include "NvBlastAsset.h" +#include "AssetDTO.h" + + +/** +Specializations of ExtSerializationCAPN for Blast LL +*/ + +namespace Nv +{ +namespace Blast +{ + +//// Nv::Blast::Asset //// + +template<> +NV_INLINE bool ExtSerializationCAPN<Asset, Serialization::Asset::Reader, Serialization::Asset::Builder>::serializeIntoBuilder(Serialization::Asset::Builder& assetBuilder, const Asset* asset) +{ + return AssetDTO::serialize(assetBuilder, asset); +} + + +template<> +NV_INLINE bool ExtSerializationCAPN<Asset, Serialization::Asset::Reader, Serialization::Asset::Builder>::serializeIntoMessage(capnp::MallocMessageBuilder& message, const Asset* asset) +{ + Serialization::Asset::Builder assetBuilder = message.initRoot<Serialization::Asset>(); + + return serializeIntoBuilder(assetBuilder, asset); +} + + +template<> +NV_INLINE Asset* ExtSerializationCAPN<Asset, Serialization::Asset::Reader, Serialization::Asset::Builder>::deserializeFromStreamReader(capnp::InputStreamMessageReader &message) +{ + Serialization::Asset::Reader reader = message.getRoot<Serialization::Asset>(); + + return AssetDTO::deserialize(reader); +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtOutputStream.cpp b/sdk/extensions/serialization/source/NvBlastExtOutputStream.cpp index cf6e31f..c270fa8 100644 --- a/sdk/extensions/serialization/source/NvBlastExtOutputStream.cpp +++ b/sdk/extensions/serialization/source/NvBlastExtOutputStream.cpp @@ -1,15 +1,32 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. -#include "NvBlastExtOutputStream.h" +#include "NvBlastExtOutputStream.h" Nv::Blast::ExtOutputStream::ExtOutputStream(std::ostream &outputStream): diff --git a/sdk/extensions/serialization/source/NvBlastExtOutputStream.h b/sdk/extensions/serialization/source/NvBlastExtOutputStream.h index ba0044e..89b19a9 100644 --- a/sdk/extensions/serialization/source/NvBlastExtOutputStream.h +++ b/sdk/extensions/serialization/source/NvBlastExtOutputStream.h @@ -1,31 +1,52 @@ -/* -* Copyright (c) 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) 2017 NVIDIA Corporation. All rights reserved. + #pragma once #include "kj/io.h" #include <ostream> + namespace Nv { - namespace Blast - { - class ExtOutputStream : public kj::OutputStream - { - - public: - ExtOutputStream() = delete; - ExtOutputStream(std::ostream &outputStream); - - virtual void write(const void* buffer, size_t size) override; - private: - std::ostream &m_outputStream; - }; - } -} +namespace Blast +{ + +class ExtOutputStream : public kj::OutputStream +{ +public: + ExtOutputStream() = delete; + ExtOutputStream(std::ostream &outputStream); + + virtual void write(const void* buffer, size_t size) override; + +private: + std::ostream &m_outputStream; +}; + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtPxSerialization.capn b/sdk/extensions/serialization/source/NvBlastExtPxSerialization.capn new file mode 100644 index 0000000..802898f --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtPxSerialization.capn @@ -0,0 +1,99 @@ +# This code contains NVIDIA Confidential Information and is disclosed to you +# under a form of NVIDIA software license agreement provided separately to you. +# +# Notice +# NVIDIA Corporation and its licensors retain all intellectual property and +# proprietary rights in and to this software and related documentation and +# any modifications thereto. Any use, reproduction, disclosure, or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA Corporation is strictly prohibited. +# +# ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +# NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +# THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +# MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +# +# Information and code furnished is believed to be accurate and reliable. +# However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +# information or for any infringement of patents or other rights of third parties that may +# result from its use. No license is granted by implication or otherwise under any patent +# or patent rights of NVIDIA Corporation. Details are subject to change without notice. +# This code supersedes and replaces all information previously supplied. +# NVIDIA Corporation products are not authorized for use as critical +# components in life support devices or systems without express written approval of +# NVIDIA Corporation. +# +# Copyright (c) 2017 NVIDIA Corporation. All rights reserved. + + +@0xf4df9a42d5842b01; + +using Cxx = import "/capnp/c++.capnp"; + +using TK = import "NvBlastExtTkSerialization.capn"; + +$Cxx.namespace("Nv::Blast::Serialization"); + +struct ExtPxAsset +{ + asset @0 :TK.TkAsset; + chunks @1 :List(ExtPxChunk); + subchunks @2 :List(ExtPxSubchunk); + uniformInitialBondHealth @3 :Float32; + bondHealths @4 :List(Float32); + uniformInitialLowerSupportChunkHealth @5 :Float32; + supportChunkHealths @6 :List(Float32); +} + +struct ExtPxChunk +{ + firstSubchunkIndex @0 :UInt32; + subchunkCount @1 :UInt32; + isStatic @2 :Bool; +} + +struct ExtPxSubchunk +{ + transform @0 :PxTransform; + geometry @1 :PxConvexMeshGeometry; +} + +struct PxConvexMeshGeometry +{ + scale @0 :PxMeshScale; + convexMesh @1 :Data; + meshFlags @2 :UInt8; + + enum Type + { + eSPHERE @0; + ePLANE @1; + eCAPSULE @2; + eBOX @3; + eCONVEXMESH @4; + eTRIANGLEMESH @5; + eHEIGHTFIELD @6; + } + + type @3 :Type; +} + +struct PxQuat +{ + x @0 :Float32; + y @1 :Float32; + z @2 :Float32; + w @3 :Float32; +} + +struct PxMeshScale +{ + scale @0 :TK.PxVec3; + rotation @1 :PxQuat; +} + +struct PxTransform +{ + q @0 :PxQuat; + p @1 :TK.PxVec3; +} diff --git a/sdk/extensions/serialization/source/NvBlastExtPxSerialization.cpp b/sdk/extensions/serialization/source/NvBlastExtPxSerialization.cpp new file mode 100644 index 0000000..d48213d --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtPxSerialization.cpp @@ -0,0 +1,109 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtSerializationInternal.h" +#include "NvBlastExtPxSerialization.h" +#include "NvBlastExtPxSerializerCAPN.h" +#include "NvBlastExtPxSerializerRAW.h" + + +namespace Nv +{ +namespace Blast +{ + +TkFramework* sExtPxSerializerFramework = nullptr; +physx::PxPhysics* sExtPxSerializerPhysics = nullptr; +physx::PxCooking* sExtPxSerializerCooking = nullptr; + + +class ExtPxSerializerAsset_CPNB : public ExtSerializer +{ +public: + ExtSerializerBoilerplate("ExtPxAsset_CPNB", "Blast PhysX extension asset (Nv::Blast::ExtPxAsset) serialization using Cap'n Proto binary format.", ExtPxObjectTypeID::Asset, ExtSerialization::EncodingID::CapnProtoBinary); + ExtSerializerDefaultFactoryAndRelease(ExtPxSerializerAsset_CPNB); + + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) override + { + return ExtSerializationCAPN<ExtPxAsset, Serialization::ExtPxAsset::Reader, Serialization::ExtPxAsset::Builder>::deserializeFromBuffer(reinterpret_cast<const unsigned char*>(buffer), size); + } + + virtual uint64_t serializeIntoBuffer(void*& buffer, ExtSerialization::BufferProvider& bufferProvider, const void* object, uint64_t offset = 0) override + { + uint64_t usedSize; + if (!ExtSerializationCAPN<ExtPxAsset, Serialization::ExtPxAsset::Reader, Serialization::ExtPxAsset::Builder>::serializeIntoBuffer(reinterpret_cast<const ExtPxAsset*>(object), + reinterpret_cast<unsigned char*&>(buffer), usedSize, &bufferProvider, offset)) + { + return 0; + } + return usedSize; + } +}; + + +class ExtPxSerializerAsset_RAW : public ExtSerializer +{ +public: + ExtSerializerBoilerplate("ExtPxAsset_RAW", "Blast PhysX extension asset (Nv::Blast::TkAsset) serialization using raw memory format.", ExtPxObjectTypeID::Asset, ExtSerialization::EncodingID::RawBinary); + ExtSerializerDefaultFactoryAndRelease(ExtPxSerializerAsset_RAW); + ExtSerializerReadOnly(ExtPxSerializerAsset_RAW); + + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) override + { + ExtIStream stream(buffer, size); + return deserializeExtPxAsset(stream, *sExtPxSerializerFramework, *sExtPxSerializerPhysics); + } +}; + +} // namespace Blast +} // namespace Nv + + +/////////////////////////////////////// + + +size_t NvBlastExtPxSerializerLoadSet(Nv::Blast::TkFramework& framework, physx::PxPhysics& physics, physx::PxCooking& cooking, Nv::Blast::ExtSerialization& serialization) +{ + Nv::Blast::sExtPxSerializerFramework = &framework; + Nv::Blast::sExtPxSerializerPhysics = &physics; + Nv::Blast::sExtPxSerializerCooking = &cooking; + + Nv::Blast::ExtSerializer* (*factories[])() = + { + Nv::Blast::ExtPxSerializerAsset_CPNB::create, + Nv::Blast::ExtPxSerializerAsset_RAW::create + }; + + return Nv::Blast::ExtSerializationLoadSet(static_cast<Nv::Blast::ExtSerializationInternal&>(serialization), factories); +} + + +uint64_t NvBlastExtSerializationSerializeExtPxAssetIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const Nv::Blast::ExtPxAsset* asset) +{ + return serialization.serializeIntoBuffer(buffer, asset, Nv::Blast::ExtPxObjectTypeID::Asset); +} diff --git a/sdk/extensions/serialization/source/NvBlastExtPxSerializerCAPN.h b/sdk/extensions/serialization/source/NvBlastExtPxSerializerCAPN.h new file mode 100644 index 0000000..cd0e45f --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtPxSerializerCAPN.h @@ -0,0 +1,70 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastExtSerializationCAPN.h" +#include "NvBlastExtPxAsset.h" +#include "ExtPxAssetDTO.h" + + +/** +Specializations of ExtSerializationCAPN for BlastExtPx +*/ + +namespace Nv +{ +namespace Blast +{ + +//// Nv::Blast::ExtPxAsset //// + +template<> +NV_INLINE bool ExtSerializationCAPN<ExtPxAsset, Serialization::ExtPxAsset::Reader, Serialization::ExtPxAsset::Builder>::serializeIntoBuilder(Serialization::ExtPxAsset::Builder& assetBuilder, const ExtPxAsset* asset) +{ + return ExtPxAssetDTO::serialize(assetBuilder, asset); +} + +template<> +NV_INLINE ExtPxAsset* ExtSerializationCAPN<ExtPxAsset, Serialization::ExtPxAsset::Reader, Serialization::ExtPxAsset::Builder>::deserializeFromStreamReader(capnp::InputStreamMessageReader &message) +{ + Serialization::ExtPxAsset::Reader reader = message.getRoot<Serialization::ExtPxAsset>(); + + return ExtPxAssetDTO::deserialize(reader); +} + +template<> +NV_INLINE bool ExtSerializationCAPN<ExtPxAsset, Serialization::ExtPxAsset::Reader, Serialization::ExtPxAsset::Builder>::serializeIntoMessage(capnp::MallocMessageBuilder& message, const ExtPxAsset* asset) +{ + Serialization::ExtPxAsset::Builder assetBuilder = message.initRoot<Serialization::ExtPxAsset>(); + + return serializeIntoBuilder(assetBuilder, asset); +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.cpp b/sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.cpp new file mode 100644 index 0000000..526b148 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.cpp @@ -0,0 +1,220 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtSerialization.h" +#include "NvBlastExtTkSerializerRAW.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastTkAsset.h" +#include "physics/NvBlastExtPxAssetImpl.h" +#include "NvBlastIndexFns.h" +#include "NvBlastAssert.h" +#include "NvBlastExtSerializationInternal.h" + +#include "PxPhysics.h" +#include "PsMemoryBuffer.h" +#include "PxIO.h" + + +namespace Nv +{ +namespace Blast +{ + +// Legacy IDs +struct ExtPxSerializationLegacyID +{ + enum Enum + { + Asset = NVBLAST_FOURCC('B', 'P', 'X', 'A'), //!< ExtPxAsset identifier token, used in serialization + }; +}; + + +// Legacy object format versions +struct ExtPxSerializationLegacyAssetVersion +{ + enum Enum + { + /** 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 + }; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helpers/Wrappers +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class FileBufToPxInputStream final : public PxInputStream +{ +public: + FileBufToPxInputStream(PxFileBuf& filebuf) : m_filebuf(filebuf) {} + + virtual uint32_t read(void* dest, uint32_t count) + { + return m_filebuf.read(dest, count); + } + +private: + FileBufToPxInputStream& operator=(const FileBufToPxInputStream&); + + PxFileBuf& m_filebuf; +}; + + +class FileBufToPxOutputStream final : public PxOutputStream +{ +public: + FileBufToPxOutputStream(PxFileBuf& filebuf) : m_filebuf(filebuf) {} + + virtual uint32_t write(const void* src, uint32_t count) override + { + return m_filebuf.write(src, count); + } + +private: + FileBufToPxOutputStream& operator=(const FileBufToPxOutputStream&); + + PxFileBuf& m_filebuf; +}; + + +ExtPxAsset* deserializeExtPxAsset(ExtIStream& stream, TkFramework& framework, physx::PxPhysics& physics) +{ + // Read header + struct LegacyAssetDataHeader + { + uint32_t dataType; + uint32_t version; + }; + LegacyAssetDataHeader header; + stream >> header.dataType; + stream >> header.version; + NVBLAST_CHECK_ERROR(header.dataType == ExtPxSerializationLegacyID::Asset, "deserializeExtPxAsset: wrong data type in filebuf stream.", return nullptr); + NVBLAST_CHECK_ERROR(header.version == ExtPxSerializationLegacyAssetVersion::Current, "deserializeExtPxAsset: wrong data version in filebuf stream.", return nullptr); + + // Read initial TkAsset + TkAsset* tkAsset = deserializeTkAsset(stream, framework); + NVBLAST_CHECK_ERROR(tkAsset != nullptr, "ExtPxAsset::deserialize: failed to deserialize TkAsset.", return nullptr); + + // Create ExtPxAsset + ExtPxAssetImpl* asset = reinterpret_cast<ExtPxAssetImpl*>(ExtPxAsset::create(tkAsset)); + + // Fill arrays + auto& chunks = asset->getChunksArray(); + chunks.resize(tkAsset->getChunkCount()); + const uint32_t chunkCount = chunks.size(); + for (uint32_t i = 0; i < chunkCount; ++i) + { + ExtPxChunk& chunk = chunks[i]; + stream >> chunk.firstSubchunkIndex; + stream >> chunk.subchunkCount; + uint32_t val; + stream >> val; + chunk.isStatic = 0 != val; + } + + auto& subchunks = asset->getSubchunksArray(); + uint32_t subchunkCount; + stream >> subchunkCount; + subchunks.resize(subchunkCount); + for (uint32_t i = 0; i < subchunkCount; ++i) + { + ExtPxSubchunk& subchunk = subchunks[i]; + + // Subchunk transform + stream >> subchunk.transform.q.x >> subchunk.transform.q.y >> subchunk.transform.q.z >> subchunk.transform.q.w; + stream >> subchunk.transform.p.x >> subchunk.transform.p.y >> subchunk.transform.p.z; + + // Subchunk scale + stream >> subchunk.geometry.scale.scale.x >> subchunk.geometry.scale.scale.y >> subchunk.geometry.scale.scale.z; + stream >> subchunk.geometry.scale.rotation.x >> subchunk.geometry.scale.rotation.y >> subchunk.geometry.scale.rotation.z >> subchunk.geometry.scale.rotation.w; + + uint32_t convexReuseIndex; + stream >> convexReuseIndex; + if (isInvalidIndex(convexReuseIndex)) + { + physx::PsMemoryBuffer memBuf(stream.view(), stream.left()); + FileBufToPxInputStream inputStream(memBuf); + subchunk.geometry.convexMesh = physics.createConvexMesh(inputStream); + stream.advance(memBuf.tellRead()); + } + else + { + NVBLAST_ASSERT_WITH_MESSAGE(convexReuseIndex < i, "ExtPxAsset::deserialize: wrong convexReuseIndex."); + subchunk.geometry.convexMesh = subchunks[convexReuseIndex].geometry.convexMesh; + } + if (!subchunk.geometry.convexMesh) + { + NVBLAST_LOG_ERROR("ExtPxAsset::deserialize: failed to deserialize convex mesh."); + return nullptr; + } + } + + // checking if it's the end, so it will be binary compatible with asset before m_defaultActorDesc was added + if (!stream.eof()) + { + auto& defaultActorDesc = asset->getDefaultActorDesc(); + + stream >> defaultActorDesc.uniformInitialBondHealth; + stream >> defaultActorDesc.uniformInitialLowerSupportChunkHealth; + + auto& bondHealths = asset->getBondHealthsArray(); + uint32_t bondHealthCount; + stream >> bondHealthCount; + bondHealths.resize(bondHealthCount); + for (uint32_t i = 0; i < bondHealths.size(); ++i) + { + stream >> bondHealths[i]; + } + defaultActorDesc.initialBondHealths = bondHealthCount ? bondHealths.begin() : nullptr; + + auto& supportChunkHealths = asset->getBondHealthsArray(); + uint32_t supportChunkHealthCount; + stream >> supportChunkHealthCount; + supportChunkHealths.resize(supportChunkHealthCount); + for (uint32_t i = 0; i < supportChunkHealths.size(); ++i) + { + stream >> supportChunkHealths[i]; + } + defaultActorDesc.initialSupportChunkHealths = supportChunkHealthCount ? supportChunkHealths.begin() : nullptr; + } + + return asset; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.h b/sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.h new file mode 100644 index 0000000..1e287c5 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.h @@ -0,0 +1,61 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + + +/** +Raw serialization function declarations for BlastExtPx +*/ + +#include <stdint.h> + + +// Forward declarations +namespace physx +{ +class PxPhysics; +} + +namespace Nv +{ +namespace Blast +{ + +// Forward declarations +class ExtPxAsset; +class TkFramework; +class ExtIStream; + + +//// Nv::Blast::TkAsset //// + +ExtPxAsset* deserializeExtPxAsset(ExtIStream& stream, TkFramework& framework, physx::PxPhysics& physics); + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtSerialization.capn b/sdk/extensions/serialization/source/NvBlastExtSerialization.capn deleted file mode 100644 index ddc439a..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerialization.capn +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright (c) 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. - -@0xaffe4498f275ee58; - -using Cxx = import "/capnp/c++.capnp"; - -using LL = import "NvBlastExtSerializationLL.capn"; - -$Cxx.namespace("Nv::Blast::Serialization"); - -struct TkAsset -{ - assetLL @0 :LL.Asset; - - jointDescs @1 :List(TkAssetJointDesc); -} - -struct ExtPxAsset -{ - asset @0 :TkAsset; - chunks @1 :List(ExtPxChunk); - subchunks @2 :List(ExtPxSubchunk); -} - -struct ExtPxChunk -{ - firstSubchunkIndex @0 :UInt32; - subchunkCount @1 :UInt32; - isStatic @2 :Bool; -} - -struct ExtPxSubchunk -{ - transform @0 :PxTransform; - geometry @1 :PxConvexMeshGeometry; -} - -struct PxConvexMeshGeometry -{ - scale @0 :PxMeshScale; - convexMesh @1 :Data; - meshFlags @2 :UInt8; - - enum Type - { - eSPHERE @0; - ePLANE @1; - eCAPSULE @2; - eBOX @3; - eCONVEXMESH @4; - eTRIANGLEMESH @5; - eHEIGHTFIELD @6; - } - - type @3 :Type; -} - -struct TkAssetJointDesc -{ - nodeIndices @0 :List(UInt32); - attachPositions @1 :List(PxVec3); -} - -struct PxVec3 -{ - x @0 :Float32; - y @1 :Float32; - z @2 :Float32; -} - -struct PxQuat -{ - x @0 :Float32; - y @1 :Float32; - z @2 :Float32; - w @3 :Float32; -} - -struct PxMeshScale -{ - scale @0 :PxVec3; - rotation @1 :PxQuat; -} - -struct PxTransform -{ - q @0 :PxQuat; - p @1 :PxVec3; -} diff --git a/sdk/extensions/serialization/source/NvBlastExtSerialization.cpp b/sdk/extensions/serialization/source/NvBlastExtSerialization.cpp index 28a1553..77ecdf6 100644 --- a/sdk/extensions/serialization/source/NvBlastExtSerialization.cpp +++ b/sdk/extensions/serialization/source/NvBlastExtSerialization.cpp @@ -1,146 +1,401 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + #include "NvBlastExtSerialization.h" -#include "BlastSerialization.h" -#include <memory> -#include "PxPhysicsVersion.h" -#include "PxConvexMeshGeometryDTO.h" -#include "NvBlastExtDefs.h" +#include "NvBlastExtLlSerialization.h" +#include "NvBlastHashMap.h" +#include "NvBlastExtSerializationInternal.h" + + +namespace Nv +{ +namespace Blast +{ + +class ExtSerializationImpl : public ExtSerializationInternal +{ +public: + // Default buffer provider + class AllocBufferProvider : public ExtSerialization::BufferProvider + { + public: + virtual void* requestBuffer(size_t size) override; + }; + + + ExtSerializationImpl(); + ~ExtSerializationImpl(); + + // ExtSerialization interface begin + virtual bool setSerializationEncoding(uint32_t encodingID) override; + virtual uint32_t getSerializationEncoding() const override; + + virtual void setBufferProvider(BufferProvider* bufferProvider) override; + + virtual bool peekHeader(uint32_t* objectTypeID, uint32_t* encodingID, uint64_t* dataSize, const void* buffer, uint64_t bufferSize) override; + virtual const void* skipObject(uint64_t& bufferSize, const void* buffer) override; + + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size, uint32_t* objectTypeIDPtr = nullptr) override; + virtual uint64_t serializeIntoBuffer(void*& buffer, const void* object, uint32_t objectTypeID) override; + virtual void release() override; + // ExtSerialization interface end -// This is terrible. -physx::PxPhysics* g_Physics = nullptr; + // ExtSerializationInternal interface begin + virtual bool registerSerializer(ExtSerializer& serializer) override; + virtual bool unregisterSerializer(ExtSerializer& serializer) override; + + virtual ExtSerializer* findSerializer(uint32_t objectTypeID, uint32_t encodingID) override; + // ExtSerializationInternal interface end + +private: + char* writeHeaderIntoBuffer(char* buffer, uint64_t bufferSize, uint32_t objectTypeID, uint32_t encodingID, uint64_t dataSize) const; + const char* readHeaderFromBuffer(uint32_t* objectTypeID, uint32_t* encodingID, uint64_t* dataSize, const char* buffer, uint64_t bufferSize) const; + + //// Static data //// + static const char* s_identifier; + static const char* s_version; + static AllocBufferProvider s_defaultBufferProvider; + + //// Member data //// + HashMap<uint64_t, ExtSerializer*>::type m_serializers; + uint32_t m_serializationEncoding; + BufferProvider* m_bufferProvider; +}; + + +//////// ExtSerializationImpl static member variables //////// + +/** Module identifying header. This should never change. */ +const char* ExtSerializationImpl::s_identifier = "NVidia(r) GameWorks Blast(tm) v."; + +const char* ExtSerializationImpl::s_version = "1"; + +ExtSerializationImpl::AllocBufferProvider ExtSerializationImpl::s_defaultBufferProvider; + + +//////// Local utility functions //////// + +static NV_INLINE uint64_t generateKey(uint32_t objectTypeID, uint32_t encodingID) +{ + return static_cast<uint64_t>(encodingID) << 32 | static_cast<uint64_t>(objectTypeID); +} -std::shared_ptr<physx::PxCooking> getCooking() +static NV_INLINE uint64_t generateKey(const ExtSerializer& serializer) { - physx::PxCookingParams cookingParams(g_Physics->getTolerancesScale()); - cookingParams.buildGPUData = true; + return generateKey(serializer.getObjectTypeID(), serializer.getEncodingID()); +} + - std::shared_ptr<physx::PxCooking> m_Cooking = std::shared_ptr<physx::PxCooking>(PxCreateCooking(PX_PHYSICS_VERSION, g_Physics->getFoundation(), cookingParams), [=](physx::PxCooking* cooking) +static NV_INLINE void writeIDToBuffer(char* buffer, uint32_t id) +{ + for (int i = 0; i < 4; ++i, id >>= 8) { - cooking->release(); - }); + *buffer++ = static_cast<char>(id & 0xFF); + } +} - NVBLASTEXT_CHECK_ERROR(m_Cooking, "Error: failed to create PhysX Cooking\n", return nullptr); - return m_Cooking; +static NV_INLINE uint32_t readIDFromBuffer(const char* buffer) +{ + return NVBLAST_FOURCC(buffer[0], buffer[1], buffer[2], buffer[3]); } -extern "C" +static NV_INLINE void writeU64InHexToBuffer(char* buffer, uint64_t val) { - NVBLAST_API void setPhysXSDK(physx::PxPhysics* physXSDK) + for (char* curr = buffer + 16; curr-- > buffer; val >>= 4) { - g_Physics = physXSDK; + *curr = "0123456789ABCDEF"[val & 0xF]; } +} + - NVBLAST_API NvBlastAsset* deserializeAsset(const unsigned char* input, uint32_t size) +static NV_INLINE uint64_t readU64InHexFromBuffer(const char* buffer) +{ + uint64_t val = 0; + for (const char* curr = buffer; curr < buffer + 16; ++curr) { - return Nv::Blast::BlastSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::deserialize(input, size); + const char c = *curr; + const char msn = c >> 4; + const char mask = ((88 >> msn) & 1) - 1; + const unsigned char digit = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xA\xB\xC\xD\xE\xF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"[((msn - 3) & 1) << 4 | (c & 0xF)] | mask; + if (digit == 0xFF) + { + return 0; // Not a hexidecimal digit + } + val = val << 4 | digit; } + return val; +} + + +//////// ExtSerialization member functions //////// + +ExtSerializationImpl::ExtSerializationImpl() : m_serializationEncoding(EncodingID::CapnProtoBinary), m_bufferProvider(&s_defaultBufferProvider) +{ +} - NVBLAST_API NvBlastAsset* deserializeAssetFromStream(std::istream &inputStream) + +ExtSerializationImpl::~ExtSerializationImpl() +{ + // Release and remove all registered serializers + auto it = m_serializers.getEraseIterator(); + while (auto entry = it.eraseCurrentGetNext(true)) { - return Nv::Blast::BlastSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::deserializeFromStream(inputStream); + entry->second->release(); } - - NVBLAST_API bool serializeAssetIntoStream(const NvBlastAsset *asset, std::ostream &outputStream) +} + + +char* ExtSerializationImpl::writeHeaderIntoBuffer(char* buffer, uint64_t bufferSize, uint32_t objectTypeID, uint32_t encodingID, uint64_t dataSize) const +{ + if (bufferSize < HeaderSize) { - return Nv::Blast::BlastSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoStream(reinterpret_cast<const Nv::Blast::Asset *>(asset), outputStream); + return nullptr; } - NVBLAST_API bool serializeAssetIntoNewBuffer(const NvBlastAsset *asset, unsigned char **outBuffer, uint32_t &outSize) + char* stop = buffer + HeaderSize; + + size_t versionLen = strlen(s_version); + if (versionLen > 63) { - return Nv::Blast::BlastSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoNewBuffer(reinterpret_cast<const Nv::Blast::Asset *>(asset), outBuffer, outSize); + versionLen = 63; } - NVBLAST_API bool serializeAssetIntoExistingBuffer(const NvBlastAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) + memset(buffer, ' ', HeaderSize); + memcpy(buffer, s_identifier, 32); buffer += 32; + memcpy(buffer, s_version, versionLen); buffer += 64; + writeIDToBuffer(buffer, objectTypeID); buffer += 5; + writeIDToBuffer(buffer, encodingID); buffer += 5; + writeU64InHexToBuffer(buffer, dataSize); buffer += 16; + *(stop - 1) = '\n'; + + return stop; +} + + +const char* ExtSerializationImpl::readHeaderFromBuffer(uint32_t* objectTypeID, uint32_t* encodingID, uint64_t* dataSize, const char* buffer, uint64_t bufferSize) const +{ + if (bufferSize < HeaderSize) { - return Nv::Blast::BlastSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoExistingBuffer(reinterpret_cast<const Nv::Blast::Asset *>(asset), buffer, maxSize, usedSize); + NVBLAST_LOG_ERROR("ExtSerializationImpl::readHeaderFromBuffer: header terminator not found."); + return nullptr; } - ////////////////////////////////////////////////////////////////////////// - // TkAsset - ////////////////////////////////////////////////////////////////////////// + const char* stop = buffer + HeaderSize; - NVBLAST_API Nv::Blast::TkAsset* deserializeTkAsset(const unsigned char* input, uint32_t size) + if (memcmp(buffer, s_identifier, 32)) { - return Nv::Blast::BlastSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::deserialize(input, size); + NVBLAST_LOG_ERROR("ExtSerializationImpl::readHeaderFromBuffer: file identifier does not match expected value."); + return nullptr; } + buffer += 32; - NVBLAST_API Nv::Blast::TkAsset* deserializeTkAssetFromStream(std::istream &inputStream) + const char* s = strchr(buffer, ' '); + if (s == nullptr) + { + NVBLAST_LOG_ERROR("ExtSerializationImpl::readHeaderFromBuffer: file format error reading serializer library version."); + } + if (memcmp(buffer, s_version, s - buffer)) { - return Nv::Blast::BlastSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::deserializeFromStream(inputStream); + NVBLAST_LOG_ERROR("ExtSerializationImpl::readHeaderFromBuffer: file version does not match serializer library version."); + return nullptr; } + buffer += 64; - NVBLAST_API bool serializeTkAssetIntoStream(const Nv::Blast::TkAsset *asset, std::ostream &outputStream) + if (objectTypeID != nullptr) { - return Nv::Blast::BlastSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoStream(reinterpret_cast<const Nv::Blast::TkAsset *>(asset), outputStream); + *objectTypeID = readIDFromBuffer(buffer); } + buffer += 5; - NVBLAST_API bool serializeTkAssetIntoNewBuffer(const Nv::Blast::TkAsset *asset, unsigned char **outBuffer, uint32_t &outSize) + if (encodingID != nullptr) { - return Nv::Blast::BlastSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoNewBuffer(reinterpret_cast<const Nv::Blast::TkAsset *>(asset), outBuffer, outSize); + *encodingID = readIDFromBuffer(buffer); } + buffer += 5; - NVBLAST_API bool serializeTkAssetIntoExistingBuffer(const Nv::Blast::TkAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) + if (dataSize != nullptr) { - return Nv::Blast::BlastSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoExistingBuffer(reinterpret_cast<const Nv::Blast::TkAsset *>(asset), buffer, maxSize, usedSize); + *dataSize = readU64InHexFromBuffer(buffer); } + buffer += 16; - ////////////////////////////////////////////////////////////////////////// - // ExtPxAsset - ////////////////////////////////////////////////////////////////////////// + return stop; +} - NVBLAST_API Nv::Blast::ExtPxAsset* deserializeExtPxAsset(const unsigned char* input, uint32_t size) - { - NVBLAST_ASSERT(g_Physics != nullptr); - return Nv::Blast::BlastSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::deserialize(input, size); - } +bool ExtSerializationImpl::registerSerializer(ExtSerializer& serializer) +{ + return m_serializers.insert(generateKey(serializer), &serializer); +} - NVBLAST_API Nv::Blast::ExtPxAsset* deserializeExtPxAssetFromStream(std::istream &inputStream) - { - NVBLAST_ASSERT(g_Physics != nullptr); - return Nv::Blast::BlastSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::deserializeFromStream(inputStream); +bool ExtSerializationImpl::unregisterSerializer(ExtSerializer& serializer) +{ + const uint64_t key = generateKey(serializer); + const auto entry = m_serializers.find(key); + if (entry == nullptr) + { + return false; } + entry->second->release(); + return m_serializers.erase(key); +} + - NVBLAST_API bool serializeExtPxAssetIntoStream(const Nv::Blast::ExtPxAsset *asset, std::ostream &outputStream) +ExtSerializer* ExtSerializationImpl::findSerializer(uint32_t objectTypeID, uint32_t encodingID) +{ + auto entry = m_serializers.find(generateKey(objectTypeID, encodingID)); + return entry != nullptr ? entry->second : nullptr; +} + + +bool ExtSerializationImpl::setSerializationEncoding(uint32_t encodingID) +{ + m_serializationEncoding = encodingID; + + return true; +} + + +uint32_t ExtSerializationImpl::getSerializationEncoding() const +{ + return m_serializationEncoding; +} + + +void ExtSerializationImpl::setBufferProvider(BufferProvider* bufferProvider) +{ + m_bufferProvider = bufferProvider != nullptr ? bufferProvider : &s_defaultBufferProvider; +} + + +bool ExtSerializationImpl::peekHeader(uint32_t* objectTypeID, uint32_t* encodingID, uint64_t* dataSize, const void* buffer, uint64_t bufferSize) +{ + return nullptr != readHeaderFromBuffer(objectTypeID, encodingID, dataSize, reinterpret_cast<const char*>(buffer), bufferSize); +} + + +const void* ExtSerializationImpl::skipObject(uint64_t& bufferSize, const void* buffer) +{ + uint64_t dataSize; + const char* next = readHeaderFromBuffer(nullptr, nullptr, &dataSize, static_cast<const char*>(buffer), bufferSize); + if (next == nullptr) { - NVBLAST_ASSERT(g_Physics != nullptr); + return nullptr; + } + next += dataSize; + const uint64_t skipSize = next - static_cast<const char*>(buffer); + NVBLAST_CHECK_ERROR(skipSize <= bufferSize, "Object size in buffer is too large for given buffer size.", return nullptr); + bufferSize -= skipSize; + return next; +} - auto cooking = getCooking(); - PxConvexMeshGeometryDTO::Cooking = cooking.get(); - PxConvexMeshGeometryDTO::Physics = g_Physics; +void* ExtSerializationImpl::deserializeFromBuffer(const void* buffer, uint64_t bufferSize, uint32_t* objectTypeIDPtr) +{ + uint32_t objectTypeID; + uint32_t encodingID; + uint64_t dataSize; + void* result = nullptr; - return Nv::Blast::BlastSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoStream(reinterpret_cast<const Nv::Blast::ExtPxAsset *>(asset), outputStream); + buffer = readHeaderFromBuffer(&objectTypeID, &encodingID, &dataSize, reinterpret_cast<const char*>(buffer), bufferSize); + if (buffer != nullptr) + { + auto entry = m_serializers.find(generateKey(objectTypeID, encodingID)); + if (entry != nullptr && entry->second != nullptr) + { + result = entry->second->deserializeFromBuffer(buffer, dataSize); + } } - NVBLAST_API bool serializeExtPxAssetIntoNewBuffer(const Nv::Blast::ExtPxAsset *asset, unsigned char **outBuffer, uint32_t &outSize) + if (objectTypeIDPtr != nullptr) { - NVBLAST_ASSERT(g_Physics != nullptr); + *objectTypeIDPtr = result != nullptr ? objectTypeID : 0; + } - auto cooking = getCooking(); + return result; +} - PxConvexMeshGeometryDTO::Cooking = cooking.get(); - PxConvexMeshGeometryDTO::Physics = g_Physics; - return Nv::Blast::BlastSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoNewBuffer(reinterpret_cast<const Nv::Blast::ExtPxAsset *>(asset), outBuffer, outSize); +uint64_t ExtSerializationImpl::serializeIntoBuffer(void*& buffer, const void* object, uint32_t objectTypeID) +{ + if (!m_serializationEncoding) + { + NVBLAST_LOG_ERROR("ExtSerializationImpl::serializeIntoBuffer: no serialization encoding has been set."); + return false; // No encoding available + } + + auto entry = m_serializers.find(generateKey(objectTypeID, m_serializationEncoding)); + if (entry == nullptr || entry->second == nullptr) + { + return false; } - NVBLAST_API bool serializeExtPxAssetIntoExistingBuffer(const Nv::Blast::ExtPxAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) + const uint64_t size = entry->second->serializeIntoBuffer(buffer, *m_bufferProvider, object, HeaderSize); + if (size < HeaderSize) { - NVBLAST_ASSERT(g_Physics != nullptr); + NVBLAST_LOG_ERROR("ExtSerializationImpl::serializeIntoBuffer: failed to write data to buffer."); + return 0; + } + + writeHeaderIntoBuffer(reinterpret_cast<char*>(buffer), HeaderSize, objectTypeID, m_serializationEncoding, size - HeaderSize); - auto cooking = getCooking(); + return size; +} - PxConvexMeshGeometryDTO::Cooking = cooking.get(); - PxConvexMeshGeometryDTO::Physics = g_Physics; - return Nv::Blast::BlastSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoExistingBuffer(reinterpret_cast<const Nv::Blast::ExtPxAsset *>(asset), buffer, maxSize, usedSize); - } +void ExtSerializationImpl::release() +{ + NVBLAST_DELETE(this, ExtSerializationImpl); +} + +//////// ExtSerializationImpl::AllocBufferProvider member functions //////// +void* ExtSerializationImpl::AllocBufferProvider::requestBuffer(size_t size) +{ + return NVBLAST_ALLOC(size); } +} // namespace Blast +} // namespace Nv + + +Nv::Blast::ExtSerialization* NvBlastExtSerializationCreate() +{ + Nv::Blast::ExtSerializationImpl* serialization = NVBLAST_NEW(Nv::Blast::ExtSerializationImpl) (); + + // Automatically load LL serializers + NvBlastExtLlSerializerLoadSet(*serialization); + + return serialization; +} diff --git a/sdk/extensions/serialization/source/NvBlastExtSerialization.h b/sdk/extensions/serialization/source/NvBlastExtSerialization.h deleted file mode 100644 index 5d44554..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerialization.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -* Copyright (c) 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. -*/ - -#pragma once -#include "kj/io.h" -#include "capnp/serialize.h" -#include "generated/NvBlastExtSerializationLL.capn.h" -#include <vector> -#include "NvBlastExtInputStream.h" -#include "NvBlastExtOutputStream.h" - -#if !defined(BLAST_LL_ALLOC) -#include "NvBlastExtAllocator.h" -#endif -#include "NvBlastExtGlobals.h" - -namespace Nv -{ - namespace Blast - { - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - class ExtSerialization - { - public: - static TAsset* deserialize(const unsigned char* input, uint32_t size); - static TAsset* deserializeFromStream(std::istream &inputStream); - - static bool serializeIntoExistingBuffer(const TAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize); - static bool serializeIntoNewBuffer(const TAsset *asset, unsigned char **outBuffer, uint32_t &outSize); - static bool serializeIntoStream(const TAsset *asset, std::ostream &outputStream); - - private: - - static void serializeMessageIntoNewBuffer(capnp::MallocMessageBuilder& message, unsigned char ** outBuffer, uint32_t &outSize); - - // Specialized - static bool serializeIntoBuilder(TSerializationBuilder& assetBuilder, const TAsset* asset); - static bool serializeIntoMessage(capnp::MallocMessageBuilder& message, const TAsset* asset); - static TAsset* deserializeFromStreamReader(capnp::InputStreamMessageReader &message); - }; - - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - TAsset* ExtSerialization<TAsset, TSerializationReader, TSerializationBuilder>::deserialize(const unsigned char* input, uint32_t size) - { - kj::ArrayPtr<const unsigned char> source(input, size); - - kj::ArrayInputStream inputStream(source); - - std::vector<uint64_t> scratch; - scratch.resize(size); - kj::ArrayPtr<capnp::word> scratchArray((capnp::word*) scratch.data(), size); - - capnp::InputStreamMessageReader message(inputStream, capnp::ReaderOptions(), scratchArray); - - return deserializeFromStreamReader(message); - } - - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - TAsset* ExtSerialization<TAsset, TSerializationReader, TSerializationBuilder>::deserializeFromStream(std::istream &inputStream) - { - Nv::Blast::ExtInputStream readStream(inputStream); - - capnp::InputStreamMessageReader message(readStream); - - return deserializeFromStreamReader(message); - } - - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - bool ExtSerialization<TAsset, TSerializationReader, TSerializationBuilder>::serializeIntoExistingBuffer(const TAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) - { - capnp::MallocMessageBuilder message; - - bool result = serializeIntoMessage(message, asset); - - if (result == false) - { - usedSize = 0; - return false; - } - - uint32_t messageSize = computeSerializedSizeInWords(message) * sizeof(uint64_t); - - if (maxSize < messageSize) - { - NvBlastLog logFn = gLog; - -#if !defined(BLAST_LL_ALLOC) - logFn = NvBlastTkFrameworkGet()->getLogFn(); -#endif - - NVBLAST_LOG_ERROR(logFn, "When attempting to serialize into an existing buffer, the provided buffer was too small."); - usedSize = 0; - return false; - } - - kj::ArrayPtr<unsigned char> outputBuffer(buffer, maxSize); - kj::ArrayOutputStream outputStream(outputBuffer); - - capnp::writeMessage(outputStream, message); - - usedSize = messageSize;; - return true; - } - - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - bool ExtSerialization<TAsset, TSerializationReader, TSerializationBuilder>::serializeIntoNewBuffer(const TAsset *asset, unsigned char **outBuffer, uint32_t &outSize) - { - capnp::MallocMessageBuilder message; - - bool result = serializeIntoMessage(message, asset); - - if (result == false) - { - *outBuffer = nullptr; - outSize = 0; - return false; - } - - serializeMessageIntoNewBuffer(message, outBuffer, outSize); - - return true; - } - - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - bool ExtSerialization<TAsset, TSerializationReader, TSerializationBuilder>::serializeIntoStream(const TAsset *asset, std::ostream &outputStream) - { - capnp::MallocMessageBuilder message; - - bool result = serializeIntoMessage(message, asset); - - if (result == false) - { - return false; - } - - Nv::Blast::ExtOutputStream blastOutputStream(outputStream); - - writeMessage(blastOutputStream, message); - - return true; - } - - template<typename TAsset, typename TSerializationReader, typename TSerializationBuilder> - void ExtSerialization<TAsset, TSerializationReader, TSerializationBuilder>::serializeMessageIntoNewBuffer(capnp::MallocMessageBuilder& message, unsigned char ** outBuffer, uint32_t &outSize) - { - uint32_t messageSize = computeSerializedSizeInWords(message) * sizeof(uint64_t); - - NvBlastExtAlloc allocFn = gAlloc; - -#if !defined(BLAST_LL_ALLOC) - allocFn = ExtAllocator::alignedAlloc16; -#endif - - unsigned char* buffer = static_cast<unsigned char *>(allocFn(messageSize)); - - kj::ArrayPtr<unsigned char> outputBuffer(buffer, messageSize); - kj::ArrayOutputStream outputStream(outputBuffer); - - capnp::writeMessage(outputStream, message); - - *outBuffer = buffer; - outSize = messageSize; - } - } -} diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationCAPN.h b/sdk/extensions/serialization/source/NvBlastExtSerializationCAPN.h new file mode 100644 index 0000000..fe261e6 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtSerializationCAPN.h @@ -0,0 +1,188 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "capnp/serialize.h" +#include "NvBlastExtInputStream.h" +#include "NvBlastExtOutputStream.h" +#include "NvBlastArray.h" +#include "NvBlastExtSerialization.h" + + +namespace Nv +{ +namespace Blast +{ + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +class ExtSerializationCAPN +{ +public: + static TObject* deserializeFromBuffer(const unsigned char* input, uint64_t size); + static TObject* deserializeFromStream(std::istream& inputStream); + + static uint64_t serializationBufferSize(const TObject* object); + + static bool serializeIntoBuffer(const TObject* object, unsigned char* buffer, uint64_t maxSize, uint64_t& usedSize); + static bool serializeIntoBuffer(const TObject *object, unsigned char*& buffer, uint64_t& size, ExtSerialization::BufferProvider* bufferProvider = nullptr, uint64_t offset = 0); + static bool serializeIntoStream(const TObject* object, std::ostream& outputStream); + +private: + // Specialized + static bool serializeIntoBuilder(TSerializationBuilder& objectBuilder, const TObject* object); + static bool serializeIntoMessage(capnp::MallocMessageBuilder& message, const TObject* object); + static TObject* deserializeFromStreamReader(capnp::InputStreamMessageReader& message); +}; + + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +TObject* ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::deserializeFromBuffer(const unsigned char* input, uint64_t size) +{ + kj::ArrayPtr<const unsigned char> source(input, size); + + kj::ArrayInputStream inputStream(source); + + Nv::Blast::Array<uint64_t>::type scratch(static_cast<uint32_t>(size)); + kj::ArrayPtr<capnp::word> scratchArray((capnp::word*) scratch.begin(), size); + + capnp::InputStreamMessageReader message(inputStream, capnp::ReaderOptions(), scratchArray); + + return deserializeFromStreamReader(message); +} + + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +TObject* ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::deserializeFromStream(std::istream& inputStream) +{ + ExtInputStream readStream(inputStream); + + capnp::InputStreamMessageReader message(readStream); + + return deserializeFromStreamReader(message); +} + + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +uint64_t ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializationBufferSize(const TObject* object) +{ + capnp::MallocMessageBuilder message; + + bool result = serializeIntoMessage(message, object); + + if (result == false) + { + return 0; + } + + return computeSerializedSizeInWords(message) * sizeof(uint64_t); +} + + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +bool ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializeIntoBuffer(const TObject* object, unsigned char* buffer, uint64_t maxSize, uint64_t& usedSize) +{ + capnp::MallocMessageBuilder message; + + bool result = serializeIntoMessage(message, object); + + if (result == false) + { + usedSize = 0; + return false; + } + + uint64_t messageSize = computeSerializedSizeInWords(message) * sizeof(uint64_t); + + if (maxSize < messageSize) + { + NVBLAST_LOG_ERROR("When attempting to serialize into an existing buffer, the provided buffer was too small."); + usedSize = 0; + return false; + } + + kj::ArrayPtr<unsigned char> outputBuffer(buffer, maxSize); + kj::ArrayOutputStream outputStream(outputBuffer); + + capnp::writeMessage(outputStream, message); + + usedSize = messageSize; + return true; +} + + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +bool ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializeIntoBuffer(const TObject *object, unsigned char*& buffer, uint64_t& size, ExtSerialization::BufferProvider* bufferProvider, uint64_t offset) +{ + capnp::MallocMessageBuilder message; + + bool result = serializeIntoMessage(message, object); + + if (result == false) + { + buffer = nullptr; + size = 0; + return false; + } + + const uint64_t blockSize = computeSerializedSizeInWords(message) * sizeof(uint64_t); + + size = blockSize + offset; + + buffer = static_cast<unsigned char *>(bufferProvider != nullptr ? bufferProvider->requestBuffer(size) : NVBLAST_ALLOC(size)); + + kj::ArrayPtr<unsigned char> outputBuffer(buffer + offset, blockSize); + kj::ArrayOutputStream outputStream(outputBuffer); + + capnp::writeMessage(outputStream, message); + + return true; +} + + +template<typename TObject, typename TSerializationReader, typename TSerializationBuilder> +bool ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializeIntoStream(const TObject* object, std::ostream& outputStream) +{ + capnp::MallocMessageBuilder message; + + bool result = serializeIntoMessage(message, object); + + if (result == false) + { + return false; + } + + ExtOutputStream blastOutputStream(outputStream); + + writeMessage(blastOutputStream, message); + + return true; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationImpl.h b/sdk/extensions/serialization/source/NvBlastExtSerializationImpl.h deleted file mode 100644 index 7f9fbc9..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerializationImpl.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -* Copyright (c) 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. -*/ - -#pragma once - -#include "NvBlastExtSerialization.h" -#include "NvBlastTkAsset.h" -#include "NvBlastExtPxAsset.h" -#include "TkAssetDTO.h" -#include "ExtPxAssetDTO.h" - -namespace Nv -{ - namespace Blast - { - /* - Specializations here - one set for each top level asset. (TkAsset, ExtPxAsset) - */ - - - // TkAsset - template<> - NV_INLINE bool ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoBuilder(Nv::Blast::Serialization::TkAsset::Builder& assetBuilder, const Nv::Blast::TkAsset* asset) - { - return TkAssetDTO::serialize(assetBuilder, asset); - } - - template<> - NV_INLINE Nv::Blast::TkAsset* ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::deserializeFromStreamReader(capnp::InputStreamMessageReader &message) - { - Nv::Blast::Serialization::TkAsset::Reader reader = message.getRoot<Nv::Blast::Serialization::TkAsset>(); - - return TkAssetDTO::deserialize(reader); - } - - template<> - NV_INLINE bool ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoMessage(capnp::MallocMessageBuilder& message, const Nv::Blast::TkAsset* asset) - { - Nv::Blast::Serialization::TkAsset::Builder assetBuilder = message.initRoot<Nv::Blast::Serialization::TkAsset>(); - - return serializeIntoBuilder(assetBuilder, asset); - } - - - //ExtPxAsset - template<> - NV_INLINE bool ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoBuilder(Nv::Blast::Serialization::ExtPxAsset::Builder& assetBuilder, const Nv::Blast::ExtPxAsset* asset) - { - return ExtPxAssetDTO::serialize(assetBuilder, asset); - } - - template<> - NV_INLINE Nv::Blast::ExtPxAsset* ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::deserializeFromStreamReader(capnp::InputStreamMessageReader &message) - { - Nv::Blast::Serialization::ExtPxAsset::Reader reader = message.getRoot<Nv::Blast::Serialization::ExtPxAsset>(); - - return ExtPxAssetDTO::deserialize(reader); - } - - template<> - NV_INLINE bool ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoMessage(capnp::MallocMessageBuilder& message, const Nv::Blast::ExtPxAsset* asset) - { - Nv::Blast::Serialization::ExtPxAsset::Builder assetBuilder = message.initRoot<Nv::Blast::Serialization::ExtPxAsset>(); - - return serializeIntoBuilder(assetBuilder, asset); - } - } -} diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationInterface.cpp b/sdk/extensions/serialization/source/NvBlastExtSerializationInterface.cpp deleted file mode 100644 index bebee5b..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerializationInterface.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* -* Copyright (c) 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 "NvBlastExtSerializationImpl.h" -#include <memory> -#include "PxPhysicsVersion.h" -#include "PxConvexMeshGeometryDTO.h" -#include "NvBlastExtDefs.h" -#include "PxPhysics.h" -#include "NvBlastAssert.h" - - -// This is terrible. -physx::PxPhysics* g_Physics = nullptr; - -using namespace Nv::Blast; - -std::shared_ptr<physx::PxCooking> getCooking() -{ - physx::PxCookingParams cookingParams(g_Physics->getTolerancesScale()); - cookingParams.buildGPUData = true; - - std::shared_ptr<physx::PxCooking> m_Cooking = std::shared_ptr<physx::PxCooking>(PxCreateCooking(PX_PHYSICS_VERSION, g_Physics->getFoundation(), cookingParams), [=](physx::PxCooking* cooking) - { - cooking->release(); - }); - - NVBLASTEXT_CHECK_ERROR(m_Cooking, "Error: failed to create PhysX Cooking\n", return nullptr); - - return m_Cooking; -} - - -extern "C" -{ - NVBLAST_API void setPhysXSDK(physx::PxPhysics* physXSDK) - { - g_Physics = physXSDK; - } - - ////////////////////////////////////////////////////////////////////////// - // TkAsset - ////////////////////////////////////////////////////////////////////////// - - NVBLAST_API Nv::Blast::TkAsset* deserializeTkAsset(const unsigned char* input, uint32_t size) - { - return Nv::Blast::ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::deserialize(input, size); - } - - NVBLAST_API Nv::Blast::TkAsset* deserializeTkAssetFromStream(std::istream &inputStream) - { - return Nv::Blast::ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::deserializeFromStream(inputStream); - } - - NVBLAST_API bool serializeTkAssetIntoStream(const Nv::Blast::TkAsset *asset, std::ostream &outputStream) - { - return Nv::Blast::ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoStream(reinterpret_cast<const Nv::Blast::TkAsset *>(asset), outputStream); - } - - NVBLAST_API bool serializeTkAssetIntoNewBuffer(const Nv::Blast::TkAsset *asset, unsigned char **outBuffer, uint32_t &outSize) - { - return Nv::Blast::ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoNewBuffer(reinterpret_cast<const Nv::Blast::TkAsset *>(asset), outBuffer, outSize); - } - - NVBLAST_API bool serializeTkAssetIntoExistingBuffer(const Nv::Blast::TkAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) - { - return Nv::Blast::ExtSerialization<Nv::Blast::TkAsset, Nv::Blast::Serialization::TkAsset::Reader, Nv::Blast::Serialization::TkAsset::Builder>::serializeIntoExistingBuffer(reinterpret_cast<const Nv::Blast::TkAsset *>(asset), buffer, maxSize, usedSize); - } - - ////////////////////////////////////////////////////////////////////////// - // ExtPxAsset - ////////////////////////////////////////////////////////////////////////// - - NVBLAST_API Nv::Blast::ExtPxAsset* deserializeExtPxAsset(const unsigned char* input, uint32_t size) - { - NVBLAST_ASSERT(g_Physics != nullptr); - - return Nv::Blast::ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::deserialize(input, size); - } - - NVBLAST_API Nv::Blast::ExtPxAsset* deserializeExtPxAssetFromStream(std::istream &inputStream) - { - NVBLAST_ASSERT(g_Physics != nullptr); - - return Nv::Blast::ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::deserializeFromStream(inputStream); - } - - NVBLAST_API bool serializeExtPxAssetIntoStream(const Nv::Blast::ExtPxAsset *asset, std::ostream &outputStream) - { - NVBLAST_ASSERT(g_Physics != nullptr); - - auto cooking = getCooking(); - - PxConvexMeshGeometryDTO::Cooking = cooking.get(); - PxConvexMeshGeometryDTO::Physics = g_Physics; - - return Nv::Blast::ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoStream(reinterpret_cast<const Nv::Blast::ExtPxAsset *>(asset), outputStream); - } - - NVBLAST_API bool serializeExtPxAssetIntoNewBuffer(const Nv::Blast::ExtPxAsset *asset, unsigned char **outBuffer, uint32_t &outSize) - { - NVBLAST_ASSERT(g_Physics != nullptr); - - auto cooking = getCooking(); - - PxConvexMeshGeometryDTO::Cooking = cooking.get(); - PxConvexMeshGeometryDTO::Physics = g_Physics; - - return Nv::Blast::ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoNewBuffer(reinterpret_cast<const Nv::Blast::ExtPxAsset *>(asset), outBuffer, outSize); - } - - NVBLAST_API bool serializeExtPxAssetIntoExistingBuffer(const Nv::Blast::ExtPxAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) - { - NVBLAST_ASSERT(g_Physics != nullptr); - - auto cooking = getCooking(); - - PxConvexMeshGeometryDTO::Cooking = cooking.get(); - PxConvexMeshGeometryDTO::Physics = g_Physics; - - return Nv::Blast::ExtSerialization<Nv::Blast::ExtPxAsset, Nv::Blast::Serialization::ExtPxAsset::Reader, Nv::Blast::Serialization::ExtPxAsset::Builder>::serializeIntoExistingBuffer(reinterpret_cast<const Nv::Blast::ExtPxAsset *>(asset), buffer, maxSize, usedSize); - } - - -} - diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationInternal.h b/sdk/extensions/serialization/source/NvBlastExtSerializationInternal.h new file mode 100644 index 0000000..117280a --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtSerializationInternal.h @@ -0,0 +1,291 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastExtSerialization.h" + +#include <cstring> + +#define ExtSerializerBoilerplate(_name, _description, _objectTypeID, _encodingID) \ +virtual const char* getName() const override { return _name; } \ +virtual const char* getDescription() const override { return _description; } \ +virtual uint32_t getObjectTypeID() const override { return _objectTypeID; } \ +virtual uint32_t getEncodingID() const override { return _encodingID; } + + +#define ExtSerializerReadOnly(_name) \ +virtual bool isReadOnly() const override { return true; } \ +virtual uint64_t serializeIntoBuffer \ +( \ + void*& buffer, \ + ExtSerialization::BufferProvider& bufferProvider, \ + const void* object, \ + uint64_t offset = 0 \ +) override \ +{ \ + NVBLAST_LOG_WARNING(#_name "::serializeIntoBuffer: ExtPxAsset_RAW serializer is read-only."); \ + NV_UNUSED(buffer); \ + NV_UNUSED(bufferProvider); \ + NV_UNUSED(object); \ + NV_UNUSED(offset); \ + return 0; \ +} + + +#define ExtSerializerDefaultFactoryAndRelease(_classname) \ +static ExtSerializer* create() \ +{ \ + return NVBLAST_NEW(_classname) (); \ +} \ +virtual void release() override \ +{ \ + NVBLAST_DELETE(this, _classname); \ +} + + +namespace Nv +{ +namespace Blast +{ + +/** +Serializer internal interface +*/ +class ExtSerializer +{ +public: + virtual ~ExtSerializer() {} + + /** + return the name of this serializer. + */ + virtual const char* getName() const = 0; + + /** + return a description of this serializer. + */ + virtual const char* getDescription() const = 0; + + /** + return an identifier for the type of object handled. + */ + virtual uint32_t getObjectTypeID() const = 0; + + /** + return an identifier for serialization format. + */ + virtual uint32_t getEncodingID() const = 0; + + /** + Whether or not this serializer supports writing. Legacy formats, for example, may not. + + \return true iff this serialization does not support writing. + */ + virtual bool isReadOnly() const { return false; } + + /** + Deserialize from a buffer into a newly allocated object. + + \param[in] buffer Pointer to the buffer to read. + \param[in] size Size of the buffer to read. + \return object pointer; returns null if failed to deserialize. + */ + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) = 0; + + /** + Serialize into a buffer. Allocates the buffer internally using the ExtSerialization::BufferProvider callack interface. + + \param[out] buffer Pointer to the buffer created. + \param[in] bufferProvider The buffer provider callback interface to use. + \param[in] object Object pointer. + + \return the number of bytes serialized into the buffer (zero if unsuccessful). + */ + virtual uint64_t serializeIntoBuffer(void*& buffer, ExtSerialization::BufferProvider& bufferProvider, const void* object, uint64_t offset = 0) = 0; + + /** + Release the serializer and free associated memory. + */ + virtual void release() = 0; +}; + + +/** +Internal serialization manager interface +*/ +class ExtSerializationInternal : public ExtSerialization +{ +public: + /** + Internal interfaces to register and unregister a serializer, used by modules to automatically + register all of their serializers with a serialization manager. + */ + virtual bool registerSerializer(ExtSerializer& serializer) = 0; + virtual bool unregisterSerializer(ExtSerializer& serializer) = 0; + + /** + Find a registered serializer for the given object type and encoding. + + \param[in] objectTypeID ID for the requested object type. + \param[in] encodingID ID for the requested encoding (see EncodingID). + + \return a registered serializer if found, NULL otherwise. + */ + virtual ExtSerializer* findSerializer(uint32_t objectTypeID, uint32_t encodingID) = 0; + + //// Enums //// + enum { HeaderSize = 128 }; +}; + + +template<typename Factory, size_t N> +size_t ExtSerializationLoadSet(Nv::Blast::ExtSerializationInternal& serialization, Factory(&factories)[N]) +{ + size_t count = 0; + + for (auto f : factories) + { + Nv::Blast::ExtSerializer* serializer = f(); + if (serializer != nullptr) + { + if (serialization.registerSerializer(*serializer)) + { + ++count; + } + else + { + NVBLAST_LOG_ERROR("Nv::Blast::ExtSerializationLoadSet: failed to register serailizer:"); + NVBLAST_LOG_ERROR(serializer->getName()); + serializer->release(); + } + } + else + { + NVBLAST_LOG_ERROR("Nv::Blast::ExtSerializationLoadSet: failed to create serailizer."); + } + } + + return count; +} + + +class ExtIStream +{ +public: + enum Flags + { + LittleEndian = (1 << 0), + Fail = (1 << 1) + }; + + ExtIStream(const void* buffer, size_t size) : m_buf(reinterpret_cast<const char*>(buffer)), m_flags(0) + { + m_cur = m_buf; + m_end = m_buf + size; + const uint16_t x = LittleEndian; + m_flags = *reinterpret_cast<const char*>(&x); + } + + bool advance(ptrdiff_t diff) + { + m_cur += diff; + if (m_cur < m_buf) + { + m_cur = m_buf; + m_flags |= Fail; + return false; + } + else + if (m_cur > m_end) + { + m_cur = m_end; + m_flags |= Fail; + return false; + } + return true; + } + + const void* view() + { + return m_cur; + } + + bool read(void* buffer, size_t size) + { + if (!canRead(size)) return false; + std::memcpy(buffer, m_cur, size); + m_cur += size; + return true; + } + + size_t tellg() const { return m_cur - m_buf; } + size_t left() const { return m_end - m_cur; } + + bool eof() const { return m_cur >= m_end; } + bool fail() const { return (m_flags & Fail) != 0; } + +private: + const char* m_buf; + const char* m_cur; + const char* m_end; + uint32_t m_flags; + + bool isLittleEndian() const { return (m_flags & LittleEndian) != 0; } + + bool canRead(size_t size) const { return m_cur + size <= m_end; } + + template<typename T> + friend ExtIStream& operator >> (ExtIStream& s, T& x); +}; + +template<typename T> +NV_INLINE ExtIStream& operator >> (ExtIStream& s, T& x) +{ + if (s.canRead(sizeof(T))) + { + if (s.isLittleEndian()) + { + x = *reinterpret_cast<const T*>(s.m_cur); + s.m_cur += sizeof(T); + } + else + { + char* b = reinterpret_cast<char*>(&x) + sizeof(T); + for (size_t n = sizeof(T); n--;) *--b = *s.m_cur++; + } + } + else + { + s.m_flags |= ExtIStream::Fail; + } + return s; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationLL.capn b/sdk/extensions/serialization/source/NvBlastExtSerializationLL.capn deleted file mode 100644 index 026056f..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerializationLL.capn +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 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. - -@0x9a4a58fac38375e0; - -using Cxx = import "/capnp/c++.capnp"; - -$Cxx.namespace("Nv::Blast::Serialization"); - -struct Asset -{ - header @0 :NvBlastDataBlock; - - iD @1 :UUID; - - chunkCount @2 :UInt32; - - graph @3 :NvBlastSupportGraph; - - leafChunkCount @4 :UInt32; - - firstSubsupportChunkIndex @5 :UInt32; - - bondCount @6 :UInt32; - - chunks @7: List(NvBlastChunk); - - bonds @8: List(NvBlastBond); - - subtreeLeafChunkCounts @9: List(UInt32); - - chunkToGraphNodeMap @10: List(UInt32); -} - -struct NvBlastDataBlock -{ - enum Type - { - assetDataBlock @0; - instanceDataBlock @1; - } - - dataType @0 :Type; - - formatVersion @1 :UInt32; - - size @2 :UInt32; -} - -struct NvBlastChunk -{ - centroid @0 :List(Float32); - - volume @1 :Float32; - - parentChunkIndex @2 :UInt32; - firstChildIndex @3 :UInt32; - childIndexStop @4 :UInt32; - userData @5 :UInt32; -} - -struct NvBlastBond -{ - normal @0 :List(Float32); - area @1 :Float32; - centroid @2 :List(Float32); - userData @3 :UInt32; -} - -struct NvBlastSupportGraph -{ - nodeCount @0 : UInt32; - - chunkIndices @1 : List(UInt32); - adjacencyPartition @2 : List(UInt32); - adjacentNodeIndices @3 : List(UInt32); - adjacentBondIndices @4 : List(UInt32); -} - -struct UUID -{ - value @0 : Data; -} - diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationLLImpl.h b/sdk/extensions/serialization/source/NvBlastExtSerializationLLImpl.h deleted file mode 100644 index d7595ba..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerializationLLImpl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* Copyright (c) 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. -*/ - -#pragma once - -#include "NvBlastExtSerialization.h" -#include "NvBlastAsset.h" -#include "AssetDTO.h" - -namespace Nv -{ - namespace Blast - { - /* - Specializations here - LL asset only - */ - - // Asset - template<> - NV_INLINE bool ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoBuilder(Nv::Blast::Serialization::Asset::Builder& assetBuilder, const Nv::Blast::Asset* asset) - { - return AssetDTO::serialize(assetBuilder, asset); - } - - template<> - NV_INLINE Nv::Blast::Asset* ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::deserializeFromStreamReader(capnp::InputStreamMessageReader &message) - { - Nv::Blast::Serialization::Asset::Reader reader = message.getRoot<Nv::Blast::Serialization::Asset>(); - - return AssetDTO::deserialize(reader); - } - - template<> - NV_INLINE bool ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoMessage(capnp::MallocMessageBuilder& message, const Nv::Blast::Asset* asset) - { - Nv::Blast::Serialization::Asset::Builder assetBuilder = message.initRoot<Nv::Blast::Serialization::Asset>(); - - return serializeIntoBuilder(assetBuilder, asset); - } - } -} diff --git a/sdk/extensions/serialization/source/NvBlastExtSerializationLLInterface.cpp b/sdk/extensions/serialization/source/NvBlastExtSerializationLLInterface.cpp deleted file mode 100644 index 26d8667..0000000 --- a/sdk/extensions/serialization/source/NvBlastExtSerializationLLInterface.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* -* Copyright (c) 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 "NvBlastExtSerializationLLInterface.h" -#include "NvBlastExtSerializationLLImpl.h" -#include <memory> -#include "NvBlastExtSerialization.h" -#include "NvBlastAsset.h" -#include <iostream> -#include "NvBlastExtGlobals.h" - - -NvBlastExtAlloc gAlloc = nullptr; -NvBlastLog gLog = nullptr; - -extern "C" -{ - NVBLAST_API void setAllocator(NvBlastExtAlloc alloc) - { - gAlloc = alloc; - } - - NVBLAST_API void setLog(NvBlastLog log) - { - gLog = log; - } - - NVBLAST_API NvBlastAsset* deserializeAsset(const unsigned char* input, uint32_t size) - { -#if defined(BLAST_LL_ALLOC) - if (gAlloc == nullptr || gLog == nullptr) - { - std::cerr << "Must set allocator and log when using low level serialization library. See setAllocator() and setLog() functions." << std::endl; - return nullptr; - } -#endif - - return Nv::Blast::ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::deserialize(input, size); - } - - NVBLAST_API NvBlastAsset* deserializeAssetFromStream(std::istream &inputStream) - { -#if defined(BLAST_LL_ALLOC) - if (gAlloc == nullptr || gLog == nullptr) - { - std::cerr << "Must set allocator and log when using low level serialization library. See setAllocator() and setLog() functions." << std::endl; - return nullptr; - } -#endif - - return Nv::Blast::ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::deserializeFromStream(inputStream); - } - - NVBLAST_API bool serializeAssetIntoStream(const NvBlastAsset *asset, std::ostream &outputStream) - { -#if defined(BLAST_LL_ALLOC) - if (gAlloc == nullptr || gLog == nullptr) - { - std::cerr << "Must set allocator and log when using low level serialization library. See setAllocator() and setLog() functions." << std::endl; - return false; - } -#endif - - return Nv::Blast::ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoStream(reinterpret_cast<const Nv::Blast::Asset *>(asset), outputStream); - } - - NVBLAST_API bool serializeAssetIntoNewBuffer(const NvBlastAsset *asset, unsigned char **outBuffer, uint32_t &outSize) - { -#if defined(BLAST_LL_ALLOC) - if (gAlloc == nullptr || gLog == nullptr) - { - std::cerr << "Must set allocator and log when using low level serialization library. See setAllocator() and setLog() functions." << std::endl; - return false; - } -#endif - - return Nv::Blast::ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoNewBuffer(reinterpret_cast<const Nv::Blast::Asset *>(asset), outBuffer, outSize); - } - - NVBLAST_API bool serializeAssetIntoExistingBuffer(const NvBlastAsset *asset, unsigned char *buffer, uint32_t maxSize, uint32_t &usedSize) - { -#if defined(BLAST_LL_ALLOC) - if (gAlloc == nullptr || gLog == nullptr) - { - std::cerr << "Must set allocator and log when using low level serialization library. See setAllocator() and setLog() functions." << std::endl; - return false; - } -#endif - - return Nv::Blast::ExtSerialization<Nv::Blast::Asset, Nv::Blast::Serialization::Asset::Reader, Nv::Blast::Serialization::Asset::Builder>::serializeIntoExistingBuffer(reinterpret_cast<const Nv::Blast::Asset *>(asset), buffer, maxSize, usedSize); - } - -} - diff --git a/sdk/extensions/serialization/source/NvBlastExtTkSerialization.capn b/sdk/extensions/serialization/source/NvBlastExtTkSerialization.capn new file mode 100644 index 0000000..5605863 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtTkSerialization.capn @@ -0,0 +1,55 @@ +# 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) 2017 NVIDIA Corporation. All rights reserved. + + +@0xaffe4498f275ee58; + +using Cxx = import "/capnp/c++.capnp"; + +using LL = import "NvBlastExtLlSerialization.capn"; + +$Cxx.namespace("Nv::Blast::Serialization"); + +struct TkAsset +{ + assetLL @0 :LL.Asset; + + jointDescs @1 :List(TkAssetJointDesc); +} + +struct TkAssetJointDesc +{ + nodeIndices @0 :List(UInt32); + attachPositions @1 :List(PxVec3); +} + +struct PxVec3 +{ + x @0 :Float32; + y @1 :Float32; + z @2 :Float32; +} diff --git a/sdk/extensions/serialization/source/NvBlastExtTkSerialization.cpp b/sdk/extensions/serialization/source/NvBlastExtTkSerialization.cpp new file mode 100644 index 0000000..4ecc920 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtTkSerialization.cpp @@ -0,0 +1,105 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtSerializationInternal.h" +#include "NvBlastExtTkSerialization.h" +#include "NvBlastExtTkSerializerCAPN.h" +#include "NvBlastExtTkSerializerRAW.h" + + +namespace Nv +{ +namespace Blast +{ + +TkFramework* sExtTkSerializerFramework = nullptr; + + +class ExtTkSerializerAsset_CPNB : public ExtSerializer +{ +public: + ExtSerializerBoilerplate("TkAsset_CPNB", "Blast high-level asset (Nv::Blast::TkAsset) serialization using Cap'n Proto binary format.", TkObjectTypeID::Asset, ExtSerialization::EncodingID::CapnProtoBinary); + ExtSerializerDefaultFactoryAndRelease(ExtTkSerializerAsset_CPNB); + + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) override + { + return ExtSerializationCAPN<TkAsset, Serialization::TkAsset::Reader, Serialization::TkAsset::Builder>::deserializeFromBuffer(reinterpret_cast<const unsigned char*>(buffer), size); + } + + virtual uint64_t serializeIntoBuffer(void*& buffer, ExtSerialization::BufferProvider& bufferProvider, const void* object, uint64_t offset = 0) override + { + uint64_t usedSize; + if (!ExtSerializationCAPN<TkAsset, Serialization::TkAsset::Reader, Serialization::TkAsset::Builder>::serializeIntoBuffer(reinterpret_cast<const TkAsset*>(object), + reinterpret_cast<unsigned char*&>(buffer), usedSize, &bufferProvider, offset)) + { + return 0; + } + return usedSize; + } +}; + + +class ExTkSerializerAsset_RAW : public ExtSerializer +{ +public: + ExtSerializerBoilerplate("TkAsset_RAW", "Blast high-level asset (Nv::Blast::TkAsset) serialization using raw memory format.", TkObjectTypeID::Asset, ExtSerialization::EncodingID::RawBinary); + ExtSerializerDefaultFactoryAndRelease(ExTkSerializerAsset_RAW); + ExtSerializerReadOnly(ExTkSerializerAsset_RAW); + + virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) override + { + ExtIStream stream(buffer, size); + return deserializeTkAsset(stream, *sExtTkSerializerFramework); + } +}; + +} // namespace Blast +} // namespace Nv + + +/////////////////////////////////////// + + +size_t NvBlastExtTkSerializerLoadSet(Nv::Blast::TkFramework& framework, Nv::Blast::ExtSerialization& serialization) +{ + Nv::Blast::sExtTkSerializerFramework = &framework; + + Nv::Blast::ExtSerializer* (*factories[])() = + { + Nv::Blast::ExtTkSerializerAsset_CPNB::create, + Nv::Blast::ExTkSerializerAsset_RAW::create + }; + + return Nv::Blast::ExtSerializationLoadSet(static_cast<Nv::Blast::ExtSerializationInternal&>(serialization), factories); +} + + +uint64_t NvBlastExtSerializationSerializeTkAssetIntoBuffer(void*& buffer, Nv::Blast::ExtSerialization& serialization, const Nv::Blast::TkAsset* asset) +{ + return serialization.serializeIntoBuffer(buffer, asset, Nv::Blast::TkObjectTypeID::Asset); +} diff --git a/sdk/extensions/serialization/source/NvBlastExtTkSerializerCAPN.h b/sdk/extensions/serialization/source/NvBlastExtTkSerializerCAPN.h new file mode 100644 index 0000000..7922338 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtTkSerializerCAPN.h @@ -0,0 +1,70 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + +#include "NvBlastExtSerializationCAPN.h" +#include "NvBlastTkAsset.h" +#include "TkAssetDTO.h" + + +/** +Specializations of ExtSerializationCAPN for BlastTk +*/ + +namespace Nv +{ +namespace Blast +{ + +//// Nv::Blast::TkAsset //// + +template<> +NV_INLINE bool ExtSerializationCAPN<TkAsset, Serialization::TkAsset::Reader, Serialization::TkAsset::Builder>::serializeIntoBuilder(Serialization::TkAsset::Builder& assetBuilder, const TkAsset* asset) +{ + return TkAssetDTO::serialize(assetBuilder, asset); +} + +template<> +NV_INLINE TkAsset* ExtSerializationCAPN<TkAsset, Serialization::TkAsset::Reader, Serialization::TkAsset::Builder>::deserializeFromStreamReader(capnp::InputStreamMessageReader &message) +{ + Serialization::TkAsset::Reader reader = message.getRoot<Serialization::TkAsset>(); + + return TkAssetDTO::deserialize(reader); +} + +template<> +NV_INLINE bool ExtSerializationCAPN<TkAsset, Serialization::TkAsset::Reader, Serialization::TkAsset::Builder>::serializeIntoMessage(capnp::MallocMessageBuilder& message, const TkAsset* asset) +{ + Serialization::TkAsset::Builder assetBuilder = message.initRoot<Serialization::TkAsset>(); + + return serializeIntoBuilder(assetBuilder, asset); +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.cpp b/sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.cpp new file mode 100644 index 0000000..ed5ce00 --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.cpp @@ -0,0 +1,184 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtSerializationInternal.h" +#include "NvBlastTkFramework.h" +#include "NvBlastTkAsset.h" +#include "NvBlast.h" + + +namespace Nv +{ +namespace Blast +{ + +// Legacy IDs +struct ExtTkSerializationLegacyID +{ + enum Enum + { + Framework = NVBLAST_FOURCC('T', 'K', 'F', 'W'), //!< TkFramework identifier token, used in serialization + Asset = NVBLAST_FOURCC('A', 'S', 'S', 'T'), //!< TkAsset identifier token, used in serialization + Family = NVBLAST_FOURCC('A', 'C', 'T', 'F'), //!< TkFamily identifier token, used in serialization + }; +}; + + +// Legacy object format versions +struct ExtTkSerializationLegacyAssetVersion +{ + enum Enum + { + /** 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 + }; +}; + +struct ExtTkSerializationLegacyFamilyVersion +{ + enum Enum + { + /** 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 + }; +}; + + +static bool deserializeTkObjectHeader(uint32_t& legacyTypeID, uint32_t& legacyVersion, NvBlastID& objID, uint64_t& userIntData, ExtIStream& stream) +{ + // Read framework ID + uint32_t fwkID; + stream >> fwkID; + if (fwkID != ExtTkSerializationLegacyID::Framework) + { + NVBLAST_LOG_ERROR("deserializeTkObjectHeader: stream does not contain a BlastTk legacy object."); + return false; + } + + // Read object class ID + stream >> legacyTypeID; + + // Read object class version and ensure it's current + stream >> legacyVersion; + + // Object ID + stream.read(objID.data, sizeof(NvBlastID)); + + // Serializable user data + uint32_t lsd, msd; + stream >> lsd >> msd; + userIntData = static_cast<uint64_t>(msd) << 32 | static_cast<uint64_t>(lsd); + + return !stream.fail(); +} + + +TkAsset* deserializeTkAsset(ExtIStream& stream, TkFramework& framework) +{ + // Deserializer header + uint32_t legacyTypeID; + uint32_t legacyVersion; + NvBlastID objID; + uint64_t userIntData; + if (!deserializeTkObjectHeader(legacyTypeID, legacyVersion, objID, userIntData, stream)) + { + return nullptr; + } + + if (legacyTypeID != ExtTkSerializationLegacyID::Asset) + { + NVBLAST_LOG_ERROR("deserializeTkAsset: stream does not contain a BlastTk legacy asset."); + return nullptr; + } + + if (legacyVersion > ExtTkSerializationLegacyAssetVersion::Current) + { + NVBLAST_LOG_ERROR("deserializeTkAsset: stream contains a BlastTk legacy asset which is in an unknown version."); + return nullptr; + } + + // LL asset + uint32_t assetSize; + stream >> assetSize; + NvBlastAsset* llAsset = static_cast<NvBlastAsset*>(NVBLAST_ALLOC_NAMED(assetSize, "deserializeTkAsset")); + stream.read(reinterpret_cast<char*>(llAsset), assetSize); + + // Joint descs + uint32_t jointDescCount; + stream >> jointDescCount; + std::vector<TkAssetJointDesc> jointDescs(jointDescCount); + for (uint32_t i = 0; i < jointDescs.size(); ++i) + { + TkAssetJointDesc& jointDesc = jointDescs[i]; + stream >> jointDesc.nodeIndices[0]; + stream >> jointDesc.nodeIndices[1]; + stream >> jointDesc.attachPositions[0].x; + stream >> jointDesc.attachPositions[0].y; + stream >> jointDesc.attachPositions[0].z; + stream >> jointDesc.attachPositions[1].x; + stream >> jointDesc.attachPositions[1].y; + stream >> jointDesc.attachPositions[1].z; + } + + if (stream.fail()) + { + NVBLAST_FREE(llAsset); + return nullptr; + } + + TkAsset* asset = framework.createAsset(llAsset, jointDescs.data(), (uint32_t)jointDescs.size(), true); + + NvBlastID zeroID; + memset(zeroID.data, 0, sizeof(zeroID)); + if (!memcmp(zeroID.data, objID.data, sizeof(NvBlastID))) + { + asset->setID(objID); + } + asset->userIntData = userIntData; + + return asset; +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.h b/sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.h new file mode 100644 index 0000000..74006ee --- /dev/null +++ b/sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.h @@ -0,0 +1,54 @@ +// 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) 2017 NVIDIA Corporation. All rights reserved. + + +#pragma once + + +/** +Raw serialization function declarations for BlastTk +*/ + +#include <stdint.h> + + +namespace Nv +{ +namespace Blast +{ + +// Forward declarations +class TkAsset; +class TkFramework; +class ExtIStream; + +//// Nv::Blast::TkAsset //// + +TkAsset* deserializeTkAsset(ExtIStream& stream, TkFramework& framework); + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h b/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h index 385bf52..8daf9cf 100644 --- a/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h +++ b/sdk/extensions/shaders/include/NvBlastExtDamageShaders.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 NVBLASTEXTDAMAGESHADERS_H #define NVBLASTEXTDAMAGESHADERS_H #include "NvBlastTypes.h" -#include "NvBlastPreprocessor.h" + /** A few example damage shader implementations. @@ -24,22 +42,39 @@ A few example damage shader implementations. /////////////////////////////////////////////////////////////////////////////// /** -Specific parameters for the material functions here present. +Example of simple material. It is passed into damage shader, thus it is not used +currently in any of them. The user can use it to filter and normalize before applying. Material function implementers may choose their own set. */ struct NvBlastExtMaterial { - float singleChunkThreshold; //!< subsupport chunks only take damage surpassing this value - float graphChunkThreshold; //!< support chunks only take damage surpassing this value - float bondTangentialThreshold; //!< bond only take damage surpassing this value - float bondNormalThreshold; //!< currently unused - forward damage propagation - float damageAttenuation; //!< factor of damage attenuation while forwarding + NvBlastExtMaterial() : health(100.f), minDamageThreshold(0.0f), maxDamageThreshold(1.0f) {} + + float health; //!< health + float minDamageThreshold; //!< min damage fraction threshold to be applied. Range [0, 1]. For example 0.1 filters all damage below 10% of health. + float maxDamageThreshold; //!< max damage fraction threshold to be applied. Range [0, 1]. For example 0.8 won't allow more then 80% of health damage to be applied. + + /** + Helper to normalize damage. + + Pass damage defined in health, damage in range [0, 1] is returned, where 0 basically + indicates that the threshold wasn't reached and there is no point in applying it. + + \param[in] damageInHealth Damage defined in terms of health amount to be reduced. + + \return normalized damage + */ + float getNormalizedDamage(float damageInHealth) const + { + const float damage = health > 0.f ? damageInHealth / health : 1.0f; + return damage > minDamageThreshold ? (damage < maxDamageThreshold ? damage : maxDamageThreshold) : 0.f; + } }; /////////////////////////////////////////////////////////////////////////////// -// Radial Damage +// Point Radial Damage /////////////////////////////////////////////////////////////////////////////// /** @@ -47,7 +82,7 @@ Radial Damage Desc */ struct NvBlastExtRadialDamageDesc { - float compressive; //!< compressive (radial) damage component + float damage; //!< normalized damage amount, range: [0, 1] (maximum health value to be reduced) float position[3]; //!< origin of damage action float minRadius; //!< inner radius of damage action float maxRadius; //!< outer radius of damage action @@ -85,6 +120,36 @@ NVBLAST_API bool NvBlastExtDamageActorRadialFalloff(NvBlastActor* actor, NvBlast /////////////////////////////////////////////////////////////////////////////// +// Segment Radial Damage +/////////////////////////////////////////////////////////////////////////////// + +/** +Segment Radial Damage Desc +*/ +struct NvBlastExtSegmentRadialDamageDesc +{ + float damage; //!< normalized damage amount, range: [0, 1] (maximum health value to be reduced) + float position0[3]; //!< damage segment point A position + float position1[3]; //!< damage segment point B position + float minRadius; //!< inner radius of damage action + float maxRadius; //!< outer radius of damage action +}; + +/** +Segment Radial Falloff damage for both graph and subgraph shaders. + +For every bond/chunk damage is calculated from the distance to line segment AB described in NvBlastExtSegmentRadialDamageDesc. +If distance is smaller then minRadius, full compressive amount of damage is applied. From minRadius to maxRaidus it linearly falls off to zero. + +NOTE: The signature of shader functions are equal to NvBlastGraphShaderFunction and NvBlastSubgraphShaderFunction respectively. +They are not expected to be called directly. +@see NvBlastGraphShaderFunction, NvBlastSubgraphShaderFunction +*/ +NVBLAST_API void NvBlastExtSegmentFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params); +NVBLAST_API void NvBlastExtSegmentFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params); + + +/////////////////////////////////////////////////////////////////////////////// // Shear Damage /////////////////////////////////////////////////////////////////////////////// @@ -93,8 +158,13 @@ Shear Damage Desc */ struct NvBlastExtShearDamageDesc { - float shear[3]; //!< directional damage component + float damage; //!< normalized damage amount, range: [0, 1] (maximum health value to be reduced) + + float normal[3]; //!< directional damage component float position[3]; //!< origin of damage action + + float minRadius; //!< inner radius of damage action + float maxRadius; //!< outer radius of damage action }; /** diff --git a/sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp b/sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp new file mode 100644 index 0000000..8027447 --- /dev/null +++ b/sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp @@ -0,0 +1,368 @@ +// 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 "NvBlastExtDamageShaders.h" +#include "NvBlastIndexFns.h" +#include "NvBlastMath.h" +#include "NvBlastGeometry.h" +#include "NvBlastAssert.h" +#include "NvBlast.h" +#include <cmath> // for abs() on linux + +using namespace Nv::Blast; +using namespace Nv::Blast::VecMath; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Profiles +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +typedef float(*ProfileFunction)(float, float, float, float); + +float falloffProfile(float min, float max, float x, float f = 1.0f) +{ + if (x > max) return 0.0f; + if (x < min) return f; + + float y = 1.0f - (x - min) / (max - min); + return y * f; +} + +float cutterProfile(float min, float max, float x, float f = 1.0f) +{ + if (x > max || x < min) return 0.0f; + + return f; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Damage Functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +typedef float(*DamageFunction)(const float pos[3], const void* damageDescBuffer, uint32_t damageIndex); + +template <ProfileFunction profileFn, typename DescT = NvBlastExtRadialDamageDesc> +float pointDistanceDamage(const float pos[3], const void* damageDescBuffer, uint32_t damageIndex) +{ + const DescT* damageData = reinterpret_cast<const DescT*>(damageDescBuffer); + const DescT& desc = damageData[damageIndex]; + + float relativePosition[3]; + sub(desc.position, pos, relativePosition); + const float distance = sqrtf(dot(relativePosition, relativePosition)); + const float damage = profileFn(desc.minRadius, desc.maxRadius, distance, desc.damage); + return damage; +} + + +// Distance from point 'p' to line segment '(a, b)' +float distanceToSegment(const float p[3], const float a[3], const float b[3]) +{ + float v[3]; + sub(b, a, v); + + float w[3]; + sub(p, a, w); + + const float c1 = dot(v, w); + if (c1 <= 0) + return length(w); + + const float c2 = dot(v, v); + if (c2 < c1) + return dist(p, b); + + const float t = c1 / c2; + mul(v, t); + return dist(v, w); +} + +template <ProfileFunction profileFn> +float segmentDistanceDamage(const float pos[3], const void* damageDescBuffer, uint32_t damageIndex) +{ + const NvBlastExtSegmentRadialDamageDesc* damageData = reinterpret_cast<const NvBlastExtSegmentRadialDamageDesc*>(damageDescBuffer); + const NvBlastExtSegmentRadialDamageDesc& desc = damageData[damageIndex]; + + const float distance = distanceToSegment(pos, desc.position0, desc.position1); + const float damage = profileFn(desc.minRadius, desc.maxRadius, distance, desc.damage); + return damage; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Radial Graph Shader Template +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template <DamageFunction damageFn> +void RadialProfileGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; + const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; + const uint32_t* adjacencyPartition = actor->adjacencyPartition; + const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; + const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; + const NvBlastBond* assetBonds = actor->assetBonds; + const float* familyBondHealths = actor->familyBondHealths; + + const uint32_t damageCount = params->damageDescCount; + + uint32_t outCount = 0; + + uint32_t currentNodeIndex = firstGraphNodeIndex; + while (!Nv::Blast::isInvalidIndex(currentNodeIndex)) + { + for (uint32_t adj = adjacencyPartition[currentNodeIndex]; adj < adjacencyPartition[currentNodeIndex + 1]; adj++) + { + uint32_t adjacentNodeIndex = adjacentNodeIndices[adj]; + if (currentNodeIndex < adjacentNodeIndex) + { + uint32_t bondIndex = adjacentBondIndices[adj]; + + // skip bonds that are already broken or were visited already + // TODO: investigate why testing against health > -1.0f seems slower + // could reuse the island edge bitmap instead + if ((familyBondHealths[bondIndex] > 0.0f)) + { + + const NvBlastBond& bond = assetBonds[bondIndex]; + + float totalBondDamage = 0.0f; + + for (uint32_t damageIndex = 0; damageIndex < damageCount; damageIndex++) + { + totalBondDamage += damageFn(bond.centroid, params->damageDescBuffer, damageIndex); + } + + if (totalBondDamage > 0.0f) + { + NvBlastBondFractureData& outCommand = commandBuffers->bondFractures[outCount++]; + outCommand.nodeIndex0 = currentNodeIndex; + outCommand.nodeIndex1 = adjacentNodeIndex; + outCommand.health = totalBondDamage; + } + } + } + } + currentNodeIndex = graphNodeIndexLinks[currentNodeIndex]; + } + + commandBuffers->bondFractureCount = outCount; + commandBuffers->chunkFractureCount = 0; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Radial Single Shader Template +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template <DamageFunction damageFn> +void RadialProfileSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + uint32_t chunkFractureCount = 0; + uint32_t chunkFractureCountMax = commandBuffers->chunkFractureCount; + const uint32_t chunkIndex = actor->chunkIndex; + const NvBlastChunk* assetChunks = actor->assetChunks; + const NvBlastChunk& chunk = assetChunks[chunkIndex]; + + float totalDamage = 0.0f; + for (uint32_t damageIndex = 0; damageIndex < params->damageDescCount; ++damageIndex) + { + totalDamage += damageFn(chunk.centroid, params->damageDescBuffer, damageIndex); + } + + if (totalDamage > 0.0f && chunkFractureCount < chunkFractureCountMax) + { + NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; + frac.chunkIndex = chunkIndex; + frac.health = totalDamage; + } + + commandBuffers->bondFractureCount = 0; + commandBuffers->chunkFractureCount = chunkFractureCount; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Radial Shaders Instantiation +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void NvBlastExtFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileGraphShader<pointDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<pointDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtCutterGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileGraphShader<pointDistanceDamage<cutterProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtCutterSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<pointDistanceDamage<cutterProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtSegmentFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileGraphShader<segmentDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtSegmentFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<segmentDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Shear Shader +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void NvBlastExtShearGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + uint32_t chunkFractureCount = 0; + uint32_t chunkFractureCountMax = commandBuffers->chunkFractureCount; + uint32_t bondFractureCount = 0; + uint32_t bondFractureCountMax = commandBuffers->bondFractureCount; + + for (uint32_t i = 0; i < params->damageDescCount; ++i) + { + const NvBlastExtShearDamageDesc& desc = reinterpret_cast<const NvBlastExtShearDamageDesc*>(params->damageDescBuffer)[i]; + const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; + const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; + const uint32_t* chunkIndices = actor->chunkIndices; + const uint32_t* adjacencyPartition = actor->adjacencyPartition; + const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; + const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; + const NvBlastBond* assetBonds = actor->assetBonds; + const NvBlastChunk* assetChunks = actor->assetChunks; + const float* familyBondHealths = actor->familyBondHealths; + const float* supportChunkHealths = actor->supportChunkHealths; + + uint32_t closestNode = findClosestNode(desc.position + , firstGraphNodeIndex, graphNodeIndexLinks + , adjacencyPartition, adjacentNodeIndices, adjacentBondIndices + , assetBonds, familyBondHealths + , assetChunks, supportChunkHealths, chunkIndices); + + uint32_t nodeIndex = closestNode; + float maxDist = 0.0f; + uint32_t nextNode = invalidIndex<uint32_t>(); + + if (chunkFractureCount < chunkFractureCountMax) + { + const uint32_t chunkIndex = chunkIndices[nodeIndex]; + const NvBlastChunk& chunk = assetChunks[chunkIndex]; + NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; + frac.chunkIndex = chunkIndex; + frac.health = pointDistanceDamage<falloffProfile, NvBlastExtShearDamageDesc>(chunk.centroid, params->damageDescBuffer, i); + } + + do { + const uint32_t startIndex = adjacencyPartition[nodeIndex]; + const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1]; + + + for (uint32_t adjacentNodeIndex = startIndex; adjacentNodeIndex < stopIndex; adjacentNodeIndex++) + { + const uint32_t neighbourIndex = adjacentNodeIndices[adjacentNodeIndex]; + const uint32_t bondIndex = adjacentBondIndices[adjacentNodeIndex]; + const NvBlastBond& bond = assetBonds[bondIndex]; + + if (!(familyBondHealths[bondIndex] > 0.0f)) + continue; + + float shear = 1 * std::abs(1 - std::abs(VecMath::dot(desc.normal, bond.normal))); + + float d[3]; VecMath::sub(bond.centroid, desc.position, d); + float ahead = VecMath::dot(d, desc.normal); + if (ahead > maxDist) + { + maxDist = ahead; + nextNode = neighbourIndex; + } + + const float damage = pointDistanceDamage<falloffProfile, NvBlastExtShearDamageDesc>(bond.centroid, params->damageDescBuffer, i); + if (damage > 0.0f && bondFractureCount < bondFractureCountMax) + { + NvBlastBondFractureData& frac = commandBuffers->bondFractures[bondFractureCount++]; + frac.userdata = bond.userData; + frac.nodeIndex0 = nodeIndex; + frac.nodeIndex1 = neighbourIndex; + frac.health = shear * damage; + } + } + + if (nodeIndex == nextNode) + break; + + nodeIndex = nextNode; + } while (!isInvalidIndex(nextNode)); + } + + commandBuffers->bondFractureCount = bondFractureCount; + commandBuffers->chunkFractureCount = chunkFractureCount; +} + +void NvBlastExtShearSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<pointDistanceDamage<falloffProfile, NvBlastExtShearDamageDesc>>(commandBuffers, actor, params); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper Functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool NvBlastExtDamageActorRadialFalloff(NvBlastActor* actor, NvBlastFractureBuffers* buffers, const NvBlastExtRadialDamageDesc* damageDescBuffer, uint32_t damageDescCount, const NvBlastExtMaterial* material, NvBlastLog logFn, NvBlastTimers* timers) +{ + NvBlastDamageProgram program = + { + NvBlastExtFalloffGraphShader, + NvBlastExtFalloffSubgraphShader + }; + + NvBlastProgramParams params = + { + damageDescBuffer, + damageDescCount, + material + }; + + NvBlastActorGenerateFracture(buffers, actor, program, ¶ms, logFn, timers); + if (buffers->bondFractureCount > 0 || buffers->chunkFractureCount > 0) + { + NvBlastActorApplyFracture(nullptr, actor, buffers, logFn, timers); + return true; + } + + return false; +}
\ No newline at end of file diff --git a/sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp b/sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp deleted file mode 100644 index 00d1010..0000000 --- a/sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp +++ /dev/null @@ -1,205 +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 "NvBlastExtDamageShaders.h" -#include "NvBlastIndexFns.h" -#include "NvBlastMath.h" -#include "NvBlastGeometry.h" -#include "NvBlastAssert.h" -#include "NvBlast.h" -#include "stdlib.h" // for abs() on linux - -using namespace Nv::Blast; -using namespace Nv::Blast::VecMath; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Profiles -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -typedef float(*ProfileFunction)(float, float, float, float); - -float falloffProfile(float min, float max, float x, float f = 1.0f) -{ - if (x > max) return 0.0f; - if (x < min) return f; - - float y = 1.0f - (x - min) / (max - min); - return y * f; -} - -float cutterProfile(float min, float max, float x, float f = 1.0f) -{ - if (x > max || x < min) return 0.0f; - - return f; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Radial Graph Shader Template -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <ProfileFunction profile> -void RadialProfileGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; - const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; - const uint32_t* adjacencyPartition = actor->adjacencyPartition; - const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; - const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; - const NvBlastBond* assetBonds = actor->assetBonds; - const float* familyBondHealths = actor->familyBondHealths; - - const NvBlastExtRadialDamageDesc* damageData = reinterpret_cast<const NvBlastExtRadialDamageDesc*>(params->damageDescBuffer); - const uint32_t damageCount = params->damageDescCount; - - uint32_t outCount = 0; - - uint32_t currentNodeIndex = firstGraphNodeIndex; - while (!Nv::Blast::isInvalidIndex(currentNodeIndex)) - { - for (uint32_t adj = adjacencyPartition[currentNodeIndex]; adj < adjacencyPartition[currentNodeIndex + 1]; adj++) - { - uint32_t adjacentNodeIndex = adjacentNodeIndices[adj]; - if (currentNodeIndex < adjacentNodeIndex) - { - uint32_t bondIndex = adjacentBondIndices[adj]; - - // skip bonds that are already broken or were visited already - // TODO: investigate why testing against health > -1.0f seems slower - // could reuse the island edge bitmap instead - if ((familyBondHealths[bondIndex] > 0.0f)) - { - - const NvBlastBond& bond = assetBonds[bondIndex]; - - float totalBondDamage = 0.0f; - - for (uint32_t damageIndex = 0; damageIndex < damageCount; damageIndex++) - { - const NvBlastExtRadialDamageDesc& damage = damageData[damageIndex]; - - float relativePosition[3]; - sub(damage.position, bond.centroid, relativePosition); - float distance = sqrtf(dot(relativePosition, relativePosition)); - - float dir[3]; - normal(relativePosition, dir); - - totalBondDamage += profile(damage.minRadius, damage.maxRadius, distance, damage.compressive); - } - - if (totalBondDamage > 0.0f) - { - NvBlastBondFractureData& outCommand = commandBuffers->bondFractures[outCount++]; - outCommand.nodeIndex0 = currentNodeIndex; - outCommand.nodeIndex1 = adjacentNodeIndex; - outCommand.health = totalBondDamage; - } - } - } - } - currentNodeIndex = graphNodeIndexLinks[currentNodeIndex]; - } - - commandBuffers->bondFractureCount = outCount; - commandBuffers->chunkFractureCount = 0; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Radial Single Shader Template -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <ProfileFunction profile> -void RadialProfileSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - uint32_t chunkFractureCount = 0; - const uint32_t chunkIndex = actor->chunkIndex; - const NvBlastChunk* assetChunks = actor->assetChunks; - const NvBlastChunk& chunk = assetChunks[chunkIndex]; - - float totalDamage = 0.0f; - for (uint32_t i = 0; i < params->damageDescCount; ++i) - { - const NvBlastExtRadialDamageDesc& damage = reinterpret_cast<const NvBlastExtRadialDamageDesc*>(params->damageDescBuffer)[i]; - - float relativePosition[3]; - sub(damage.position, chunk.centroid, relativePosition); - float distance = sqrtf(dot(relativePosition, relativePosition)); - - totalDamage += profile(damage.minRadius, damage.maxRadius, distance, damage.compressive); - } - - if (totalDamage > 0.0f) - { - NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; - frac.chunkIndex = chunkIndex; - frac.health = totalDamage; - } - - commandBuffers->bondFractureCount = 0; - commandBuffers->chunkFractureCount = chunkFractureCount; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Shader Instantiation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void NvBlastExtFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileGraphShader<falloffProfile>(commandBuffers, actor, params); -} - -void NvBlastExtFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileSubgraphShader<falloffProfile>(commandBuffers, actor, params); -} - -void NvBlastExtCutterGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileGraphShader<cutterProfile>(commandBuffers, actor, params); -} - -void NvBlastExtCutterSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileSubgraphShader<cutterProfile>(commandBuffers, actor, params); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helper Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool NvBlastExtDamageActorRadialFalloff(NvBlastActor* actor, NvBlastFractureBuffers* buffers, const NvBlastExtRadialDamageDesc* damageDescBuffer, uint32_t damageDescCount, const NvBlastExtMaterial* material, NvBlastLog logFn, NvBlastTimers* timers) -{ - NvBlastDamageProgram program = - { - NvBlastExtFalloffGraphShader, - NvBlastExtFalloffSubgraphShader - }; - - NvBlastProgramParams params = - { - damageDescBuffer, - damageDescCount, - material - }; - - NvBlastActorGenerateFracture(buffers, actor, program, ¶ms, logFn, timers); - if (buffers->bondFractureCount > 0 || buffers->chunkFractureCount > 0) - { - NvBlastActorApplyFracture(nullptr, actor, buffers, logFn, timers); - return true; - } - - return false; -}
\ No newline at end of file diff --git a/sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp b/sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp deleted file mode 100644 index 26707e1..0000000 --- a/sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp +++ /dev/null @@ -1,149 +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 "NvBlastExtDamageShaders.h" -#include "NvBlastIndexFns.h" -#include "NvBlastMath.h" -#include "NvBlastGeometry.h" -#include "NvBlastAssert.h" -#include "stdlib.h" // for abs() on linux - -using namespace Nv::Blast; -using namespace Nv::Blast::VecMath; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Graph Shader -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void NvBlastExtShearGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - const NvBlastExtMaterial* materialProperties = reinterpret_cast<const NvBlastExtMaterial*>(params->material); - const float graphChunkThreshold = materialProperties->graphChunkThreshold; - const float bondTangentialThreshold = materialProperties->bondTangentialThreshold; - const float damageAttenuation = 1.0f - materialProperties->damageAttenuation; - - uint32_t chunkFractureCount = 0; - uint32_t chunkFractureCountMax = commandBuffers->chunkFractureCount; - uint32_t bondFractureCount = 0; - uint32_t bondFractureCountMax = commandBuffers->bondFractureCount; - - for (uint32_t i = 0; i < params->damageDescCount; ++i) - { - const NvBlastExtShearDamageDesc& damage = reinterpret_cast<const NvBlastExtShearDamageDesc*>(params->damageDescBuffer)[i]; - - const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; - const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; - const uint32_t* chunkIndices = actor->chunkIndices; - const uint32_t* adjacencyPartition = actor->adjacencyPartition; - const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; - const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; - const NvBlastBond* assetBonds = actor->assetBonds; - const float* familyBondHealths = actor->familyBondHealths; - - uint32_t closestNode = findNodeByPositionLinked(damage.position, firstGraphNodeIndex, graphNodeIndexLinks, adjacencyPartition, adjacentNodeIndices, adjacentBondIndices, assetBonds, familyBondHealths); - NVBLAST_ASSERT(!isInvalidIndex(closestNode)); - - float damageDir[3]; - float damageMag = VecMath::normal(damage.shear, damageDir); - - uint32_t nodeIndex = closestNode; - float maxDist = 0.0f; - uint32_t nextNode = invalidIndex<uint32_t>(); - - if (damageMag > graphChunkThreshold && chunkFractureCount < chunkFractureCountMax) - { - NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; - frac.chunkIndex = chunkIndices[nodeIndex]; - frac.health = damageMag * 2; - } - - do { - const uint32_t startIndex = adjacencyPartition[nodeIndex]; - const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1]; - - - for (uint32_t adjacentNodeIndex = startIndex; adjacentNodeIndex < stopIndex; adjacentNodeIndex++) - { - const uint32_t neighbourIndex = adjacentNodeIndices[adjacentNodeIndex]; - const uint32_t bondIndex = adjacentBondIndices[adjacentNodeIndex]; - const NvBlastBond& bond = assetBonds[bondIndex]; - - if (!(familyBondHealths[bondIndex] > 0.0f)) - continue; - - float shear = 1 * abs(1 - abs(VecMath::dot(damage.shear, bond.normal))); - - float d[3]; VecMath::sub(bond.centroid, damage.position, d); - float ahead = VecMath::dot(d, damage.shear); - if (ahead > maxDist) - { - maxDist = ahead; - nextNode = neighbourIndex; - } - - if (shear > bondTangentialThreshold && bondFractureCount < bondFractureCountMax) - { - NvBlastBondFractureData& frac = commandBuffers->bondFractures[bondFractureCount++]; - frac.userdata = bond.userData; - frac.nodeIndex0 = nodeIndex; - frac.nodeIndex1 = neighbourIndex; - frac.health = shear; - } - } - - if (nodeIndex == nextNode) - break; - - nodeIndex = nextNode; - - damageMag *= damageAttenuation; - } while (!isInvalidIndex(nextNode)); - } - - commandBuffers->bondFractureCount = bondFractureCount; - commandBuffers->chunkFractureCount = chunkFractureCount; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Single Shader -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void NvBlastExtShearSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - const NvBlastExtMaterial* materialProperties = reinterpret_cast<const NvBlastExtMaterial*>(params->material); - - uint32_t chunkFractureCount = 0; - - float totalDamage = 0.0f; - for (uint32_t i = 0; i < params->damageDescCount; ++i) - { - const NvBlastExtShearDamageDesc& damage = reinterpret_cast<const NvBlastExtShearDamageDesc*>(params->damageDescBuffer)[i]; - - float damageDir[3]; - float damageMag = VecMath::normal(damage.shear, damageDir); - - if (damageMag > materialProperties->singleChunkThreshold) - { - totalDamage += damageMag * 2; - } - } - - if (totalDamage > 0.0f) - { - NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; - frac.chunkIndex = actor->chunkIndex; - frac.health = totalDamage; - } - - commandBuffers->bondFractureCount = 0; - commandBuffers->chunkFractureCount = chunkFractureCount; -} diff --git a/sdk/extensions/stress/include/NvBlastExtStressSolver.h b/sdk/extensions/stress/include/NvBlastExtStressSolver.h new file mode 100644 index 0000000..471c35e --- /dev/null +++ b/sdk/extensions/stress/include/NvBlastExtStressSolver.h @@ -0,0 +1,410 @@ +// 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 NVBLASTEXTSTRESSSOLVER_H +#define NVBLASTEXTSTRESSSOLVER_H + +#include "NvBlastTypes.h" +#include "PxVec3.h" +#include <vector> + + +namespace Nv +{ +namespace Blast +{ + + +/** +Stress Solver Settings + +Stress on every bond is calculated as +stress = (bond.linearStress * stressLinearFactor + bond.angularStress * stressAngularFactor) / hardness; +where: +bond.linearStress = the linear stress force on particular bond +bond.angularStress = the angular stress force on particular bond +stressLinearFactor, stressAngularFactor, hardness = multiplier parameters set by this struct + +Support graph reduction: +graphReductionLevel is the number of node merge passes. The resulting graph will be +roughly 2^graphReductionLevel times smaller than the original. +*/ +struct ExtStressSolverSettings +{ + float hardness; //!< hardness of bond's material + 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() : + hardness(1000.0f), + stressLinearFactor(0.25f), + stressAngularFactor(0.75f), + bondIterationsPerFrame(18000), + graphReductionLevel(3) + {} +}; + + +/** +Parameter to addForce() calls, determines the exact operation that is carried out. + +@see ExtStressSolver.addForce() +*/ +struct ExtForceMode +{ + enum Enum + { + IMPULSE, //!< parameter has unit of mass * distance /time + VELOCITY, //!< parameter has unit of distance / time, i.e. the effect is mass independent: a velocity change. + }; +}; + + +/** +Stress Solver. + +Uses NvBlastFamily, allocates and prepares its graph once when it's created. Then it's being quickly updated on every +actor split. +It uses NvBlastAsset support graph, you can apply forces on nodes and stress on bonds will be calculated as the result. +When stress on bond exceeds it's health bond is considered broken (overstressed). +Basic usage: +1. Create it with create function once for family +2. Fill node info for every node in support graph or use setAllNodesInfoFromLL() function. +3. Use notifyActorCreated / notifyActorDestroyed whenever actors are created and destroyed in family. +4. Every frame: Apply forces (there are different functions for it see @addForce) +5. Every frame: Call update() for actual solver to process. +6. If getOverstressedBondCount() > 0 use generateFractureCommands() functions to get FractureCommands with bonds fractured +*/ +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(NvBlastFamily& family, ExtStressSolverSettings settings = ExtStressSolverSettings()); + + + //////// interface //////// + + /** + Release this stress solver. + */ + virtual void release() = 0; + + /** + Set node info. + + All the required info per node for stress solver is set with this function. Call it for every node in graph or use setAllNodesInfoFromLL(). + + \param[in] graphNodeIndex Index of the node in support graph. see NvBlastSupportGraph. + \param[in] mass Node mass. For static node it is irrelevant. + \param[in] volume Node volume. For static node it is irrelevant. + \param[in] localPosition Node local position. + \param[in] isStatic Is node static. + */ + virtual void setNodeInfo(uint32_t graphNodeIndex, float mass, float volume, physx::PxVec3 localPosition, bool isStatic) = 0; + + /** + Set all nodes info using low level NvBlastAsset data. + Uses NvBlastChunk's centroid and volume. + Uses 'world' node to mark nodes as static. + + \param[in] density Density. Used to convert volume to mass. + */ + virtual void setAllNodesInfoFromLL(float density = 1.0f) = 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; + + /** + Notify stress solver on newly created actor. + + Call this function for all initial actors present in family and later upon every actor split. + + \param[in] actor The actor created. + + \return true if actor will take part in stress solver process. false if actor doesn't contain any bonds. + */ + virtual bool notifyActorCreated(const NvBlastActor& actor) = 0; + + /** + Notify stress solver on destroyed actor. + + Call this function when actor is destroyed (split futher) or deactivated. + + \param[in] actor The actor destroyed. + */ + virtual void notifyActorDestroyed(const NvBlastActor& actor) = 0; + + /** + Apply external impulse on particular actor of family. This function will find nearest actor's graph node to apply impulse on. + + \param[in] actor The actor to apply impulse on. + \param[in] localPosition Local position in actor's coordinates to apply impulse on. + \param[in] localForce Force to apply in local actor's coordinates. + \param[in] mode The mode to use when applying the force/impulse(see #ExtForceMode) + + \return true iff node was found and force applied. + */ + virtual bool addForce(const NvBlastActor& actor, physx::PxVec3 localPosition, physx::PxVec3 localForce, ExtForceMode::Enum mode = ExtForceMode::IMPULSE) = 0; + + /** + Apply external impulse on particular node. + + \param[in] graphNodeIndex The graph node index to apply impulse on. See #NvBlastSupportGraph. + \param[in] localForce Force to apply in local actor's coordinates. + \param[in] mode The mode to use when applying the force/impulse(see #ExtForceMode) + */ + virtual void addForce(uint32_t graphNodeIndex, physx::PxVec3 localForce, ExtForceMode::Enum mode = ExtForceMode::IMPULSE) = 0; + + /** + Apply external gravity on particular actor of family. This function applies gravity on every node withing actor, so it makes sense only for static actors. + + \param[in] actor The actor to apply impulse on. + \param[in] localGravity Gravity to apply in local actor's coordinates. ExtForceMode::VELOCITY is used. + + \return true iff force was applied on at least one node. + */ + virtual bool addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity) = 0; + + /** + Apply centrifugal force produced by actor's angular movement. + + \param[in] actor The actor to apply impulse on. + \param[in] localCenterMass Actor's local center of mass. + \param[in] localAngularVelocity Local angular velocity of an actor. + + \return true iff force was applied on at least one node. + */ + virtual bool addAngularVelocity(const NvBlastActor& actor, physx::PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity) = 0; + + /** + Update stress solver. + + Actual performance heavy stress calculation happens there. Call it after all relevant forces were applied, usually every frame. + */ + virtual void update() = 0; + + /** + Get overstressed/broken bonds count. + + This count is updated after every update() call. Number of overstressed bond directly hints if any bond fracture is recommended by stress solver. + + \return the overstressed bonds count. + */ + virtual uint32_t getOverstressedBondCount() const = 0; + + /** + Generate fracture commands for particular actor. + + Calling this function if getOverstressedBondCount() == 0 or actor has no bond doesn't make sense, bondFractureCount will be '0'. + Filled fracture commands buffer can be passed directly to NvBlastActorApplyFracture. + + IMPORTANT: NvBlastFractureBuffers::bondFractures will point to internal stress solver memory which will be valid till next call + of any of generateFractureCommands() functions or stress solver release() call. + + \param[in] actor The actor to fill fracture commands for. + \param[in] commands Pointer to command buffer to fill. + */ + virtual void generateFractureCommands(const NvBlastActor& actor, NvBlastFractureBuffers& commands) = 0; + + /** + Generate fracture commands for whole family. A bit faster way to get all fractured bonds then calling generateFractureCommands() for every actor. + + Calling this function if getOverstressedBondCount() == 0 or actor has no bond doesn't make sense, bondFractureCount will be '0'. + + IMPORTANT: NvBlastFractureBuffers::bondFractures will point to internal stress solver memory which will be valid till next call + of any of generateFractureCommands() functions or stress solver release() call. + + \param[in] commands Pointer to command buffer to fill. + */ + virtual void generateFractureCommands(NvBlastFractureBuffers& commands) = 0; + + /** + Generate fracture commands for every actor in family. + + Actors and commands buffer must be passed in order to be filled. It's recommended for bufferSize to be the count of actor with more then one bond in family. + + Calling this function if getOverstressedBondCount() == 0 or actor has no bond doesn't make sense, '0' will be returned. + + IMPORTANT: NvBlastFractureBuffers::bondFractures will point to internal stress solver memory which will be valid till next call + of any of generateFractureCommands() functions or stress solver release() call. + + \param[out] buffer A user-supplied array of NvBlastActor pointers to fill. + \param[out] commandsBuffer A user-supplied array of NvBlastFractureBuffers to fill. + \param[in] bufferSize The number of elements available to write into buffer. + + \return the number of actors and command buffers written to the buffer. + */ + virtual uint32_t generateFractureCommandsPerActor(const NvBlastActor** actorBuffer, NvBlastFractureBuffers* commandsBuffer, uint32_t bufferSize) = 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; + + /** + 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 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; + + + /** + 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 + }; + + /** + Used to store a single line and colour for debug rendering. + */ + struct DebugLine + { + DebugLine(const physx::PxVec3& p0, const physx::PxVec3& p1, const uint32_t& c) + : pos0(p0), color0(c), pos1(p1), color1(c) {} + + physx::PxVec3 pos0; + uint32_t color0; + physx::PxVec3 pos1; + uint32_t color1; + }; + + /** + Debug Buffer + */ + struct DebugBuffer + { + const DebugLine* lines; + uint32_t lineCount; + }; + + /** + Fill debug render for passed array of support graph nodes. + + NOTE: Returned DebugBuffer points into internal memory which is valid till next fillDebugRender() call. + + \param[in] nodes Node indices of support graph to debug render for. + \param[in] nodeCount Node indices count. + \param[in] mode Debug render mode. + \param[in] scale Scale to be applied on impulses. + + \return debug buffer with array of lines + */ + virtual const DebugBuffer fillDebugRender(const uint32_t* nodes, uint32_t nodeCount, DebugRenderMode mode, float scale = 1.0f) = 0; + + + //////// helpers //////// + + /** + Get solver iteration per frame (update() call) for particular settings and bondCount. + + Helper method to know how many solver iterations are made per frame. + This function made so transparent to make it clear how ExtStressSolverSettings::bondIterationsPerFrame is used. + + \param[in] settings Debug render mode. + \param[in] bondCount Scale to be applied on impulses. + + \return the iterations per frame count. + */ + static uint32_t getIterationsPerFrame(const ExtStressSolverSettings& settings, uint32_t bondCount) + { + uint32_t perFrame = settings.bondIterationsPerFrame / (bondCount + 1); + return perFrame > 0 ? perFrame : 1; + } + + /** + 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 + { + return getIterationsPerFrame(getSettings(), getBondCount()); + } + +}; + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTSTRESSSOLVER_H diff --git a/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.cpp b/sdk/extensions/stress/source/NvBlastExtStressSolver.cpp index 8329de5..335aacb 100644 --- a/sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.cpp +++ b/sdk/extensions/stress/source/NvBlastExtStressSolver.cpp @@ -1,39 +1,53 @@ -/* -* 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" +// 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 "NvBlastExtStressSolver.h" +#include "NvBlast.h" +#include "NvBlastGlobals.h" +#include "NvBlastArray.h" +#include "NvBlastHashMap.h" +#include "NvBlastHashSet.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 +#if GRAPH_INTERGRIRY_CHECK +#include <set> +#endif + namespace Nv { @@ -59,11 +73,6 @@ public: 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); @@ -83,33 +92,33 @@ public: m_bondsData.reserve(maxBondCount); } - NV_INLINE const NodeData& getNodeData(uint32_t node) const + const NodeData& getNodeData(uint32_t node) const { return m_nodesData[node]; } - NV_INLINE const BondData& getBondData(uint32_t bond) const + const BondData& getBondData(uint32_t bond) const { return m_bondsData[bond]; } - NV_INLINE uint32_t getBondCount() const + uint32_t getBondCount() const { return m_bondsData.size(); } - NV_INLINE uint32_t getNodeCount() const + uint32_t getNodeCount() const { return m_nodesData.size();; } - NV_INLINE void setNodeMassInfo(uint32_t node, float invMass, float invI) + void setNodeMassInfo(uint32_t node, float invMass, float invI) { m_nodesData[node].invMass = invMass; m_nodesData[node].invI = invI; } - NV_INLINE void initialize() + void initialize() { for (auto& node : m_nodesData) { @@ -118,13 +127,13 @@ public: } } - NV_INLINE void setNodeVelocities(uint32_t node, const PxVec3& velocityLinear, const PxVec3& velocityAngular) + 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) + uint32_t addBond(uint32_t node0, uint32_t node1, const PxVec3& offset) { const BondData data = { PxVec3(PxZero), @@ -138,23 +147,23 @@ public: return m_bondsData.size() - 1; } - NV_INLINE void replaceWithLast(uint32_t bondIndex) + void replaceWithLast(uint32_t bondIndex) { m_bondsData.replaceWithLast(bondIndex); } - NV_INLINE void reset(uint32_t nodeCount) + void reset(uint32_t nodeCount) { m_bondsData.clear(); m_nodesData.resize(nodeCount); } - NV_INLINE void clearBonds() + void clearBonds() { m_bondsData.clear(); } - void solve(uint32_t iterationCount, bool warmStart = false) + void solve(uint32_t iterationCount, bool warmStart = true) { solveInit(warmStart); @@ -218,7 +227,7 @@ private: } - NV_INLINE void iterate() + void iterate() { using namespace physx::shdfnd::aos; @@ -297,8 +306,8 @@ private: } } - shdfnd::Array<BondData, ExtAlignedAllocator<16>> m_bondsData; - shdfnd::Array<NodeData, ExtAlignedAllocator<16>> m_nodesData; + Array<BondData>::type m_bondsData; + Array<NodeData>::type m_nodesData; }; @@ -321,6 +330,7 @@ public: uint32_t node0; uint32_t node1; uint32_t blastBondIndex; + float stress; }; struct NodeData @@ -349,7 +359,7 @@ public: struct SolverBondData { - ExtInlineArray<uint32_t, 8>::type blastBondIndices; + InlineArray<uint32_t, 8>::type blastBondIndices; }; SupportGraphProcessor(uint32_t nodeCount, uint32_t maxBondCount) : m_solver(nodeCount, maxBondCount), m_nodesDirty(true) @@ -364,67 +374,85 @@ public: m_blastBondIndexMap.resize(maxBondCount); memset(m_blastBondIndexMap.begin(), 0xFF, m_blastBondIndexMap.size() * sizeof(uint32_t)); + + resetImpulses(); } - NV_INLINE const NodeData& getNodeData(uint32_t node) const + const NodeData& getNodeData(uint32_t node) const { return m_nodesData[node]; } - NV_INLINE const BondData& getBondData(uint32_t bond) const + const BondData& getBondData(uint32_t bond) const { return m_bondsData[bond]; } - NV_INLINE const SolverNodeData& getSolverNodeData(uint32_t node) const + const SolverNodeData& getSolverNodeData(uint32_t node) const { return m_solverNodesData[node]; } - NV_INLINE const SolverBondData& getSolverBondData(uint32_t bond) const + const SolverBondData& getSolverBondData(uint32_t bond) const { return m_solverBondsData[bond]; } - NV_INLINE const SequentialImpulseSolver::BondData& getSolverInternalBondData(uint32_t bond) const + const SequentialImpulseSolver::BondData& getSolverInternalBondData(uint32_t bond) const { return m_solver.getBondData(bond); } - NV_INLINE const SequentialImpulseSolver::NodeData& getSolverInternalNodeData(uint32_t node) const + const SequentialImpulseSolver::NodeData& getSolverInternalNodeData(uint32_t node) const { return m_solver.getNodeData(node); } - NV_INLINE uint32_t getBondCount() const + uint32_t getBondCount() const { return m_bondsData.size(); } - NV_INLINE uint32_t getNodeCount() const + uint32_t getNodeCount() const { return m_nodesData.size();; } - NV_INLINE uint32_t getSolverBondCount() const + uint32_t getSolverBondCount() const { return m_solverBondsData.size(); } - NV_INLINE uint32_t getSolverNodeCount() const + uint32_t getSolverNodeCount() const { return m_solverNodesData.size();; } - NV_INLINE void setNodeInfo(uint32_t node, float mass, float volume, PxVec3 localPos, bool isStatic) + uint32_t getOverstressedBondCount() const + { + return m_overstressedBondCount; + } + + float getSolverBondStressHealth(uint32_t bond, const ExtStressSolverSettings& settings) const + { + const auto& solverBond = getSolverInternalBondData(bond); + const float impulse = solverBond.impulseLinear.magnitude() * settings.stressLinearFactor + solverBond.impulseAngular.magnitude() * settings.stressAngularFactor; + // We then divide uniformly across bonds, which is obviously rough estimate. + // Potentially we can add bond area there and norm across area sum + const auto& blastBondIndices = m_solverBondsData[bond].blastBondIndices; + return blastBondIndices.empty() ? 0.0f : impulse / (blastBondIndices.size() * settings.hardness); + } + + 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; + m_nodesDirty = true; } - NV_INLINE void setNodeNeighborsCount(uint32_t node, uint32_t neighborsCount) + 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; @@ -436,44 +464,38 @@ public: } } - NV_INLINE void initialize() + void addNodeForce(uint32_t node, const PxVec3& force, ExtForceMode::Enum mode) { - sync(); - - m_solver.initialize(); - - for (auto& node : m_nodesData) - { - node.impulse = PxVec3(PxZero); - } + const PxVec3 impuse = (mode == ExtForceMode::IMPULSE) ? force : force * m_nodesData[node].mass; + m_nodesData[node].impulse += impuse; } - NV_INLINE void addNodeImpulse(uint32_t node, const PxVec3& impulse) + void addNodeVelocity(uint32_t node, const PxVec3& velocity) { - m_nodesData[node].impulse += impulse; + addNodeForce(node, velocity, ExtForceMode::VELOCITY); } - NV_INLINE void addNodeVelocity(uint32_t node, const PxVec3& velocity) + void addNodeImpulse(uint32_t node, const PxVec3& impulse) { - PxVec3 impulse = velocity * m_nodesData[node].mass; - addNodeImpulse(node, impulse); + addNodeForce(node, impulse, ExtForceMode::IMPULSE); } - NV_INLINE void addBond(uint32_t node0, uint32_t node1, uint32_t blastBondIndex) + void addBond(uint32_t node0, uint32_t node1, uint32_t blastBondIndex) { if (isInvalidIndex(m_blastBondIndexMap[blastBondIndex])) { const BondData data = { node0, node1, - blastBondIndex + blastBondIndex, + 0.0f }; m_bondsData.pushBack(data); m_blastBondIndexMap[blastBondIndex] = m_bondsData.size() - 1; } } - NV_INLINE void removeBondIfExists(uint32_t blastBondIndex) + void removeBondIfExists(uint32_t blastBondIndex) { const uint32_t bondIndex = m_blastBondIndexMap[blastBondIndex]; @@ -528,7 +550,7 @@ public: } } - NV_INLINE void setGraphReductionLevel(uint32_t level) + void setGraphReductionLevel(uint32_t level) { m_graphReductionLevel = level; m_nodesDirty = true; @@ -539,9 +561,11 @@ public: return m_graphReductionLevel; } - void solve(uint32_t iterationCount, bool warmStart = false) + void solve(const ExtStressSolverSettings& settings, const float* bondHealth, bool warmStart = true) { - CHECK_GRAPH_INTEGRITY; + sync(); + + m_solver.initialize(); for (const NodeData& node : m_nodesData) { @@ -549,7 +573,12 @@ public: m_solver.setNodeVelocities(node.solverNode, solverNode.velocityLinear + node.impulse * solverNode.invMass, PxVec3(PxZero)); } + uint32_t iterationCount = ExtStressSolver::getIterationsPerFrame(settings, getSolverBondCount()); m_solver.solve(iterationCount, warmStart); + + resetImpulses(); + + updateBondStress(settings, bondHealth); } void calcError(float& linear, float& angular) @@ -557,40 +586,53 @@ public: m_solver.calcError(linear, angular); } - void generateFracture(ExtArray<NvBlastBondFractureData>::type& bondFractureBuffer, const ExtStressSolverSettings& settings, const float* blastBondHealths) + float getBondStress(uint32_t blastBondIndex) { - CHECK_GRAPH_INTEGRITY; + const uint32_t bondIndex = m_blastBondIndexMap[blastBondIndex]; + return isInvalidIndex(bondIndex) ? 0.0f : m_bondsData[bondIndex].stress; + } + +private: + + void resetImpulses() + { + for (auto& node : m_nodesData) + { + node.impulse = PxVec3(PxZero); + } + } + + void updateBondStress(const ExtStressSolverSettings& settings, const float* bondHealth) + { + m_overstressedBondCount = 0; 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 float stress = getSolverBondStressHealth(i, settings); + const auto& blastBondIndices = m_solverBondsData[i].blastBondIndices; + const float stressPerBond = blastBondIndices.size() > 0 ? stress / blastBondIndices.size() : 0.0f; + for (auto blastBondIndex : blastBondIndices) { - const auto& blastBondIndices = m_solverBondsData[i].blastBondIndices; - for (auto blastBondIndex : blastBondIndices) + const uint32_t bondIndex = m_blastBondIndexMap[blastBondIndex]; + if (!isInvalidIndex(bondIndex)) { - const uint32_t bondIndex = m_blastBondIndexMap[blastBondIndex]; - if (!isInvalidIndex(bondIndex)) - { - const BondData& bond = m_bondsData[bondIndex]; + BondData& bond = m_bondsData[bondIndex]; - NVBLAST_ASSERT(getNodeData(bond.node0).solverNode != getNodeData(bond.node1).solverNode); - NVBLAST_ASSERT(bond.blastBondIndex == blastBondIndex); + NVBLAST_ASSERT(getNodeData(bond.node0).solverNode != getNodeData(bond.node1).solverNode); + NVBLAST_ASSERT(bond.blastBondIndex == blastBondIndex); + + bond.stress = stressPerBond; - NvBlastBondFractureData data; - data.health = blastBondHealths[blastBondIndex]; - data.nodeIndex0 = bond.node0; - data.nodeIndex1 = bond.node1; - bondFractureBuffer.pushBack(data); + if (stress > bondHealth[blastBondIndex]) + { + m_overstressedBondCount++; } } } } } -private: - - NV_INLINE void sync() + void sync() { if (m_nodesDirty) { @@ -620,6 +662,10 @@ private: const uint32_t STATIC_NODES_COUNT_PENALTY = 2 << 2; // reducing graph by aggregating nodes level by level + // NOTE (@anovoselov): Recently, I found a flow in the algorithm below. In very rare situations aggregate (solver node) + // can contain more then one connected component. I didn't notice it to produce any visual artifacts and it's + // unlikely to influence stress solvement a lot. Possible solution is to merge *whole* solver nodes, that + // will raise complexity a bit (at least will add another loop on nodes for every reduction level. for (uint32_t k = 0; k < m_graphReductionLevel; k++) { const uint32_t maxAggregateSize = 1 << (k + 1); @@ -748,11 +794,14 @@ private: m_solver.clearBonds(); m_solverBondsMap.clear(); m_solverBondsData.clear(); - for (const BondData& bond : m_bondsData) + for (BondData& bond : m_bondsData) { const NodeData& node0 = m_nodesData[bond.node0]; const NodeData& node1 = m_nodesData[bond.node1]; + // reset stress, bond structure changed and internal bonds stress won't be updated during updateBondStress() + bond.stress = 0.0f; + if (node0.solverNode == node1.solverNode) continue; // skip (internal) @@ -852,106 +901,199 @@ private: }; SequentialImpulseSolver m_solver; - ExtArray<SolverNodeData>::type m_solverNodesData; - ExtArray<SolverBondData>::type m_solverBondsData; + Array<SolverNodeData>::type m_solverNodesData; + Array<SolverBondData>::type m_solverBondsData; - uint32_t m_graphReductionLevel; + uint32_t m_graphReductionLevel; bool m_nodesDirty; bool m_bondsDirty; - ExtHashMap<BondKey, uint32_t>::type m_solverBondsMap; - ExtArray<uint32_t>::type m_blastBondIndexMap; + uint32_t m_overstressedBondCount; + + HashMap<BondKey, uint32_t>::type m_solverBondsMap; + Array<uint32_t>::type m_blastBondIndexMap; - ExtArray<BondData>::type m_bondsData; - ExtArray<NodeData>::type m_nodesData; + Array<BondData>::type m_bondsData; + Array<NodeData>::type m_nodesData; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtImpulseStressSolver +// ExtStressSolver /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Creation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +struct ExtStressNodeCachedData +{ + physx::PxVec3 localPos; + bool isStatic; +}; -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) + +struct ExtStressBondCachedData +{ + uint32_t bondIndex; +}; + +/** +*/ +class ExtStressSolverImpl final : public ExtStressSolver { + NV_NOCOPY(ExtStressSolverImpl) - 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(); +public: + ExtStressSolverImpl(NvBlastFamily& family, ExtStressSolverSettings settings); + virtual void release() override; - 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) + //////// ExtStressSolverImpl interface //////// + + virtual void setAllNodesInfoFromLL(float density = 1.0f) override; + + virtual void setNodeInfo(uint32_t graphNode, float mass, float volume, PxVec3 localPos, bool isStatic) override; + + virtual void setSettings(const ExtStressSolverSettings& settings) override { - uint32_t node0 = i; - uint32_t chunkIndex0 = m_graph.chunkIndices[node0]; - const ExtPxChunk& chunk0 = chunks[chunkIndex0]; + m_settings = settings; + } - bool isChunkStatic = chunk0.isStatic; + virtual const ExtStressSolverSettings& getSettings() const override + { + return m_settings; + } - 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]; + virtual bool addForce(const NvBlastActor& actor, physx::PxVec3 localPosition, physx::PxVec3 localForce, ExtForceMode::Enum mode) override; - if (chunk1.subchunkCount == 0 || chunk1.isStatic) - { - isChunkStatic |= chunk1.isStatic; - continue; - } - } + virtual void addForce(uint32_t graphNode, physx::PxVec3 localForce, ExtForceMode::Enum mode) override; - // fill node info + virtual bool addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity) override; + virtual bool addAngularVelocity(const NvBlastActor& actor, PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity) override; - 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); + virtual void update() override; + + virtual uint32_t getOverstressedBondCount() const override + { + return m_graphProcessor->getOverstressedBondCount(); + } + + virtual void generateFractureCommands(const NvBlastActor& actor, NvBlastFractureBuffers& commands) override; + virtual void generateFractureCommands(NvBlastFractureBuffers& commands) override; + virtual uint32_t generateFractureCommandsPerActor(const NvBlastActor** actorBuffer, NvBlastFractureBuffers* commandsBuffer, uint32_t bufferSize) 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 getFrameCount() const override + { + return m_framesCount; + } + + virtual uint32_t getBondCount() const override + { + return m_graphProcessor->getSolverBondCount(); + } + + virtual bool notifyActorCreated(const NvBlastActor& actor) override; + + virtual void notifyActorDestroyed(const NvBlastActor& actor) override; + + virtual const DebugBuffer fillDebugRender(const uint32_t* nodes, uint32_t nodeCount, DebugRenderMode mode, float scale) override; + + +private: + ~ExtStressSolverImpl(); + + + //////// private methods //////// + + void solve(); + + void fillFractureCommands(const NvBlastActor& actor, NvBlastFractureBuffers& commands); + + void initialize(); + + void iterate(); + + void syncSolver(); + + template<class T> + T* getScratchArray(uint32_t size); + + + //////// data //////// + + struct ImpulseData + { + physx::PxVec3 position; + physx::PxVec3 impulse; + }; + + NvBlastFamily& m_family; + HashSet<const NvBlastActor*>::type m_activeActors; + 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; + Array<NvBlastBondFractureData>::type m_bondFractureBuffer; + Array<uint8_t>::type m_scratch; + Array<DebugLine>::type m_debugLineBuffer; +}; + + +template<class T> +NV_INLINE T* ExtStressSolverImpl::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()); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Creation +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ExtStressSolverImpl::ExtStressSolverImpl(NvBlastFamily& 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 NvBlastAsset* asset = NvBlastFamilyGetAsset(&m_family, logLL); + NVBLAST_ASSERT(asset); + + m_graph = NvBlastAssetGetSupportGraph(asset, logLL); + const uint32_t bondCount = NvBlastAssetGetBondCount(asset, logLL); + + m_bondFractureBuffer.reserve(bondCount); + + { + NvBlastActor* actor; + NvBlastFamilyGetActors(&actor, 1, &family, logLL); + m_bondHealths = NvBlastActorGetBondHealths(actor, logLL); + } + + m_graphProcessor = NVBLAST_NEW(SupportGraphProcessor)(m_graph.nodeCount, bondCount); + // traverse graph and fill bond info for (uint32_t node0 = 0; node0 < m_graph.nodeCount; ++node0) { @@ -968,69 +1110,110 @@ ExtImpulseStressSolver::ExtImpulseStressSolver(ExtPxFamily& family, ExtStressSol } } } - - // 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() +ExtStressSolverImpl::~ExtStressSolverImpl() { - NVBLASTEXT_DELETE(m_graphProcessor, SupportGraphProcessor); - m_family.unsubscribe(*this); + NVBLAST_DELETE(m_graphProcessor, SupportGraphProcessor); } -ExtStressSolver* ExtStressSolver::create(ExtPxFamily& family, ExtStressSolverSettings settings) +ExtStressSolver* ExtStressSolver::create(NvBlastFamily& family, ExtStressSolverSettings settings) { - return NVBLASTEXT_NEW(ExtImpulseStressSolver) (family, settings); + return NVBLAST_NEW(ExtStressSolverImpl) (family, settings); } -void ExtImpulseStressSolver::release() +void ExtStressSolverImpl::release() { - NVBLASTEXT_DELETE(this, ExtImpulseStressSolver); + NVBLAST_DELETE(this, ExtStressSolverImpl); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Actors +// Actors & Graph Data /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void ExtImpulseStressSolver::onActorCreated(ExtPxFamily& /*family*/, ExtPxActor& actor) +void ExtStressSolverImpl::setAllNodesInfoFromLL(float density) +{ + const NvBlastAsset* asset = NvBlastFamilyGetAsset(&m_family, logLL); + NVBLAST_ASSERT(asset); + + const uint32_t chunkCount = NvBlastAssetGetChunkCount(asset, logLL); + const NvBlastChunk* chunks = NvBlastAssetGetChunks(asset, logLL); + + // traverse graph and fill node info + for (uint32_t node0 = 0; node0 < m_graph.nodeCount; ++node0) + { + const uint32_t chunkIndex0 = m_graph.chunkIndices[node0]; + if (chunkIndex0 >= chunkCount) + { + // chunkIndex is invalid means it is static node (represents world) + m_graphProcessor->setNodeInfo(node0, 0.0f, 0.0f, PxVec3(), true); + } + else + { + // Check if node is static. There is at maximum only one static node in LL that represents world, but we consider all nodes + // connected to it directly to be static too. It's better for general stress solver quality to have more then 1 static node. + bool isNodeConnectedToStatic = false; + 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]; + if (chunkIndex1 >= chunkCount) + { + isNodeConnectedToStatic = true; + break; + } + } + + // fill node info + const NvBlastChunk& chunk = chunks[chunkIndex0]; + const float volume = chunk.volume; + const float mass = volume * density; + const PxVec3 localPos = *reinterpret_cast<const PxVec3*>(chunk.centroid); + m_graphProcessor->setNodeInfo(node0, mass, volume, localPos, isNodeConnectedToStatic); + } + } +} + +void ExtStressSolverImpl::setNodeInfo(uint32_t graphNode, float mass, float volume, PxVec3 localPos, bool isStatic) { - if (actor.getTkActor().getGraphNodeCount() > 1) + m_graphProcessor->setNodeInfo(graphNode, mass, volume, localPos, isStatic); +} + +bool ExtStressSolverImpl::notifyActorCreated(const NvBlastActor& actor) +{ + const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL); + if (graphNodeCount > 1) { // update neighbors { - const uint32_t graphNodeCount = actor.getTkActor().getGraphNodeCount(); uint32_t* graphNodeIndices = getScratchArray<uint32_t>(graphNodeCount); - actor.getTkActor().getGraphNodeIndices(graphNodeIndices, graphNodeCount); + NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeCount, &actor, logLL); for (uint32_t i = 0; i < graphNodeCount; ++i) { m_graphProcessor->setNodeNeighborsCount(graphNodeIndices[i], graphNodeCount); } } - m_actors.insert(&actor); + m_activeActors.insert(&actor); m_isDirty = true; + return true; } + return false; } -void ExtImpulseStressSolver::onActorDestroyed(ExtPxFamily& /*family*/, ExtPxActor& actor) +void ExtStressSolverImpl::notifyActorDestroyed(const NvBlastActor& actor) { - if (m_actors.erase(&actor)) + if (m_activeActors.erase(&actor)) { m_isDirty = true; } } -void ExtImpulseStressSolver::syncSolver() +void ExtStressSolverImpl::syncSolver() { // traverse graph and remove dead bonds for (uint32_t node0 = 0; node0 < m_graph.nodeCount; ++node0) @@ -1053,8 +1236,7 @@ void ExtImpulseStressSolver::syncSolver() m_isDirty = false; } - -void ExtImpulseStressSolver::initialize() +void ExtStressSolverImpl::initialize() { if (m_reset) { @@ -1070,86 +1252,82 @@ void ExtImpulseStressSolver::initialize() { m_graphProcessor->setGraphReductionLevel(m_settings.graphReductionLevel); } +} - m_graphProcessor->initialize(); +bool ExtStressSolverImpl::addForce(const NvBlastActor& actor, physx::PxVec3 localPosition, physx::PxVec3 localForce, ExtForceMode::Enum mode) +{ + float bestDist = FLT_MAX; + uint32_t bestNode = invalidIndex<uint32_t>(); - for (auto it = m_actors.getIterator(); !it.done(); ++it) + const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL); + if (graphNodeCount > 1) { - 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); + NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeCount, &actor, logLL); - for (uint32_t i = 0; i < graphNodeCount; ++i) - { - const uint32_t node = graphNodeIndices[i]; - m_graphProcessor->addNodeVelocity(node, gravity); - } - } - else + for (uint32_t i = 0; i < graphNodeCount; ++i) { - 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 float sqrDist = (localPosition - m_graphProcessor->getNodeData(node).localPos).magnitudeSquared(); + if (sqrDist < bestDist) { - 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); + bestDist = sqrDist; + bestNode = node; } } - const auto entry = m_impulseBuffer.find(actor); - if (entry) + if (!isInvalidIndex(bestNode)) { - 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(); + m_graphProcessor->addNodeForce(bestNode, localForce, mode); + return true; } } + return false; +} + +void ExtStressSolverImpl::addForce(uint32_t graphNode, physx::PxVec3 localForce, ExtForceMode::Enum mode) +{ + m_graphProcessor->addNodeForce(graphNode, localForce, mode); } -void ExtImpulseStressSolver::applyImpulse(ExtPxActor& actor, physx::PxVec3 position, physx::PxVec3 force) +bool ExtStressSolverImpl::addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity) { - ImpulseData data = { position, force }; + const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL); + if (graphNodeCount > 1) + { + uint32_t* graphNodeIndices = getScratchArray<uint32_t>(graphNodeCount); + NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeCount, &actor, logLL); - m_impulseBuffer[&actor].pushBack(data); + for (uint32_t i = 0; i < graphNodeCount; ++i) + { + const uint32_t node = graphNodeIndices[i]; + m_graphProcessor->addNodeVelocity(node, localGravity); + } + return true; + } + return false; } -uint32_t ExtImpulseStressSolver::getBondCount() const +bool ExtStressSolverImpl::addAngularVelocity(const NvBlastActor& actor, PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity) { - return m_graphProcessor->getSolverBondCount(); + const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL); + if (graphNodeCount > 1) + { + uint32_t* graphNodeIndices = getScratchArray<uint32_t>(graphNodeCount); + NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeCount, &actor, logLL); + + // 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 = localAngularVelocity.cross(localAngularVelocity.cross(localPos - localCenterMass)); + m_graphProcessor->addNodeVelocity(node, centrifugalAcceleration); + } + return true; + } + return false; } @@ -1157,26 +1335,20 @@ uint32_t ExtImpulseStressSolver::getBondCount() const // Update /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void ExtImpulseStressSolver::update(bool doDamage) +void ExtStressSolverImpl::update() { initialize(); solve(); - if (doDamage) - { - applyDamage(); - } - m_framesCount++; } -void ExtImpulseStressSolver::solve() +void ExtStressSolverImpl::solve() { PX_SIMD_GUARD; - const uint32_t iterations = getIterationsPerFrame(); - m_graphProcessor->solve(iterations, WARM_START && !m_reset); + m_graphProcessor->solve(m_settings, m_bondHealths, WARM_START && !m_reset); m_reset = false; m_graphProcessor->calcError(m_errorLinear, m_errorAngular); @@ -1187,25 +1359,103 @@ void ExtImpulseStressSolver::solve() // Damage /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void ExtImpulseStressSolver::applyDamage() +void ExtStressSolverImpl::fillFractureCommands(const NvBlastActor& actor, NvBlastFractureBuffers& commands) { - m_bondFractureBuffer.clear(); - m_graphProcessor->generateFracture(m_bondFractureBuffer, m_settings, m_bondHealths); + const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL); + uint32_t commandCount = 0; - if (m_bondFractureBuffer.size() > 0) + if (graphNodeCount > 1 && m_graphProcessor->getOverstressedBondCount() > 0) { - NvBlastFractureBuffers fractureCommands; - fractureCommands.chunkFractureCount = 0; - fractureCommands.bondFractureCount = m_bondFractureBuffer.size(); - fractureCommands.bondFractures = m_bondFractureBuffer.begin(); + uint32_t* graphNodeIndices = getScratchArray<uint32_t>(graphNodeCount); + NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeCount, &actor, logLL); + + for (uint32_t i = 0; i < graphNodeCount; ++i) + { + const uint32_t node0 = graphNodeIndices[i]; + 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]; + const float bondHealth = m_bondHealths[bondIndex]; + const float bondStress = m_graphProcessor->getBondStress(bondIndex); - m_family.getTkFamily().applyFracture(&fractureCommands); + if (bondHealth > 0.0f && bondStress > bondHealth) + { + const NvBlastBondFractureData data = { + 0, + node0, + node1, + bondHealth + }; + m_bondFractureBuffer.pushBack(data); + commandCount++; + } + } + } + } + } + + commands.chunkFractureCount = 0; + commands.chunkFractures = nullptr; + commands.bondFractureCount = commandCount; + commands.bondFractures = commandCount > 0 ? m_bondFractureBuffer.end() - commandCount : nullptr; +} + +void ExtStressSolverImpl::generateFractureCommands(const NvBlastActor& actor, NvBlastFractureBuffers& commands) +{ + m_bondFractureBuffer.clear(); + fillFractureCommands(actor, commands); +} + +void ExtStressSolverImpl::generateFractureCommands(NvBlastFractureBuffers& commands) +{ + m_bondFractureBuffer.clear(); + + const uint32_t bondCount = m_graphProcessor->getBondCount(); + const uint32_t overstressedBondCount = m_graphProcessor->getOverstressedBondCount(); + for (uint32_t i = 0; i < bondCount && m_bondFractureBuffer.size() < overstressedBondCount; i++) + { + const auto& bondData = m_graphProcessor->getBondData(i); + const float bondHealth = m_bondHealths[bondData.blastBondIndex]; + if (bondHealth > 0.0f && bondData.stress > bondHealth) + { + const NvBlastBondFractureData data = { + 0, + bondData.node0, + bondData.node1, + bondHealth + }; + m_bondFractureBuffer.pushBack(data); + } } + + commands.chunkFractureCount = 0; + commands.chunkFractures = nullptr; + commands.bondFractureCount = m_bondFractureBuffer.size(); + commands.bondFractures = m_bondFractureBuffer.size() > 0 ? m_bondFractureBuffer.begin() : nullptr; } -uint32_t ExtImpulseStressSolver::getIterationCount() const +uint32_t ExtStressSolverImpl::generateFractureCommandsPerActor(const NvBlastActor** actorBuffer, NvBlastFractureBuffers* commandsBuffer, uint32_t bufferSize) { - return getFrameCount() * getIterationsPerFrame(); + if (m_graphProcessor->getOverstressedBondCount() == 0) + return 0; + + m_bondFractureBuffer.clear(); + uint32_t index = 0; + for (auto it = m_activeActors.getIterator(); !it.done() && index < bufferSize; ++it) + { + const NvBlastActor* actor = *it; + NvBlastFractureBuffers& nextCommand = commandsBuffer[index]; + fillFractureCommands(*actor, nextCommand); + if (nextCommand.bondFractureCount > 0) + { + actorBuffer[index] = actor; + index++; + } + } + return index; } @@ -1230,7 +1480,7 @@ static PxVec4 PxVec4Lerp(const PxVec4 v0, const PxVec4 v1, float val) v0.y * (1 - val) + v1.y * val, v0.z * (1 - val) + v1.z * val, v0.w * (1 - val) + v1.w * val - ); + ); return v; } @@ -1250,21 +1500,26 @@ inline PxVec4 bondHealthColor(float healthFraction) 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 ExtStressSolver::DebugBuffer ExtStressSolverImpl::fillDebugRender(const uint32_t* nodes, uint32_t nodeCount, 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); + ExtStressSolver::DebugBuffer debugBuffer = { nullptr, 0 }; + if (m_isDirty) - return; + return debugBuffer; - ExtArray<uint8_t>::type& nodesSet = m_scratch; + m_debugLineBuffer.clear(); + + Array<uint8_t>::type& nodesSet = m_scratch; nodesSet.resize(m_graphProcessor->getSolverNodeCount()); memset(nodesSet.begin(), 0, nodesSet.size() * sizeof(uint8_t)); - for (auto& nodeIndex : nodes) + for (uint32_t i = 0; i < nodeCount; ++i) { - nodesSet[m_graphProcessor->getNodeData(nodeIndex).solverNode] = 1; + NVBLAST_ASSERT(m_graphProcessor->getNodeData(nodes[i]).solverNode < nodesSet.size()); + nodesSet[m_graphProcessor->getNodeData(nodes[i]).solverNode] = 1; } const uint32_t bondCount = m_graphProcessor->getSolverBondCount(); @@ -1273,8 +1528,7 @@ void ExtImpulseStressSolver::fillDebugRender(const std::vector<uint32_t>& nodes, const auto& solverInternalBondData = m_graphProcessor->getSolverInternalBondData(i); if (nodesSet[solverInternalBondData.node0] != 0) { - NVBLAST_ASSERT(nodesSet[solverInternalBondData.node1] != 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); @@ -1284,27 +1538,32 @@ void ExtImpulseStressSolver::fillDebugRender(const std::vector<uint32_t>& nodes, PxVec3 p1 = solverNode1.localPos; PxVec3 center = (p0 + p1) * 0.5f; - const float stress = std::min<float>(solverInternalBondData.getStressHealth(m_settings), 1.0f); + const float stress = std::min<float>(m_graphProcessor->getSolverBondStressHealth(i, m_settings), 1.0f); PxVec4 color = bondHealthColor(1.0f - stress); - lines.push_back(PxDebugLine(p0, p1, PxVec4ToU32Color(color))); + m_debugLineBuffer.pushBack(DebugLine(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))); + m_debugLineBuffer.pushBack(DebugLine(p0, p0 + solverInternalNode0.velocityLinear * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR))); + m_debugLineBuffer.pushBack(DebugLine(p0, p0 + solverInternalNode0.velocityAngular * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR))); + m_debugLineBuffer.pushBack(DebugLine(p1, p1 + solverInternalNode1.velocityLinear * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR))); + m_debugLineBuffer.pushBack(DebugLine(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))); + m_debugLineBuffer.pushBack(DebugLine(center, center + solverInternalBondData.impulseLinear * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR))); + m_debugLineBuffer.pushBack(DebugLine(center, center + solverInternalBondData.impulseAngular * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR))); } } } + + debugBuffer.lines = m_debugLineBuffer.begin(); + debugBuffer.lineCount = m_debugLineBuffer.size(); + + return debugBuffer; } diff --git a/sdk/globals/include/NvBlastAllocator.h b/sdk/globals/include/NvBlastAllocator.h new file mode 100644 index 0000000..72d2199 --- /dev/null +++ b/sdk/globals/include/NvBlastAllocator.h @@ -0,0 +1,69 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTALLOCATOR_H +#define NVBLASTALLOCATOR_H + +#include "NvBlastGlobals.h" + +/** +This file contains AllocatorCallback wrappers compatible with PxShared containers. +*/ + +namespace Nv +{ +namespace Blast +{ + +/** +Allocator uses global AllocatorCallback. +*/ +class Allocator +{ +public: + Allocator(const char* = 0) + { + } + + void* allocate(size_t size, const char* filename, int line) + { + return NvBlastGlobalGetAllocatorCallback()->allocate(size, nullptr, filename, line); + } + + void deallocate(void* ptr) + { + NvBlastGlobalGetAllocatorCallback()->deallocate(ptr); + } +}; + + +} // namespace Blast +} // namespace Nv + + +#endif // #ifndef NVBLASTALLOCATOR_H diff --git a/sdk/globals/include/NvBlastGlobals.h b/sdk/globals/include/NvBlastGlobals.h new file mode 100644 index 0000000..0325538 --- /dev/null +++ b/sdk/globals/include/NvBlastGlobals.h @@ -0,0 +1,277 @@ +// 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 NVBLASTGLOBALS_H +#define NVBLASTGLOBALS_H + +#include <new> +#include "NvBlastTypes.h" + + +namespace Nv +{ +namespace Blast +{ + + +/** +\brief Abstract base class for an application defined memory allocator that can be used by toolkit (Tk) or any extension (Ext). +*/ +class AllocatorCallback +{ +public: + /** + \brief destructor + */ + virtual ~AllocatorCallback() + { + } + + /** + \brief Allocates size bytes of memory, which must be 16-byte aligned. + + This method should never return NULL. If you run out of memory, then + you should terminate the app or take some other appropriate action. + + \param size Number of bytes to allocate. + \param typeName Name of the datatype that is being allocated + \param filename The source file which allocated the memory + \param line The source line which allocated the memory + \return The allocated block of memory. + */ + virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) = 0; + + /** + \brief Frees memory previously allocated by allocate(). + + \param ptr Memory to free. + */ + virtual void deallocate(void* ptr) = 0; +}; + + +/** +\brief Error codes + +These error codes are passed to #ErrorCallback + +\note: It's actually the copy of PxErrorCallback's PxErrorCode so it can be easily casted to it. Keep that +in mind if you are going to change this enum. + +@see ErrorCallback +*/ +struct ErrorCode +{ + enum Enum + { + eNO_ERROR = 0, + + //! \brief An informational message. + eDEBUG_INFO = 1, + + //! \brief a warning message for the user to help with debugging + eDEBUG_WARNING = 2, + + //! \brief method called with invalid parameter(s) + eINVALID_PARAMETER = 4, + + //! \brief method was called at a time when an operation is not possible + eINVALID_OPERATION = 8, + + //! \brief method failed to allocate some memory + eOUT_OF_MEMORY = 16, + + /** \brief The library failed for some reason. + Possibly you have passed invalid values like NaNs, which are not checked for. + */ + eINTERNAL_ERROR = 32, + + //! \brief An unrecoverable error, execution should be halted and log output flushed + eABORT = 64, + + //! \brief The SDK has determined that an operation may result in poor performance. + ePERF_WARNING = 128, + + //! \brief A bit mask for including all errors + eMASK_ALL = -1 + }; +}; + + +/** +\brief User defined interface class. Used by the library to emit debug information. + +\note The SDK state should not be modified from within any error reporting functions. +*/ +class ErrorCallback +{ +public: + virtual ~ErrorCallback() + { + } + + /** + \brief Reports an error code. + \param code Error code, see #ErrorCode + \param message Message to display. + \param file File error occured in. + \param line Line number error occured on. + */ + virtual void reportError(ErrorCode::Enum code, const char* message, const char* file, int line) = 0; +}; + + +} // namespace Blast +} // namespace Nv + + +//////// Global API to Access Global AllocatorCallback and ErrorCallback //////// + +/** +Retrieve a pointer to the global AllocatorCallback. Default implementation with std allocator is used if user didn't provide +it's own. It always exist, 'nullptr' will never be returned. + +\return the pointer to the global AllocatorCallback. +*/ +NVBLAST_API Nv::Blast::AllocatorCallback* NvBlastGlobalGetAllocatorCallback(); + +/** +Set global AllocatorCallback. If 'nullptr' is passed the default AllocatorCallback with std allocator is set. +*/ +NVBLAST_API void NvBlastGlobalSetAllocatorCallback(Nv::Blast::AllocatorCallback* allocatorCallback); + +/** +Retrieve a pointer to the global ErrorCallback. Default implementation which writes messages to stdout is used if user didn't provide +it's own. It always exist, 'nullptr' will never be returned. + +\return the pointer to the global ErrorCallback. +*/ +NVBLAST_API Nv::Blast::ErrorCallback* NvBlastGlobalGetErrorCallback(); + +/** +Set global ErrorCallback. If 'nullptr' is passed the default ErrorCallback that writes messages to stdout is set. +*/ +NVBLAST_API void NvBlastGlobalSetErrorCallback(Nv::Blast::ErrorCallback* errorCallback); + + +//////// Helper Global Functions //////// + +namespace Nv +{ +namespace Blast +{ + + +/** +Logging wrapper compatible with NvBlastLog. @see NvBlastLog. + +Pass this function to LowLevel function calls in order to get logging into global ErrorCallback. +*/ +NV_INLINE void logLL(int type, const char* msg, const char* file, int line) +{ + ErrorCode::Enum errorCode = ErrorCode::eNO_ERROR; + switch (type) + { + case NvBlastMessage::Error: errorCode = ErrorCode::eINVALID_OPERATION; break; + case NvBlastMessage::Warning: errorCode = ErrorCode::eDEBUG_WARNING; break; + case NvBlastMessage::Info: errorCode = ErrorCode::eDEBUG_INFO; break; + case NvBlastMessage::Debug: errorCode = ErrorCode::eNO_ERROR; break; + } + + NvBlastGlobalGetErrorCallback()->reportError(errorCode, msg, file, line); +} + + +} // namespace Blast +} // namespace Nv + + + +//////// Allocator macros //////// + +/** +Alloc/Free macros that use global AllocatorCallback. Thus allocated memory is 16-byte aligned. +*/ +#define NVBLAST_ALLOC(_size) NvBlastGlobalGetAllocatorCallback()->allocate(_size, nullptr, __FILE__, __LINE__) +#define NVBLAST_ALLOC_NAMED(_size, _name) NvBlastGlobalGetAllocatorCallback()->allocate(_size, _name, __FILE__, __LINE__) +#define NVBLAST_FREE(_mem) NvBlastGlobalGetAllocatorCallback()->deallocate(_mem) + +/** +Placement new with ExtContext allocation. +Example: Foo* foo = NVBLAST_NEW(Foo, context) (params); +*/ +#define NVBLAST_NEW(T) new (NvBlastGlobalGetAllocatorCallback()->allocate(sizeof(T), #T, __FILE__, __LINE__)) T + +/** +Respective delete to NVBLAST_NEW +Example: NVBLAST_DELETE(foo, Foo, context); +*/ +#define NVBLAST_DELETE(obj, T) \ + (obj)->~T(); \ + NvBlastGlobalGetAllocatorCallback()->deallocate(obj) + + + +//////// Log macros //////// + +/** +Logging macros that use global AllocatorCallback. +*/ +#define NVBLAST_LOG(_code, _msg) NvBlastGlobalGetErrorCallback()->reportError(_code, _msg, __FILE__, __LINE__) +#define NVBLAST_LOG_ERROR(_msg) NVBLAST_LOG(Nv::Blast::ErrorCode::eINVALID_OPERATION, _msg) +#define NVBLAST_LOG_WARNING(_msg) NVBLAST_LOG(Nv::Blast::ErrorCode::eDEBUG_WARNING, _msg) +#define NVBLAST_LOG_INFO(_msg) NVBLAST_LOG(Nv::Blast::ErrorCode::eDEBUG_INFO, _msg) +#define NVBLAST_LOG_DEBUG(_msg) NVBLAST_LOG(Nv::Blast::ErrorCode::eNO_ERROR, _msg) + +/** +Check macros that use global AllocatorCallback. The idea is that you pass an expression to check, if it fails +it logs and calls '_onFail' code you passed. +*/ +#define NVBLAST_CHECK(_code, _expr, _msg, _onFail) \ + { \ + if(!(_expr)) \ + { \ + NVBLAST_LOG(_code, _msg); \ + { _onFail; }; \ + } \ + } + +#define NVBLAST_CHECK_ERROR(_expr, _msg, _onFail) NVBLAST_CHECK(Nv::Blast::ErrorCode::eINVALID_OPERATION, _expr, _msg, _onFail) +#define NVBLAST_CHECK_WARNING(_expr, _msg, _onFail) NVBLAST_CHECK(Nv::Blast::ErrorCode::eDEBUG_WARNING, _expr, _msg, _onFail) +#define NVBLAST_CHECK_INFO(_expr, _msg, _onFail) NVBLAST_CHECK(Nv::Blast::ErrorCode::eDEBUG_INFO, _expr, _msg, _onFail) +#define NVBLAST_CHECK_DEBUG(_expr, _msg, _onFail) NVBLAST_CHECK(Nv::Blast::ErrorCode::eNO_ERROR, _expr, _msg, _onFail) + + +//////// Misc //////// + + +// Macro to load a uint32_t (or larger) with four characters +#define NVBLAST_FOURCC(_a, _b, _c, _d) ( (uint32_t)(_a) | (uint32_t)(_b)<<8 | (uint32_t)(_c)<<16 | (uint32_t)(_d)<<24 ) + + +#endif // ifndef NVBLASTGLOBALS_H diff --git a/sdk/globals/include/NvBlastProfiler.h b/sdk/globals/include/NvBlastProfiler.h new file mode 100644 index 0000000..7ca3277 --- /dev/null +++ b/sdk/globals/include/NvBlastProfiler.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 NVBLASTPROFILER_H +#define NVBLASTPROFILER_H + +#include "NvBlastPreprocessor.h" + + +namespace Nv +{ +namespace Blast +{ + + +/** +Custom Blast profiler interface. +*/ +class ProfilerCallback +{ +protected: + virtual ~ProfilerCallback() {} + +public: + /** + Called when a nested profile zone starts. + */ + virtual void zoneStart(const char* name) = 0; + + /** + Called when the current profile zone ends. + */ + virtual void zoneEnd() = 0; +}; + + +/** +Profiler detail to be reported. The higher setting is used, the more details are reported. +*/ +struct ProfilerDetail +{ + enum Level + { + LOW, + MEDIUM, + HIGH + }; +}; + + +} // namespace Blast +} // namespace Nv + + +/** +Profiler features are only active in checked, debug and profile builds. +*/ + +/** +Set a custom profiler callback. May be nullptr (the default). +*/ +NVBLAST_API void NvBlastProfilerSetCallback(Nv::Blast::ProfilerCallback* pcb); + + +/** +Sets the depth of reported profile zones. +Higher levels (more nesting) of instrumentation can have a significant impact. +Defaults to Nv::Blast::ProfilerDetail::Level::LOW. +*/ +NVBLAST_API void NvBlastProfilerSetDetail(Nv::Blast::ProfilerDetail::Level); + + +#endif diff --git a/sdk/globals/source/NvBlastGlobals.cpp b/sdk/globals/source/NvBlastGlobals.cpp new file mode 100644 index 0000000..e56d43b --- /dev/null +++ b/sdk/globals/source/NvBlastGlobals.cpp @@ -0,0 +1,190 @@ +// 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 "NvBlastAssert.h" +#include <cstdlib> +#include <sstream> +#include <iostream> + +#if NV_WINDOWS_FAMILY +#include <windows.h> +#endif + +#if NV_WINDOWS_FAMILY || NV_LINUX_FAMILY +#include <malloc.h> +#endif + + +namespace Nv +{ +namespace Blast +{ + +#if NV_WINDOWS_FAMILY +// on win32 we only have 8-byte alignment guaranteed, but the CRT provides special aligned allocation fns +NV_FORCE_INLINE void* platformAlignedAlloc(size_t size) +{ + return _aligned_malloc(size, 16); +} + +NV_FORCE_INLINE void platformAlignedFree(void* ptr) +{ + _aligned_free(ptr); +} +#elif NV_LINUX_FAMILY +NV_FORCE_INLINE void* platformAlignedAlloc(size_t size) +{ + return ::memalign(16, size); +} + +NV_FORCE_INLINE void platformAlignedFree(void* ptr) +{ + ::free(ptr); +} +#elif NV_XBOXONE || NV_PS4 +// on these platforms we get 16-byte alignment by default +NV_FORCE_INLINE void* platformAlignedAlloc(size_t size) +{ + return ::malloc(size); +} + +NV_FORCE_INLINE void platformAlignedFree(void* ptr) +{ + ::free(ptr); +} +#else +NV_FORCE_INLINE void* platformAlignedAlloc(size_t size) +{ + const int A = 16; + unsigned char* mem = (unsigned char*)malloc(size + A); + const unsigned char offset = (unsigned char)((uintptr_t)A - (uintptr_t)mem % A - 1); + mem += offset; + *mem++ = offset; + return mem; +} + +NV_FORCE_INLINE void platformAlignedFree(void* ptr) +{ + if (ptr != nullptr) + { + unsigned char* mem = (unsigned char*)ptr; + const unsigned char offset = *--mem; + ::free(mem - offset); + } +} +#endif + +class DefaultAllocatorCallback : public AllocatorCallback +{ +public: + virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) override + { + NV_UNUSED(typeName); + NV_UNUSED(filename); + NV_UNUSED(line); + return platformAlignedAlloc(size); + } + + virtual void deallocate(void* ptr) override + { + platformAlignedFree(ptr); + } +}; +DefaultAllocatorCallback g_defaultAllocatorCallback; + + +class DefaultErrorCallback : public ErrorCallback +{ + virtual void reportError(ErrorCode::Enum code, const char* msg, const char* file, int line) override + { +#if NV_DEBUG || NV_CHECKED + std::stringstream str; + str << "NvBlast "; + bool critical = false; + switch (code) + { + case ErrorCode::eNO_ERROR: str << "[Info]"; critical = false; break; + case ErrorCode::eDEBUG_INFO: str << "[Debug Info]"; critical = false; break; + case ErrorCode::eDEBUG_WARNING: str << "[Debug Warning]"; critical = false; break; + case ErrorCode::eINVALID_PARAMETER: str << "[Invalid Parameter]"; critical = true; break; + case ErrorCode::eINVALID_OPERATION: str << "[Invalid Operation]"; critical = true; break; + case ErrorCode::eOUT_OF_MEMORY: str << "[Out of] Memory"; critical = true; break; + case ErrorCode::eINTERNAL_ERROR: str << "[Internal Error]"; critical = true; break; + case ErrorCode::eABORT: str << "[Abort]"; critical = true; break; + case ErrorCode::ePERF_WARNING: str << "[Perf Warning]"; critical = false; break; + default: NVBLAST_ASSERT(false); + } + str << file << "(" << line << "): " << msg << "\n"; + + std::string message = str.str(); + std::cout << message; +#if NV_WINDOWS_FAMILY + OutputDebugStringA(message.c_str()); +#endif + NVBLAST_ASSERT_WITH_MESSAGE(!critical, message.c_str()); +#else + NV_UNUSED(code); + NV_UNUSED(msg); + NV_UNUSED(file); + NV_UNUSED(line); +#endif + } +}; +DefaultErrorCallback g_defaultErrorCallback; + + +AllocatorCallback* g_allocatorCallback = &g_defaultAllocatorCallback; +ErrorCallback* g_errorCallback = &g_defaultErrorCallback; + + +} // namespace Blast +} // namespace Nv + + +//////// Global API implementation //////// + +Nv::Blast::AllocatorCallback* NvBlastGlobalGetAllocatorCallback() +{ + return Nv::Blast::g_allocatorCallback; +} + +void NvBlastGlobalSetAllocatorCallback(Nv::Blast::AllocatorCallback* allocator) +{ + Nv::Blast::g_allocatorCallback = allocator ? allocator : &Nv::Blast::g_defaultAllocatorCallback; +} + +Nv::Blast::ErrorCallback* NvBlastGlobalGetErrorCallback() +{ + return Nv::Blast::g_errorCallback; +} + +void NvBlastGlobalSetErrorCallback(Nv::Blast::ErrorCallback* errorCallback) +{ + Nv::Blast::g_errorCallback = errorCallback ? errorCallback : &Nv::Blast::g_defaultErrorCallback; +} diff --git a/sdk/globals/source/NvBlastProfiler.cpp b/sdk/globals/source/NvBlastProfiler.cpp new file mode 100644 index 0000000..48d4b7b --- /dev/null +++ b/sdk/globals/source/NvBlastProfiler.cpp @@ -0,0 +1,96 @@ +// 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 "stdint.h" +#include "NvBlastProfilerInternal.h" + +#if NV_PROFILE || NV_CHECKED || NV_DEBUG + +namespace Nv +{ +namespace Blast +{ + +class EmptyProfilerCallback : public ProfilerCallback +{ + void zoneStart(const char*) {} + void zoneEnd() {} +}; +EmptyProfilerCallback g_EmptyCallback; + +ProfilerCallback* g_ProfilerCallback = &g_EmptyCallback; +ProfilerDetail::Level g_ProfilerDetail = ProfilerDetail::LOW; + +} // namespace Blast +} // namespace Nv + + +void NvBlastProfilerSetCallback(Nv::Blast::ProfilerCallback* pcb) +{ + Nv::Blast::g_ProfilerCallback = pcb != nullptr ? pcb : &Nv::Blast::g_EmptyCallback; +} + +Nv::Blast::ProfilerCallback* NvBlastProfilerGetCallback() +{ + return Nv::Blast::g_ProfilerCallback; +} + + +void NvBlastProfilerSetDetail(Nv::Blast::ProfilerDetail::Level level) +{ + Nv::Blast::g_ProfilerDetail = level; +} + +Nv::Blast::ProfilerDetail::Level NvBlastProfilerGetDetail() +{ + return Nv::Blast::g_ProfilerDetail; +} + + +void NvBlastProfilerBegin(const char* name, Nv::Blast::ProfilerDetail::Level level) +{ + if (level <= NvBlastProfilerGetDetail()) + { + NvBlastProfilerGetCallback()->zoneStart(name); + } +} + +void NvBlastProfilerEnd(const void* /*name*/, Nv::Blast::ProfilerDetail::Level level) +{ + if (level <= NvBlastProfilerGetDetail()) + { + NvBlastProfilerGetCallback()->zoneEnd(); + } +} + +#else + +void NvBlastProfilerSetCallback(Nv::Blast::ProfilerCallback*) {} +void NvBlastProfilerSetDetail(Nv::Blast::ProfilerDetail::Level) {} + +#endif // NV_PROFILE diff --git a/sdk/globals/source/NvBlastProfilerInternal.h b/sdk/globals/source/NvBlastProfilerInternal.h new file mode 100644 index 0000000..dd0cfbf --- /dev/null +++ b/sdk/globals/source/NvBlastProfilerInternal.h @@ -0,0 +1,91 @@ +// 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 NVBLASTPROFILERINTERNAL_H +#define NVBLASTPROFILERINTERNAL_H + +#include "NvBlastPreprocessor.h" +#include "NvBlastProfiler.h" + +#if NV_PROFILE || NV_CHECKED || NV_DEBUG + +NVBLAST_API void NvBlastProfilerBegin(const char* name, Nv::Blast::ProfilerDetail::Level); +NVBLAST_API void NvBlastProfilerEnd(const void* name, Nv::Blast::ProfilerDetail::Level); + +Nv::Blast::ProfilerCallback* NvBlastProfilerGetCallback(); +Nv::Blast::ProfilerDetail::Level NvBlastProfilerGetDetail(); + + +namespace Nv +{ +namespace Blast +{ + + +class ProfileScope +{ +public: + ProfileScope(const char* name, ProfilerDetail::Level level) :m_name(name), m_level(level) + { + NvBlastProfilerBegin(m_name, m_level); + } + + ~ProfileScope() + { + NvBlastProfilerEnd(m_name, m_level); + } + +private: + const char* m_name; + ProfilerDetail::Level m_level; +}; + + +} // namespace Blast +} // namespace Nv + + +#define BLAST_PROFILE_PREFIX "Blast: " +#define BLAST_PROFILE_ZONE_BEGIN(name) NvBlastProfilerBegin(BLAST_PROFILE_PREFIX name, Nv::Blast::ProfilerDetail::HIGH) +#define BLAST_PROFILE_ZONE_END(name) NvBlastProfilerEnd(BLAST_PROFILE_PREFIX name, Nv::Blast::ProfilerDetail::HIGH) +#define BLAST_PROFILE_SCOPE(name, detail) Nv::Blast::ProfileScope NV_CONCAT(_scope,__LINE__) (BLAST_PROFILE_PREFIX name, detail) +#define BLAST_PROFILE_SCOPE_L(name) BLAST_PROFILE_SCOPE(name, Nv::Blast::ProfilerDetail::LOW) +#define BLAST_PROFILE_SCOPE_M(name) BLAST_PROFILE_SCOPE(name, Nv::Blast::ProfilerDetail::MEDIUM) +#define BLAST_PROFILE_SCOPE_H(name) BLAST_PROFILE_SCOPE(name, Nv::Blast::ProfilerDetail::HIGH) + +#else + +#define BLAST_PROFILE_ZONE_BEGIN(name) +#define BLAST_PROFILE_ZONE_END(name) +#define BLAST_PROFILE_SCOPE_L(name) +#define BLAST_PROFILE_SCOPE_M(name) +#define BLAST_PROFILE_SCOPE_H(name) + +#endif + +#endif diff --git a/sdk/lowlevel/include/NvBlast.h b/sdk/lowlevel/include/NvBlast.h index d4c91a7..0a4872f 100644 --- a/sdk/lowlevel/include/NvBlast.h +++ b/sdk/lowlevel/include/NvBlast.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 NVBLAST_H #define NVBLAST_H @@ -155,6 +173,21 @@ NVBLAST_API uint32_t NvBlastAssetGetChunkCount(const NvBlastAsset* asset, NvBlas /** +Get the number of support chunks in the given asset. This will equal the number of +graph nodes in NvBlastSupportGraph::nodeCount returned by NvBlastAssetGetSupportGraph only +if no extra "world" node was created due to bonds defined between support chunks and the world. +If such bonds were created, then there is an extra graph node representing the world, and this +function will return NvBlastSupportGraph::nodeCount - 1. + +\param[in] asset The asset. +\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + +\return the number of chunks in the asset. +*/ +NVBLAST_API uint32_t NvBlastAssetGetSupportChunkCount(const NvBlastAsset* asset, NvBlastLog logFn); + + +/** Get the number of leaf chunks in the given asset. \param[in] asset The asset. @@ -280,8 +313,8 @@ Build chunk reorder map. NvBlastCreateAsset function requires NvBlastChunkDesc array to be in correct oder: 1. Root chunks (chunks with invalid parent index) must be first in the asset's chunk list. -2. Chunks in the asset should be arranged such that sibling chunks (chunks with the same parent) are contiguous. -3. Chunks are also should be arranged such that upper-support chunks (support chunks and their parent chunks) should go first in +2. Chunks in the asset must be arranged such that sibling chunks (chunks with the same parent) are contiguous. +3. Chunks must be arranged such that upper-support chunks (support chunks and their parent chunks) go first in chunk list. This function builds chunk reorder map which can be used to order chunk descs. Reordering chunk's descriptors @@ -308,13 +341,14 @@ with new indices. Bonds are kept in the same order, but their 'chunkIndices' fie @see NvBlastBuildAssetDescChunkReorderMap -\param[out] reorderedChunkDescs User-supplied array of size chunkCount to fill with new reordered NvBlastChunkDesc's. -\param[in] chunkDescs Array of chunk descriptors of size chunkCount. -\param[in] chunkCount The number of chunk descriptors. -\param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. -\param[in] bondCount The number of bond descriptors. -\param[in] chunkReorderMap Chunk reorder map to use, must be of size chunkCount. -\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. +\param[out] reorderedChunkDescs User-supplied array of size chunkCount to fill with new reordered NvBlastChunkDesc's. +\param[in] chunkDescs Array of chunk descriptors of size chunkCount. +\param[in] chunkCount The number of chunk descriptors. +\param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. +\param[in] bondCount The number of bond descriptors. +\param[in] chunkReorderMap Chunk reorder map to use, must be of size chunkCount. +\param[in] keepBondNormalChunkOrder If true, bond normals will be flipped if their chunk index order was reveresed by the reorder map. +\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. */ NVBLAST_API void NvBlastApplyAssetDescChunkReorderMap ( @@ -324,6 +358,7 @@ NVBLAST_API void NvBlastApplyAssetDescChunkReorderMap NvBlastBondDesc* bondDescs, uint32_t bondCount, const uint32_t* chunkReorderMap, + bool keepBondNormalChunkOrder, NvBlastLog logFn ); @@ -338,15 +373,26 @@ This overload of function reorders chunks in place. @see NvBlastBuildAssetDescChunkReorderMap -\param[in] chunkDescs Array of chunk descriptors of size chunkCount. It will be updated accordingly. -\param[in] chunkCount The number of chunk descriptors. -\param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. -\param[in] bondCount The number of bond descriptors. -\param[in] chunkReorderMap Chunk reorder map to use, must be of size chunkCount. -\param[in] scratch User-supplied scratch storage, must point to chunkCount * sizeof(NvBlastChunkDesc) valid bytes of memory. -\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. +\param[in] chunkDescs Array of chunk descriptors of size chunkCount. It will be updated accordingly. +\param[in] chunkCount The number of chunk descriptors. +\param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. +\param[in] bondCount The number of bond descriptors. +\param[in] chunkReorderMap Chunk reorder map to use, must be of size chunkCount. +\param[in] keepBondNormalChunkOrder If true, bond normals will be flipped if their chunk index order was reveresed by the reorder map. +\param[in] scratch User-supplied scratch storage, must point to chunkCount * sizeof(NvBlastChunkDesc) valid bytes of memory. +\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. */ -NVBLAST_API void NvBlastApplyAssetDescChunkReorderMapInplace(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, const uint32_t* chunkReorderMap, void* scratch, NvBlastLog logFn); +NVBLAST_API void NvBlastApplyAssetDescChunkReorderMapInPlace +( + NvBlastChunkDesc* chunkDescs, + uint32_t chunkCount, + NvBlastBondDesc* bondDescs, + uint32_t bondCount, + const uint32_t* chunkReorderMap, + bool keepBondNormalChunkOrder, + void* scratch, + NvBlastLog logFn +); /** @@ -354,17 +400,28 @@ Build and apply chunk reorder map. Function basically calls NvBlastBuildAssetDescChunkReorderMap and NvBlastApplyAssetDescChunkReorderMap. Used for Convenience. -\param[in] chunkDescs Array of chunk descriptors of size chunkCount. It will be updated accordingly. -\param[in] chunkCount The number of chunk descriptors. -\param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. -\param[in] bondCount The number of bond descriptors. -\param[in] chunkReorderMap Chunk reorder map to fill, must be of size chunkCount. -\param[in] scratch User-supplied scratch storage, must point to chunkCount * sizeof(NvBlastChunkDesc) valid bytes of memory. -\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. +\param[in] chunkDescs Array of chunk descriptors of size chunkCount. It will be updated accordingly. +\param[in] chunkCount The number of chunk descriptors. +\param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. +\param[in] bondCount The number of bond descriptors. +\param[in] chunkReorderMap Chunk reorder map to fill, must be of size chunkCount. +\param[in] keepBondNormalChunkOrder If true, bond normals will be flipped if their chunk index order was reveresed by the reorder map. +\param[in] scratch User-supplied scratch storage, must point to chunkCount * sizeof(NvBlastChunkDesc) valid bytes of memory. +\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. \return true iff the chunks did not require reordering (chunkReorderMap is the identity map). */ -NVBLAST_API bool NvBlastReorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap, void* scratch, NvBlastLog logFn); +NVBLAST_API bool NvBlastReorderAssetDescChunks +( + NvBlastChunkDesc* chunkDescs, + uint32_t chunkCount, + NvBlastBondDesc* bondDescs, + uint32_t bondCount, + uint32_t* chunkReorderMap, + bool keepBondNormalChunkOrder, + void* scratch, + NvBlastLog logFn +); ///@} End NvBlastAsset helper functions @@ -386,6 +443,17 @@ NVBLAST_API uint32_t NvBlastFamilyGetFormatVersion(const NvBlastFamily* family, /** +Retrieve the asset of the given family. + +\param[in] family The family. +\param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + +\return pointer to the asset associated with the family. +*/ +NVBLAST_API const NvBlastAsset* NvBlastFamilyGetAsset(const NvBlastFamily* family, NvBlastLog logFn); + + +/** Set asset to the family. It should be the same asset as the one family was created from (same ID). \param[in] family The family. @@ -776,6 +844,24 @@ Determines if the actor can fracture further. */ NVBLAST_API bool NvBlastActorCanFracture(const NvBlastActor* actor, NvBlastLog logFn); + +/** +Determines if the actor is damaged (was fractured) and split call is required. + +The actor could be damaged by calling NvBlastActorApplyFracture or NvBlastFamilyApplyFracture and NvBlastActorSplit is expected after. +This function gives a hint that NvBlastActorSplit will have some work to be done and actor could potentially be split. +If actor is not damaged calling NvBlastActorSplit will make no effect. + +\return true iff split call is required for this actor. +*/ +NVBLAST_API bool NvBlastActorIsSplitRequired(const NvBlastActor* actor, NvBlastLog logFn); + + +/** +\return true iff this actor contains the "world" support graph node, created when a bond contains the UINT32_MAX value for one of their chunkIndices. +*/ +NVBLAST_API bool NvBlastActorIsBoundToWorld(const NvBlastActor* actor, NvBlastLog logFn); + ///@} End NvBlastActor damage and fracturing functions diff --git a/sdk/lowlevel/include/NvBlastPreprocessor.h b/sdk/lowlevel/include/NvBlastPreprocessor.h index 25a8516..8e5cc78 100644 --- a/sdk/lowlevel/include/NvBlastPreprocessor.h +++ b/sdk/lowlevel/include/NvBlastPreprocessor.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 NVBLASTPREPROCESSOR_H #define NVBLASTPREPROCESSOR_H @@ -19,13 +37,4 @@ #define NVBLAST_API NV_C_EXPORT NV_DLL_EXPORT -/** -Macros for more convenient logging -*/ -#define NVBLAST_LOG_ERROR(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Error, _msg, __FILE__, __LINE__); } ((void)0) -#define NVBLAST_LOG_WARNING(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Warning, _msg, __FILE__, __LINE__); } ((void)0) -#define NVBLAST_LOG_INFO(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Info, _msg, __FILE__, __LINE__); } ((void)0) -#define NVBLAST_LOG_DEBUG(_logFn, _msg) if (_logFn != nullptr) { _logFn(NvBlastMessage::Debug, _msg, __FILE__, __LINE__); } ((void)0) - - #endif // ifndef NVBLASTPREPROCESSOR_H diff --git a/sdk/lowlevel/include/NvBlastProfiler.h b/sdk/lowlevel/include/NvBlastProfiler.h deleted file mode 100644 index cd60b4f..0000000 --- a/sdk/lowlevel/include/NvBlastProfiler.h +++ /dev/null @@ -1,52 +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 NVBLASTPROFILER_H -#define NVBLASTPROFILER_H - -#include "NvBlastPreprocessor.h" - -namespace physx { - class PxProfilerCallback; -} - -struct NvBlastProfilerDetail -{ - enum Level - { - LOW, - MEDIUM, - HIGH - }; -}; - -/** -Profiler features are only active in checked, debug and profile builds. -*/ - -/** -Set a callback to PVD or another PxProfilerCallback based profiler. -*/ -NVBLAST_API void NvBlastProfilerSetCallback(physx::PxProfilerCallback* pcb); - -/** -Enable events for platform specific profiler tools. Currently supported: -Nsight, PS4, Xbox One -*/ -NVBLAST_API void NvBlastProfilerEnablePlatform(bool); - -/** -Sets the depth of reported profile zones. -Higher levels (more nesting) of instrumentation can have a significant impact. -Defaults to NvBlastProfilerDetail::Level::LOW. -*/ -NVBLAST_API void NvBlastProfilerSetDetail(NvBlastProfilerDetail::Level); - -#endif diff --git a/sdk/lowlevel/include/NvBlastTypes.h b/sdk/lowlevel/include/NvBlastTypes.h index d711842..9fbeef9 100644 --- a/sdk/lowlevel/include/NvBlastTypes.h +++ b/sdk/lowlevel/include/NvBlastTypes.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 NVBLASTTYPES_H #define NVBLASTTYPES_H @@ -123,28 +141,6 @@ struct NvBlastDataBlock /////////////////////////////////////////////////////////////////////////////// ///@{ - -/** -Struct-enum which keeps track of the asset data format. -*/ -struct NvBlastAssetDataFormat -{ - 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 asset formats. */ - Count, - - /** The current version. This should always be Count-1 */ - Current = Count - 1 - }; -}; - - /** Represents a piece of a destructible asset which may be realized as an entity with a physical and graphical component. @@ -189,8 +185,6 @@ struct NvBlastChunk /** Represents the interface between two chunks. At most one bond is created for a chunk pair. -The convention regarding the normal direction is based upon the chunk indices, -pointing from the lower-indexed chunk to the higher-indexed chunk. */ struct NvBlastBond { @@ -283,7 +277,7 @@ struct NvBlastSupportGraph /** Asset (opaque) -Static destructible data, used to create actor familes. +Static destructible data, used to create actor families. Pointer to this struct can be created with NvBlastCreateAsset. @@ -327,11 +321,16 @@ Chunk bond descriptor used to build an asset. See NvBlastAssetDesc. */ struct NvBlastBondDesc { - /** The indices of the chunks linked by this bond. They must be different support chunk indices. */ - uint32_t chunkIndices[2]; - /** Bond data (see NvBlastBond). */ NvBlastBond bond; + + /** + The indices of the chunks linked by this bond. They must be different support chunk indices. + If one of the chunk indices is the invalid index (UINT32_MAX), then this will create a bond between + the chunk indexed by the other index (which must be valid) and "the world." Any actor containing + this bond will cause the function NvBlastActorIsBoundToWorld to return true. + */ + uint32_t chunkIndices[2]; }; @@ -366,28 +365,6 @@ struct NvBlastAssetDesc /////////////////////////////////////////////////////////////////////////////// ///@{ - -/** -Struct-enum which keeps track of the family data format. -*/ -struct NvBlastFamilyDataFormat -{ - 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 family formats. */ - Count, - - /** The current version. This should always be Count-1 */ - Current = Count - 1 - }; -}; - - /** Family (opaque) @@ -435,7 +412,7 @@ struct NvBlastActorDesc /** Initial health of all support chunks. If not NULL, this must be of length - NvBlastAssetGetSupportGraph(asset, logFn).nodeCount. The elements in the initialSupportChunkHealth + NvBlastAssetGetSupportChunkCount(asset, logFn).nodeCount. The elements in the initialSupportChunkHealth array will correspond to the chunk indices in the NvBlastAssetGetSupportGraph(asset, logFn).chunkIndices array. Every descendent of a support chunk will have its health initialized to its ancestor support chunk's health, so this initializes all lower-support chunk healths. @@ -520,7 +497,9 @@ struct NvBlastGraphShaderActor const uint32_t* adjacentNodeIndices; //!< See NvBlastSupportGraph::adjacentNodeIndices. const uint32_t* adjacentBondIndices; //!< See NvBlastSupportGraph::adjacentBondIndices. const NvBlastBond* assetBonds; //!< NvBlastBonds geometry in the NvBlastAsset. + const NvBlastChunk* assetChunks; //!< NvBlastChunks geometry in the NvBlastAsset. const float* familyBondHealths; //!< Actual bond health values for broken bond detection. + const float* supportChunkHealths; //!< Actual chunk health values for dead chunk detection. }; diff --git a/sdk/lowlevel/include/NvCTypes.h b/sdk/lowlevel/include/NvCTypes.h new file mode 100644 index 0000000..0dcf885 --- /dev/null +++ b/sdk/lowlevel/include/NvCTypes.h @@ -0,0 +1,125 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef NV_C_TYPES_H +#define NV_C_TYPES_H + +#include "NvPreprocessor.h" +#ifdef _MSC_VER +#ifndef _INTPTR +#define _INTPTR 0 +#endif +#endif +#include <stdint.h> + +/** C type for 2-float vectors */ +typedef struct +{ + float x, y; +} NvcVec2; + +/** C type for 3-float vectors */ +typedef struct +{ + float x, y, z; +} NvcVec3; + +/** C type for 4-float vectors */ +typedef struct +{ + float x, y, z, w; +} NvcVec4; + +/** C type for quaternions */ +typedef struct +{ + float x, y, z, w; +} NvcQuat; + +/** C type for transforms */ +typedef struct +{ + NvcQuat q; + NvcVec3 p; +} NvcTransform; + +/** C type for 3x3 matrices */ +typedef struct +{ + NvcVec3 column0, column1, column2, column3; +} NvcMat34; + +/** C type for 3x3 matrices */ +typedef struct +{ + NvcVec3 column0, column1, column2; +} NvcMat33; + +/** C type for 4x4 matrices */ +typedef struct +{ + NvcVec4 column0, column1, column2, column3; +} NvcMat44; + +/** C type for 3d bounding box */ +typedef struct +{ + NvcVec3 minimum; + NvcVec3 maximum; +} NvcBounds3; + +/** C type for a plane */ +typedef struct +{ + NvcVec3 n; + float d; +} NvcPlane; + +/** C type for 2-integer vectors */ +typedef struct +{ + int32_t x, y; +} NvcVec2i; + +/** C type for 3-integer vectors */ +typedef struct +{ + int32_t x, y, z; +} NvcVec3i; + +/** C type for 4-integer vectors */ +typedef struct +{ + int32_t x, y, z, w; +} NvcVec4i; + +/** @} */ + +#endif // NV_C_TYPES_H diff --git a/sdk/lowlevel/include/NvPreprocessor.h b/sdk/lowlevel/include/NvPreprocessor.h index 07a3ebc..01e2d0f 100644 --- a/sdk/lowlevel/include/NvPreprocessor.h +++ b/sdk/lowlevel/include/NvPreprocessor.h @@ -23,7 +23,7 @@ // components in life support devices or systems without express written approval of // NVIDIA Corporation. // -// Copyright (c) 2008-2014 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. diff --git a/sdk/lowlevel/source/NvBlastActor.cpp b/sdk/lowlevel/source/NvBlastActor.cpp index b93c47a..afed7bb 100644 --- a/sdk/lowlevel/source/NvBlastActor.cpp +++ b/sdk/lowlevel/source/NvBlastActor.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 "NvBlastActor.h" #include "NvBlastFamilyGraph.h" @@ -24,29 +42,11 @@ namespace Nv namespace Blast { -//////// Local helper functions //////// - -#if NVBLAST_CHECK_PARAMS -/** -Helper function to validate fracture buffer values being meaningful. -*/ -static inline bool isValid(const NvBlastFractureBuffers* buffers) -{ - if (buffers->chunkFractureCount != 0 && buffers->chunkFractures == nullptr) - return false; - - if (buffers->bondFractureCount != 0 && buffers->bondFractures == nullptr) - return false; - - return true; -} -#endif - //////// Actor static methods //////// size_t Actor::createRequiredScratch(const NvBlastFamily* family) { -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS if (family == nullptr || reinterpret_cast<const FamilyHeader*>(family)->m_asset == nullptr) { NVBLAST_ALWAYS_ASSERT(); @@ -61,22 +61,22 @@ size_t Actor::createRequiredScratch(const NvBlastFamily* family) Actor* Actor::create(NvBlastFamily* family, const NvBlastActorDesc* desc, void* scratch, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "Actor::create: NULL family pointer input.", return nullptr); - NVBLAST_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset != nullptr, logFn, "Actor::create: family has NULL asset.", return nullptr); - NVBLAST_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset->m_graph.m_nodeCount != 0, logFn, "Actor::create: family's asset has no support chunks.", return nullptr); - NVBLAST_CHECK(desc != nullptr, logFn, "Actor::create: NULL desc pointer input.", return nullptr); - NVBLAST_CHECK(scratch != nullptr, logFn, "Actor::create: NULL scratch input.", return nullptr); + NVBLASTLL_CHECK(family != nullptr, logFn, "Actor::create: NULL family pointer input.", return nullptr); + NVBLASTLL_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset != nullptr, logFn, "Actor::create: family has NULL asset.", return nullptr); + NVBLASTLL_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset->m_graph.m_nodeCount != 0, logFn, "Actor::create: family's asset has no support chunks.", return nullptr); + NVBLASTLL_CHECK(desc != nullptr, logFn, "Actor::create: NULL desc pointer input.", return nullptr); + NVBLASTLL_CHECK(scratch != nullptr, logFn, "Actor::create: NULL scratch input.", return nullptr); FamilyHeader* header = reinterpret_cast<FamilyHeader*>(family); if (header->m_actorCount > 0) { - NVBLAST_LOG_ERROR(logFn, "Actor::create: input family is not empty."); + NVBLASTLL_LOG_ERROR(logFn, "Actor::create: input family is not empty."); return nullptr; } const Asset& solverAsset = *static_cast<const Asset*>(header->m_asset); - const Nv::Blast::SupportGraph& graph = solverAsset.m_graph; + const SupportGraph& graph = solverAsset.m_graph; // Lower support chunk healths - initialize float* lowerSupportChunkHealths = header->getLowerSupportChunkHealths(); @@ -190,14 +190,14 @@ uint32_t Actor::damageBond(const NvBlastBondFractureData& cmd) void Actor::generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams, NvBlastLog logFn, NvBlastTimers* timers) const { - NVBLAST_CHECK(commandBuffers != nullptr, logFn, "Actor::generateFracture: NULL commandBuffers pointer input.", return); - NVBLAST_CHECK(isValid(commandBuffers), logFn, "NvBlastActorGenerateFracture: commandBuffers memory is NULL but size is > 0.", + NVBLASTLL_CHECK(commandBuffers != nullptr, logFn, "Actor::generateFracture: NULL commandBuffers pointer input.", return); + NVBLASTLL_CHECK(isValid(commandBuffers), logFn, "NvBlastActorGenerateFracture: commandBuffers memory is NULL but size is > 0.", commandBuffers->bondFractureCount = 0; commandBuffers->chunkFractureCount = 0; return); -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS if (commandBuffers->bondFractureCount == 0 && commandBuffers->chunkFractureCount == 0) { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorGenerateFracture: commandBuffers do not provide any space."); + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorGenerateFracture: commandBuffers do not provide any space."); return; } #endif @@ -221,7 +221,9 @@ void Actor::generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBla graph->getAdjacentNodeIndices(), graph->getAdjacentBondIndices(), getBonds(), - getBondHealths() + getChunks(), + getBondHealths(), + getLowerSupportChunkHealths() }; program.graphShaderFunction(commandBuffers, &shaderActor, programParams); @@ -252,374 +254,6 @@ void Actor::generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBla } -void Actor::fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks) -{ - const NvBlastChunk& chunk = chunks[chunkIndex]; - uint32_t numChildren = chunk.childIndexStop - chunk.firstChildIndex; - - if (numChildren > 0) - { - healthDamage /= numChildren; - for (uint32_t childIndex = chunk.firstChildIndex; childIndex < chunk.childIndexStop; childIndex++) - { - float& health = chunkHealths[childIndex - suboffset]; - if (health > 0.0f) - { - float remainingDamage = healthDamage - health; - health -= healthDamage; - - NVBLAST_ASSERT(chunks[childIndex].parentChunkIndex == chunkIndex); - - if (health <= 0.0f && remainingDamage > 0.0f) - { - fractureSubSupportNoEvents(childIndex, suboffset, remainingDamage, chunkHealths, chunks); - } - } - } - } -} - - -void Actor::fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount) -{ - const NvBlastChunk& chunk = chunks[chunkIndex]; - uint32_t numChildren = chunk.childIndexStop - chunk.firstChildIndex; - - if (numChildren > 0) - { - healthDamage /= numChildren; - for (uint32_t childIndex = chunk.firstChildIndex; childIndex < chunk.childIndexStop; childIndex++) - { - float& health = chunkHealths[childIndex - suboffset]; - if (health > 0.0f) - { - float remainingDamage = healthDamage - health; - health -= healthDamage; - - NVBLAST_ASSERT(chunks[childIndex].parentChunkIndex == chunkIndex); - - if (*currentIndex < maxCount) - { - NvBlastChunkFractureData& event = outBuffer[*currentIndex]; - event.userdata = chunks[childIndex].userData; - event.chunkIndex = childIndex; - event.health = health; - } - (*currentIndex)++; - - if (health <= 0.0f && remainingDamage > 0.0f) - { - fractureSubSupport(childIndex, suboffset, remainingDamage, chunkHealths, chunks, outBuffer, currentIndex, maxCount); - } - } - } - } - -} - - -void Actor::fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures) -{ - const Asset& asset = *getAsset(); - const SupportGraph& graph = *getGraph(); - const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); - const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices(); - float* bondHealths = getBondHealths(); - float* chunkHealths = getLowerSupportChunkHealths(); - float* subChunkHealths = getSubsupportChunkHealths(); - const NvBlastChunk* chunks = getChunks(); - - for (uint32_t i = 0; i < chunkFractureCount; ++i) - { - const NvBlastChunkFractureData& command = chunkFractures[i]; - const uint32_t chunkIndex = command.chunkIndex; - const uint32_t chunkHealthIndex = asset.getContiguousLowerSupportIndex(chunkIndex); - NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); - if (isInvalidIndex(chunkHealthIndex)) - { - continue; - } - float& health = chunkHealths[chunkHealthIndex]; - if (health > 0.0f && command.health > 0.0f) - { - const uint32_t nodeIndex = asset.getChunkToGraphNodeMap()[chunkIndex]; - if (getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) - { - for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) - { - - const uint32_t bondIndex = graph.findBond(nodeIndex, graphAdjacentNodeIndices[adjacentIndex]); - NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); - if (bondHealths[bondIndex] > 0.0f) - { - bondHealths[bondIndex] = 0.0f; - } - } - getFamilyGraph()->notifyNodeRemoved(getIndex(), nodeIndex, &graph); - } - - health -= command.health; - - const float remainingDamage = -health; - - if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health - { - uint32_t firstSubOffset = getFirstSubsupportChunkIndex(); - fractureSubSupportNoEvents(chunkIndex, firstSubOffset, remainingDamage, subChunkHealths, chunks); - } - } - } -} - - -void Actor::fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count) -{ - const Asset& asset = *getAsset(); - const SupportGraph& graph = *getGraph(); - const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); - const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices(); - float* bondHealths = getBondHealths(); - float* chunkHealths = getLowerSupportChunkHealths(); - float* subChunkHealths = getSubsupportChunkHealths(); - const NvBlastChunk* chunks = getChunks(); - - for (uint32_t i = 0; i < chunkFractureCount; ++i) - { - const NvBlastChunkFractureData& command = commands[i]; - const uint32_t chunkIndex = command.chunkIndex; - const uint32_t chunkHealthIndex = asset.getContiguousLowerSupportIndex(chunkIndex); - NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); - if (isInvalidIndex(chunkHealthIndex)) - { - continue; - } - float& health = chunkHealths[chunkHealthIndex]; - if (health > 0.0f && command.health > 0.0f) - { - const uint32_t nodeIndex = asset.getChunkToGraphNodeMap()[chunkIndex]; - if (getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) - { - for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) - { - const uint32_t bondIndex = graph.findBond(nodeIndex, graphAdjacentNodeIndices[adjacentIndex]); - NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); - if (bondHealths[bondIndex] > 0.0f) - { - bondHealths[bondIndex] = 0.0f; - } - } - getFamilyGraph()->notifyNodeRemoved(getIndex(), nodeIndex, &graph); - } - - health -= command.health; - - if (*count < eventsSize) - { - NvBlastChunkFractureData& outEvent = events[*count]; - outEvent.userdata = chunks[chunkIndex].userData; - outEvent.chunkIndex = chunkIndex; - outEvent.health = health; - } - (*count)++; - - const float remainingDamage = -health; - - if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health - { - uint32_t firstSubOffset = getFirstSubsupportChunkIndex(); - fractureSubSupport(chunkIndex, firstSubOffset, remainingDamage, subChunkHealths, chunks, events, count, eventsSize); - } - } - } -} - - -void Actor::fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count) -{ - const Asset& asset = *getAsset(); - const SupportGraph& graph = *getGraph(); - const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); - const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices(); - float* bondHealths = getBondHealths(); - float* chunkHealths = getLowerSupportChunkHealths(); - float* subChunkHealths = getSubsupportChunkHealths(); - const NvBlastChunk* chunks = getChunks(); - - // - // First level Chunk Fractures - // - - for (uint32_t i = 0; i < chunkFractureCount; ++i) - { - const NvBlastChunkFractureData& command = inoutbuffer[i]; - const uint32_t chunkIndex = command.chunkIndex; - const uint32_t chunkHealthIndex = asset.getContiguousLowerSupportIndex(chunkIndex); - NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); - if (isInvalidIndex(chunkHealthIndex)) - { - continue; - } - float& health = chunkHealths[chunkHealthIndex]; - if (health > 0.0f && command.health > 0.0f) - { - const uint32_t nodeIndex = asset.getChunkToGraphNodeMap()[chunkIndex]; - if (getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) - { - for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) - { - const uint32_t bondIndex = graph.findBond(nodeIndex, graphAdjacentNodeIndices[adjacentIndex]); - NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); - if (bondHealths[bondIndex] > 0.0f) - { - bondHealths[bondIndex] = 0.0f; - } - } - getFamilyGraph()->notifyNodeRemoved(getIndex(), nodeIndex, &graph); - } - - health -= command.health; - - NvBlastChunkFractureData& outEvent = inoutbuffer[(*count)++]; - outEvent.userdata = chunks[chunkIndex].userData; - outEvent.chunkIndex = chunkIndex; - outEvent.health = health; - } - } - - // - // Hierarchical Chunk Fractures - // - - uint32_t commandedChunkFractures = *count; - - for (uint32_t i = 0; i < commandedChunkFractures; ++i) - { - NvBlastChunkFractureData& event = inoutbuffer[i]; - const uint32_t chunkIndex = event.chunkIndex; - - const float remainingDamage = -event.health; - if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health - { - uint32_t firstSubOffset = getFirstSubsupportChunkIndex(); - fractureSubSupport(chunkIndex, firstSubOffset, remainingDamage, subChunkHealths, chunks, inoutbuffer, count, eventsSize); - } - } -} - - -void Actor::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, NvBlastLog logFn, NvBlastTimers* timers) -{ - NVBLAST_CHECK(commands != nullptr, logFn, "Actor::applyFracture: NULL commands pointer input.", return); - NVBLAST_CHECK(isValid(commands), logFn, "Actor::applyFracture: commands memory is NULL but size is > 0.", return); - NVBLAST_CHECK(eventBuffers == nullptr || isValid(eventBuffers), logFn, "NvBlastActorApplyFracture: eventBuffers memory is NULL but size is > 0.", - eventBuffers->bondFractureCount = 0; eventBuffers->chunkFractureCount = 0; return); - -#if NVBLAST_CHECK_PARAMS - if (eventBuffers != nullptr && eventBuffers->bondFractureCount == 0 && eventBuffers->chunkFractureCount == 0) - { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers do not provide any space."); - return; - } -#endif - -#if NV_PROFILE - Time time; -#else - NV_UNUSED(timers); -#endif - - // - // Chunk Fracture - // - - if (eventBuffers == nullptr || eventBuffers->chunkFractures == nullptr) - { - // immediate hierarchical fracture - fractureNoEvents(commands->chunkFractureCount, commands->chunkFractures); - } - else if (eventBuffers->chunkFractures != commands->chunkFractures) - { - // immediate hierarchical fracture - uint32_t count = 0; - fractureWithEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractures, eventBuffers->chunkFractureCount, &count); - - if (count > eventBuffers->chunkFractureCount) - { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Chunk events were lost."); - } - else - { - eventBuffers->chunkFractureCount = count; - } - } - else if (eventBuffers->chunkFractures == commands->chunkFractures) - { - // compacting first - uint32_t count = 0; - fractureInPlaceEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractureCount, &count); - - if (count > eventBuffers->chunkFractureCount) - { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Chunk events were lost."); - } - else - { - eventBuffers->chunkFractureCount = count; - } - } - - // - // Bond Fracture - // - - uint32_t outCount = 0; - const uint32_t eventBufferSize = eventBuffers ? eventBuffers->bondFractureCount : 0; - - NvBlastBond* bonds = getBonds(); - float* bondHealths = getBondHealths(); - for (uint32_t i = 0; i < commands->bondFractureCount; ++i) - { - const NvBlastBondFractureData& frac = commands->bondFractures[i]; - - const uint32_t bondIndex = damageBond(frac.nodeIndex0, frac.nodeIndex1, frac.health); - - if (!isInvalidIndex(bondIndex)) - { - if (eventBuffers && eventBuffers->bondFractures) - { - if (outCount < eventBufferSize) - { - NvBlastBondFractureData& outEvent = eventBuffers->bondFractures[outCount]; - outEvent.userdata = bonds[bondIndex].userData; - outEvent.nodeIndex0 = frac.nodeIndex0; - outEvent.nodeIndex1 = frac.nodeIndex1; - outEvent.health = bondHealths[bondIndex]; - } - } - outCount++; - } - } - - if (eventBuffers && eventBuffers->bondFractures) - { - if (outCount > eventBufferSize) - { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Bond events were lost."); - } - else - { - eventBuffers->bondFractureCount = outCount; - } - } - -#if NV_PROFILE - if (timers != nullptr) - { - timers->fracture += time.getElapsedTicks(); - } -#endif - -} size_t Actor::splitRequiredScratch() const @@ -630,9 +264,9 @@ size_t Actor::splitRequiredScratch() const uint32_t Actor::split(NvBlastActorSplitEvent* result, uint32_t newActorsMaxCount, void* scratch, NvBlastLog logFn, NvBlastTimers* timers) { - NVBLAST_CHECK(result != nullptr, logFn, "Actor::split: NULL result pointer input.", return 0); - NVBLAST_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0); - NVBLAST_CHECK(scratch != nullptr, logFn, "Actor::split: NULL scratch pointer input.", return 0); + NVBLASTLL_CHECK(result != nullptr, logFn, "Actor::split: NULL result pointer input.", return 0); + NVBLASTLL_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0); + NVBLASTLL_CHECK(scratch != nullptr, logFn, "Actor::split: NULL scratch pointer input.", return 0); #if NV_PROFILE Time time; @@ -708,10 +342,21 @@ uint32_t Actor::split(NvBlastActorSplitEvent* result, uint32_t newActorsMaxCount #endif // Recalculate visible chunk lists if the graph nodes have been redistributed + uint32_t actualActorsCount = 0; for (uint32_t i = 0; i < actorsCount; ++i) { - newActors[i]->updateVisibleChunksFromGraphNodes(); + newActors[actualActorsCount] = newActors[i]; + newActors[actualActorsCount]->updateVisibleChunksFromGraphNodes(); + if (newActors[actualActorsCount]->getVisibleChunkCount() > 0) // If we've split such that the world node is by itself, it will have no visible chunks + { + ++actualActorsCount; + } + else + { + getFamilyHeader()->returnActor(*newActors[actualActorsCount]); + } } + actorsCount = actualActorsCount; #if NV_PROFILE if (timers != nullptr) @@ -780,7 +425,7 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor // Check for single subsupport chunk, no partitioning if (m_graphNodeCount <= 1) { - NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: actor is a single lower-support chunk, and cannot be partitioned by this function."); + NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: actor is a single lower-support chunk, and cannot be partitioned by this function."); return 0; } @@ -810,7 +455,11 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor if (islandID == thisActorIndex) { - m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndices[graphNodeIndex]]; + const uint32_t graphChunkIndex = graphChunkIndices[graphNodeIndex]; + if (!isInvalidIndex(graphChunkIndex)) // Invalid if this is the world chunk + { + m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndex]; + } lastGraphNodeIndex = graphNodeIndex; continue; // Leave the chunk in this actor } @@ -855,7 +504,11 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor newActor->m_firstGraphNodeIndex = graphNodeIndex; ++newActor->m_graphNodeCount; // Add to the actor's leaf chunk count - newActor->m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndices[graphNodeIndex]]; + const uint32_t graphChunkIndex = graphChunkIndices[graphNodeIndex]; + if (!isInvalidIndex(graphChunkIndex)) // Invalid if this is the world chunk + { + newActor->m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndex]; + } } if (m_graphNodeCount > 0) @@ -878,7 +531,7 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor if (overflow) { - NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: input newActors array could not hold all actors generated."); + NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: input newActors array could not hold all actors generated."); } return newActorCount; @@ -892,7 +545,7 @@ uint32_t Actor::partitionSingleLowerSupportChunk(Actor** newActors, uint32_t new // Ensure this is a single subsupport chunk, no partitioning if (m_graphNodeCount > 1) { - NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: actor is not a single lower-support chunk, and cannot be partitioned by this function."); + NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: actor is not a single lower-support chunk, and cannot be partitioned by this function."); return 0; } @@ -901,6 +554,12 @@ uint32_t Actor::partitionSingleLowerSupportChunk(Actor** newActors, uint32_t new // The conditional (visible vs. support chunk) is needed because we allow single-child chunk chains // This makes it possible that an actor with a single support chunk will have a different visible chunk (ancestor of the support chunk) const uint32_t chunkIndex = m_graphNodeCount == 0 ? m_firstVisibleChunkIndex : getGraph()->getChunkIndices()[m_firstGraphNodeIndex]; + + if (isInvalidIndex(chunkIndex)) + { + return 0; // This actor has no chunks; only a graph node representing the world + } + NVBLAST_ASSERT(isInvalidIndex(header->getVisibleChunkIndexLinks()[chunkIndex].m_adj[1])); const NvBlastChunk& chunk = header->m_asset->getChunks()[chunkIndex]; @@ -909,7 +568,7 @@ uint32_t Actor::partitionSingleLowerSupportChunk(Actor** newActors, uint32_t new // Warn if we cannot fit all child chunks in the output list if (childCount > newActorsSize) { - NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: input newActors array will not hold all actors generated."); + NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: input newActors array will not hold all actors generated."); childCount = newActorsSize; } @@ -959,7 +618,7 @@ void Actor::updateVisibleChunksFromGraphNodes() Actor* actors = header->getActors(); IndexDLink<uint32_t>* visibleChunkIndexLinks = header->getVisibleChunkIndexLinks(); uint32_t* chunkActorIndices = header->getChunkActorIndices(); - const Nv::Blast::SupportGraph& graph = asset->m_graph; + const SupportGraph& graph = asset->m_graph; const uint32_t* graphChunkIndices = graph.getChunkIndices(); const NvBlastChunk* chunks = asset->getChunks(); const uint32_t upperSupportChunkCount = asset->getUpperSupportChunkCount(); @@ -968,7 +627,11 @@ void Actor::updateVisibleChunksFromGraphNodes() const uint32_t* graphNodeIndexLinks = header->getGraphNodeIndexLinks(); for (uint32_t graphNodeIndex = m_firstGraphNodeIndex; !isInvalidIndex(graphNodeIndex); graphNodeIndex = graphNodeIndexLinks[graphNodeIndex]) { - updateVisibleChunksFromSupportChunk<Actor>(actors, visibleChunkIndexLinks, chunkActorIndices, thisActorIndex, graphChunkIndices[graphNodeIndex], chunks, upperSupportChunkCount); + const uint32_t supportChunkIndex = graphChunkIndices[graphNodeIndex]; + if (!isInvalidIndex(supportChunkIndex)) // Invalid if this is the world chunk + { + updateVisibleChunksFromSupportChunk<Actor>(actors, visibleChunkIndexLinks, chunkActorIndices, thisActorIndex, graphChunkIndices[graphNodeIndex], chunks, upperSupportChunkCount); + } } } @@ -983,9 +646,9 @@ extern "C" NvBlastActor* NvBlastFamilyCreateFirstActor(NvBlastFamily* family, const NvBlastActorDesc* desc, void* scratch, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL family input.", return nullptr); - NVBLAST_CHECK(desc != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL desc input.", return nullptr); - NVBLAST_CHECK(scratch != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL scratch input.", return nullptr); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL family input.", return nullptr); + NVBLASTLL_CHECK(desc != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL desc input.", return nullptr); + NVBLASTLL_CHECK(scratch != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL scratch input.", return nullptr); return Nv::Blast::Actor::create(family, desc, scratch, logFn); } @@ -993,8 +656,8 @@ NvBlastActor* NvBlastFamilyCreateFirstActor(NvBlastFamily* family, const NvBlast size_t NvBlastFamilyGetRequiredScratchForCreateFirstActor(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetRequiredScratchForCreateFirstActor: NULL family input.", return 0); - NVBLAST_CHECK(reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_asset != nullptr, + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetRequiredScratchForCreateFirstActor: NULL family input.", return 0); + NVBLASTLL_CHECK(reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_asset != nullptr, logFn, "NvBlastFamilyGetRequiredScratchForCreateFirstActor: family has NULL asset.", return 0); return Nv::Blast::Actor::createRequiredScratch(family); @@ -1003,13 +666,13 @@ size_t NvBlastFamilyGetRequiredScratchForCreateFirstActor(const NvBlastFamily* f bool NvBlastActorDeactivate(NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorDeactivate: NULL actor input.", return false); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorDeactivate: NULL actor input.", return false); Nv::Blast::Actor& a = *static_cast<Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorDeactivate: inactive actor input."); + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorDeactivate: inactive actor input."); } return a.release(); @@ -1018,13 +681,13 @@ bool NvBlastActorDeactivate(NvBlastActor* actor, NvBlastLog logFn) uint32_t NvBlastActorGetVisibleChunkCount(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkCount: NULL actor input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkCount: NULL actor input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkCount: inactive actor input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkCount: inactive actor input."); return 0; } @@ -1034,14 +697,14 @@ uint32_t NvBlastActorGetVisibleChunkCount(const NvBlastActor* actor, NvBlastLog uint32_t NvBlastActorGetVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize, const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(visibleChunkIndices != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL visibleChunkIndices pointer input.", return 0); - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL actor pointer input.", return 0); + NVBLASTLL_CHECK(visibleChunkIndices != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL visibleChunkIndices pointer input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL actor pointer input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkIndices: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkIndices: inactive actor pointer input."); return 0; } @@ -1058,13 +721,13 @@ uint32_t NvBlastActorGetVisibleChunkIndices(uint32_t* visibleChunkIndices, uint3 uint32_t NvBlastActorGetGraphNodeCount(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeCount: NULL actor pointer input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeCount: NULL actor pointer input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeCount: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeCount: inactive actor pointer input."); return 0; } @@ -1074,22 +737,27 @@ uint32_t NvBlastActorGetGraphNodeCount(const NvBlastActor* actor, NvBlastLog log uint32_t NvBlastActorGetGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize, const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(graphNodeIndices != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL graphNodeIndices pointer input.", return 0); - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL actor pointer input.", return 0); + NVBLASTLL_CHECK(graphNodeIndices != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL graphNodeIndices pointer input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL actor pointer input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeIndices: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeIndices: inactive actor pointer input."); return 0; } // Iterate through graph node list and write to supplied array + const uint32_t* graphChunkIndices = a.getAsset()->m_graph.getChunkIndices(); uint32_t indexCount = 0; for (Nv::Blast::Actor::GraphNodeIt i = a; indexCount < graphNodeIndicesSize && (bool)i; ++i) { - graphNodeIndices[indexCount++] = (uint32_t)i; + const uint32_t graphNodeIndex = (uint32_t)i; + if (!Nv::Blast::isInvalidIndex(graphChunkIndices[graphNodeIndex])) + { + graphNodeIndices[indexCount++] = graphNodeIndex; + } } return indexCount; @@ -1098,13 +766,13 @@ uint32_t NvBlastActorGetGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t gr const float* NvBlastActorGetBondHealths(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetBondHealths: NULL actor pointer input.", return nullptr); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetBondHealths: NULL actor pointer input.", return nullptr); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetBondHealths: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetBondHealths: inactive actor pointer input."); return nullptr; } @@ -1114,13 +782,13 @@ const float* NvBlastActorGetBondHealths(const NvBlastActor* actor, NvBlastLog lo NvBlastFamily* NvBlastActorGetFamily(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetFamily: NULL actor pointer input.", return nullptr); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetFamily: NULL actor pointer input.", return nullptr); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetFamily: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetFamily: inactive actor pointer input."); return nullptr; } @@ -1130,13 +798,13 @@ NvBlastFamily* NvBlastActorGetFamily(const NvBlastActor* actor, NvBlastLog logFn uint32_t NvBlastActorGetIndex(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetIndex: NULL actor pointer input.", return Nv::Blast::invalidIndex<uint32_t>()); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetIndex: NULL actor pointer input.", return Nv::Blast::invalidIndex<uint32_t>()); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active."); return Nv::Blast::invalidIndex<uint32_t>(); } @@ -1154,14 +822,14 @@ void NvBlastActorGenerateFracture NvBlastTimers* timers ) { - NVBLAST_CHECK(commandBuffers != nullptr, logFn, "NvBlastActorGenerateFracture: NULL commandBuffers pointer input.", return); - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGenerateFracture: NULL actor pointer input.", return); + NVBLASTLL_CHECK(commandBuffers != nullptr, logFn, "NvBlastActorGenerateFracture: NULL commandBuffers pointer input.", return); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGenerateFracture: NULL actor pointer input.", return); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGenerateFracture: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGenerateFracture: actor is not active."); commandBuffers->bondFractureCount = 0; commandBuffers->chunkFractureCount = 0; return; @@ -1180,15 +848,15 @@ void NvBlastActorApplyFracture NvBlastTimers* timers ) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorApplyFracture: NULL actor pointer input.", return); - NVBLAST_CHECK(commands != nullptr, logFn, "NvBlastActorApplyFracture: NULL commands pointer input.", return); - NVBLAST_CHECK(Nv::Blast::isValid(commands), logFn, "NvBlastActorApplyFracture: commands memory is NULL but size is > 0.", return); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorApplyFracture: NULL actor pointer input.", return); + NVBLASTLL_CHECK(commands != nullptr, logFn, "NvBlastActorApplyFracture: NULL commands pointer input.", return); + NVBLASTLL_CHECK(Nv::Blast::isValid(commands), logFn, "NvBlastActorApplyFracture: commands memory is NULL but size is > 0.", return); Nv::Blast::Actor& a = *static_cast<Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorApplyFracture: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorApplyFracture: actor is not active."); if (eventBuffers != nullptr) { eventBuffers->bondFractureCount = 0; @@ -1197,19 +865,19 @@ void NvBlastActorApplyFracture return; } - a.applyFracture(eventBuffers, commands, logFn, timers); + a.getFamilyHeader()->applyFracture(eventBuffers, commands, &a, logFn, timers); } size_t NvBlastActorGetRequiredScratchForSplit(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetRequiredScratchForSplit: NULL actor input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetRequiredScratchForSplit: NULL actor input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetRequiredScratchForSplit: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetRequiredScratchForSplit: actor is not active."); return 0; } @@ -1219,13 +887,13 @@ size_t NvBlastActorGetRequiredScratchForSplit(const NvBlastActor* actor, NvBlast uint32_t NvBlastActorGetMaxActorCountForSplit(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetMaxActorCountForSplit: NULL actor input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetMaxActorCountForSplit: NULL actor input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetMaxActorCountForSplit: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetMaxActorCountForSplit: actor is not active."); return 0; } @@ -1243,16 +911,16 @@ uint32_t NvBlastActorSplit NvBlastTimers* timers ) { - NVBLAST_CHECK(result != nullptr, logFn, "NvBlastActorSplit: NULL result pointer input.", return 0); - NVBLAST_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0); - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorSplit: NULL actor pointer input.", return 0); - NVBLAST_CHECK(scratch != nullptr, logFn, "NvBlastActorSplit: NULL scratch pointer input.", return 0); + NVBLASTLL_CHECK(result != nullptr, logFn, "NvBlastActorSplit: NULL result pointer input.", return 0); + NVBLASTLL_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorSplit: NULL actor pointer input.", return 0); + NVBLASTLL_CHECK(scratch != nullptr, logFn, "NvBlastActorSplit: NULL scratch pointer input.", return 0); Nv::Blast::Actor& a = *static_cast<Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active."); return 0; } @@ -1262,13 +930,13 @@ uint32_t NvBlastActorSplit bool NvBlastActorCanFracture(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorCanFracture: NULL actor input.", return false); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorCanFracture: NULL actor input.", return false); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorCanFracture: actor is not active."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorCanFracture: actor is not active."); return false; } @@ -1287,30 +955,25 @@ bool NvBlastActorCanFracture(const NvBlastActor* actor, NvBlastLog logFn) } -} // extern "C" +bool NvBlastActorIsBoundToWorld(const NvBlastActor* actor, NvBlastLog logFn) +{ + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorIsBoundToWorld: NULL actor input.", return false); + return static_cast<const Nv::Blast::Actor*>(actor)->isBoundToWorld(); +} -// deprecated API, still used in tests -uint32_t NvBlastActorClosestChunk(const float point[4], const NvBlastActor* actor, NvBlastLog logFn) + +bool NvBlastActorIsSplitRequired(const NvBlastActor* actor, NvBlastLog logFn) { - const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorIsSplitRequired: NULL actor input.", return false); - if (a.isSubSupportChunk()) + const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); + if (!a.isActive()) { - NVBLAST_LOG_WARNING(logFn, "NvBlastActorClosestChunk: not a graph actor."); - return Nv::Blast::invalidIndex<uint32_t>(); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorIsSplitRequired: actor is not active."); + return false; } - - uint32_t closestNode = Nv::Blast::findNodeByPositionLinked( - point, - a.getFirstGraphNodeIndex(), - a.getFamilyHeader()->getGraphNodeIndexLinks(), - a.getAsset()->m_graph.getAdjacencyPartition(), - a.getAsset()->m_graph.getAdjacentNodeIndices(), - a.getAsset()->m_graph.getAdjacentBondIndices(), - a.getAsset()->getBonds(), - a.getFamilyHeader()->getBondHealths() - ); - - return a.getAsset()->m_graph.getChunkIndices()[closestNode]; + return a.isSplitRequired(); } + +} // extern "C" diff --git a/sdk/lowlevel/source/NvBlastActor.h b/sdk/lowlevel/source/NvBlastActor.h index 42879e7..7e30660 100644 --- a/sdk/lowlevel/source/NvBlastActor.h +++ b/sdk/lowlevel/source/NvBlastActor.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 NVBLASTACTOR_H #define NVBLASTACTOR_H @@ -16,6 +34,8 @@ #include "NvBlastDLink.h" #include "NvBlastIteratorBase.h" #include "NvBlastSupportGraph.h" +#include "NvBlastFamilyGraph.h" +#include "NvBlastPreprocessorInternal.h" #include <cstring> @@ -309,6 +329,11 @@ public: //////// Damage and fracturing methods //////// /** + See NvBlastActorGenerateFracture + */ + void generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams, NvBlastLog logFn, NvBlastTimers* timers) const; + + /** Damage bond between two chunks by health amount (instance graph also will be notified in case bond is broken after). */ uint32_t damageBond(uint32_t nodeIndex0, uint32_t nodeIndex1, float healthDamage); @@ -324,73 +349,6 @@ public: uint32_t damageBond(const NvBlastBondFractureData& cmd); /** - See NvBlastActorGenerateFracture - */ - void generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams, NvBlastLog logFn, NvBlastTimers* timers) const; - - /** - Hierarchically distribute damage to child chunks. - - \param chunkIndex asset chunk index to hierarchically damage - \param suboffset index of the first sub-support health - \param healthDamage damage strength to apply - \param chunkHealths instance chunk healths - \param chunks asset chunk collection - */ - void fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks); - - /** - Hierarchically distribute damage to child chunks, recording a fracture event for each health damage applied. - - If outBuffer is too small, events are dropped but the chunks are still damaged. - - \param chunkIndex asset chunk index to hierarchically damage - \param suboffset index of the first sub-support health - \param healthDamage damage strength to apply - \param chunkHealths instance chunk healths - \param chunks asset chunk collection - \param outBuffer target buffer for fracture events - \param currentIndex current position in outBuffer - returns the number of damaged chunks - \param maxCount capacity of outBuffer - */ - void fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount); - - /** - Apply chunk fracture commands hierarchically. - - \param chunkFractureCount number of chunk fracture commands to apply - \param chunkFractures array of chunk fracture commands - */ - void fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures); - - /** - Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied. - - If events array is too small, events are dropped but the chunks are still damaged. - - \param chunkFractureCount number of chunk fracture commands to apply - \param commands array of chunk fracture commands - \param events target buffer for fracture events - \param eventsSize number of available entries in 'events' - \param count returns the number of damaged chunks - */ - void fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count); - - /** - Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied. - - In-Place version: fracture commands are replaced by fracture events. - - If inoutbuffer array is too small, events are dropped but the chunks are still damaged. - - \param chunkFractureCount number of chunk fracture commands to apply - \param inoutbuffer array of chunk fracture commands to be replaced by events - \param eventsSize number of available entries in inoutbuffer - \param count returns the number of damaged chunks - */ - void fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count); - - /** See NvBlastActorApplyFracture */ void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, NvBlastLog logFn, NvBlastTimers* timers); @@ -473,6 +431,16 @@ public: */ uint32_t partitionMultipleGraphNodes(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn); + /** + \return true iff this actor contains the "world" support graph node, created when a bond contains the invalidIndex<uint32_t>() value for one of their chunkIndices. + */ + bool isBoundToWorld() const; + + /** + \return true iff this actor was damaged and split() call is required. + */ + bool isSplitRequired() const; + private: //////// Data //////// @@ -695,7 +663,7 @@ NV_INLINE bool Actor::release() NV_INLINE uint32_t Actor::partition(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn) { - NVBLAST_CHECK(newActorsSize == 0 || newActors != nullptr, logFn, "Nv::Blast::Actor::partition: NULL newActors pointer array input with non-zero newActorCount.", return 0); + NVBLASTLL_CHECK(newActorsSize == 0 || newActors != nullptr, logFn, "Nv::Blast::Actor::partition: NULL newActors pointer array input with non-zero newActorCount.", return 0); // Call one of two partition functions depending on the actor's support status return m_graphNodeCount <= 1 ? @@ -704,6 +672,58 @@ NV_INLINE uint32_t Actor::partition(Actor** newActors, uint32_t newActorsSize, N } +NV_INLINE bool Actor::isBoundToWorld() const +{ + const SupportGraph& graph = *getGraph(); + + if (graph.m_nodeCount == 0) + { + return false; // This shouldn't happen + } + + const uint32_t lastGraphChunkIndex = graph.getChunkIndices()[graph.m_nodeCount - 1]; + + if (!isInvalidIndex(lastGraphChunkIndex)) + { + return false; // There is no world node + } + + return getFamilyGraph()->getIslandIds()[graph.m_nodeCount - 1] == getIndex(); +} + + +NV_INLINE bool Actor::isSplitRequired() const +{ + NVBLAST_ASSERT(isActive()); + + if (getGraphNodeCount() <= 1) + { + uint32_t chunkHealthIndex = isSingleSupportChunk() ? getIndex() : getFirstVisibleChunkIndex() - getFirstSubsupportChunkIndex() + getGraph()->m_nodeCount; + float* chunkHealths = getLowerSupportChunkHealths(); + if (chunkHealths[chunkHealthIndex] <= 0.0f) + { + const uint32_t chunkIndex = m_graphNodeCount == 0 ? m_firstVisibleChunkIndex : getGraph()->getChunkIndices()[m_firstGraphNodeIndex]; + if (!isInvalidIndex(chunkIndex)) + { + const NvBlastChunk& chunk = getChunks()[chunkIndex]; + uint32_t childCount = chunk.childIndexStop - chunk.firstChildIndex; + return childCount > 0; + } + } + } + else + { + uint32_t* firstDirtyNodeIndices = getFamilyGraph()->getFirstDirtyNodeIndices(); + if (!isInvalidIndex(firstDirtyNodeIndices[getIndex()])) + { + return true; + } + + } + return false; +} + + //////// Actor::VisibleChunkIt inline methods //////// NV_INLINE Actor::VisibleChunkIt::VisibleChunkIt(const Actor& actor) : DListIt<uint32_t>(actor.m_firstVisibleChunkIndex, actor.getFamilyHeader()->getVisibleChunkIndexLinks()) @@ -717,16 +737,28 @@ NV_INLINE Actor::GraphNodeIt::GraphNodeIt(const Actor& actor) : LListIt<uint32_t { } -} // namespace Blast -} // namespace Nv +//////// Helper functions //////// +#if NVBLASTLL_CHECK_PARAMS /** -Returns the closest chunk asset index for a supported actor. -Helper functions still used in tests. -Has become obsolete with introduction of chunkMap and its inverse. +Helper function to validate fracture buffer values being meaningful. */ -uint32_t NvBlastActorClosestChunk(const float point[4], const NvBlastActor* actor, NvBlastLog logFn); +static inline bool isValid(const NvBlastFractureBuffers* buffers) +{ + if (buffers->chunkFractureCount != 0 && buffers->chunkFractures == nullptr) + return false; + + if (buffers->bondFractureCount != 0 && buffers->bondFractures == nullptr) + return false; + + return true; +} +#endif + + +} // namespace Blast +} // namespace Nv #endif // ifndef NVBLASTACTOR_H diff --git a/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp b/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp index e496a69..ca830a7 100644 --- a/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp +++ b/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp @@ -1,12 +1,29 @@ -/* -* 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 "NvBlastActor.h" @@ -25,18 +42,18 @@ namespace Blast Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "Actor::deserialize: NULL family pointer input.", return nullptr); + NVBLASTLL_CHECK(family != nullptr, logFn, "Actor::deserialize: NULL family pointer input.", return nullptr); const ActorSerializationHeader* serHeader = reinterpret_cast<const ActorSerializationHeader*>(buffer); if (serHeader->m_formatVersion != ActorSerializationFormat::Current) { - NVBLAST_LOG_ERROR(logFn, "Actor::deserialize: wrong data format. Serialization data must be converted to current version."); + NVBLASTLL_LOG_ERROR(logFn, "Actor::deserialize: wrong data format. Serialization data must be converted to current version."); return nullptr; } FamilyHeader* header = reinterpret_cast<FamilyHeader*>(family); const Asset* asset = header->m_asset; - const Nv::Blast::SupportGraph& graph = asset->m_graph; + const SupportGraph& graph = asset->m_graph; const uint32_t* graphChunkIndices = graph.getChunkIndices(); const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices(); @@ -55,7 +72,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog if (actor == nullptr) { - NVBLAST_LOG_ERROR(logFn, "Actor::deserialize: invalid actor index in serialized data. Actor not created."); + NVBLASTLL_LOG_ERROR(logFn, "Actor::deserialize: invalid actor index in serialized data. Actor not created."); return nullptr; } @@ -63,7 +80,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog uint32_t* chunkActorIndices = header->getChunkActorIndices(); FamilyGraph* familyGraph = header->getFamilyGraph(); -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS { const uint32_t* serVisibleChunkIndices = serHeader->getVisibleChunkIndices(); for (uint32_t i = 0; i < serHeader->m_visibleChunkCount; ++i) @@ -71,7 +88,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog const uint32_t visibleChunkIndex = serVisibleChunkIndices[i]; if (!isInvalidIndex(chunkActorIndices[visibleChunkIndex])) { - NVBLAST_LOG_ERROR(logFn, "Actor::deserialize: visible chunk already has an actor in family. Actor not created."); + NVBLASTLL_LOG_ERROR(logFn, "Actor::deserialize: visible chunk already has an actor in family. Actor not created."); header->returnActor(*actor); return nullptr; } @@ -125,7 +142,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog { uint32_t serLowerSupportChunkCount = 0; float* graphNodeHealths = header->getLowerSupportChunkHealths(); - for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i) + for (Actor::GraphNodeIt i = *actor; (bool)i; ++i) { const uint32_t graphNodeIndex = (uint32_t)i; graphNodeHealths[graphNodeIndex] = serLowerSupportChunkHealths[serLowerSupportChunkCount++]; @@ -152,7 +169,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog { const float* serBondHealths = serHeader->getBondHealths(); float* bondHealths = header->getBondHealths(); - for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i) + for (Actor::GraphNodeIt i = *actor; (bool)i; ++i) { const uint32_t graphNodeIndex = (uint32_t)i; for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex) @@ -176,7 +193,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog { const uint32_t* serFastRoute = serHeader->getFastRoute(); uint32_t* fastRoute = header->getFamilyGraph()->getFastRoute(); - for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i) + for (Actor::GraphNodeIt i = *actor; (bool)i; ++i) { fastRoute[(uint32_t)i] = *serFastRoute++; } @@ -186,7 +203,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog { const uint32_t* serHopCounts = serHeader->getHopCounts(); uint32_t* hopCounts = header->getFamilyGraph()->getHopCounts(); - for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i) + for (Actor::GraphNodeIt i = *actor; (bool)i; ++i) { hopCounts[(uint32_t)i] = *serHopCounts++; } @@ -198,7 +215,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog uint32_t serBondIndex = 0; const FixedBoolArray* serEdgeRemovedArray = serHeader->getEdgeRemovedArray(); FixedBoolArray* edgeRemovedArray = familyGraph->getIsEdgeRemoved(); - for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i) + for (Actor::GraphNodeIt i = *actor; (bool)i; ++i) { const uint32_t graphNodeIndex = (uint32_t)i; for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex) @@ -232,7 +249,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c { // Set up pointers and such const Asset* asset = getAsset(); - const Nv::Blast::SupportGraph& graph = asset->m_graph; + const SupportGraph& graph = asset->m_graph; const uint32_t* graphChunkIndices = graph.getChunkIndices(); const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices(); @@ -247,7 +264,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c const uint32_t* firstDirtyNodeIndices = header->getFamilyGraph()->getFirstDirtyNodeIndices(); if (!isInvalidIndex(firstDirtyNodeIndices[thisActorIndex])) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: instance graph has dirty nodes. Call Nv::Blast::Actor::findIslands before serializing."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: instance graph has dirty nodes. Call Nv::Blast::Actor::findIslands before serializing."); return 0; } } @@ -274,12 +291,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c offset = align16(offset + m_visibleChunkCount*sizeof(uint32_t)); if (offset > bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } uint32_t* serVisibleChunkIndices = serHeader->getVisibleChunkIndices(); uint32_t serVisibleChunkCount = 0; - for (Nv::Blast::Actor::VisibleChunkIt i = *this; (bool)i; ++i) + for (Actor::VisibleChunkIt i = *this; (bool)i; ++i) { NVBLAST_ASSERT(serVisibleChunkCount < m_visibleChunkCount); serVisibleChunkIndices[serVisibleChunkCount++] = (uint32_t)i; @@ -293,12 +310,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c offset = align16(offset + m_graphNodeCount*sizeof(uint32_t)); if (offset > bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } uint32_t* serGraphNodeIndices = serHeader->getGraphNodeIndices(); uint32_t serGraphNodeCount = 0; - for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i) + for (Actor::GraphNodeIt i = *this; (bool)i; ++i) { NVBLAST_ASSERT(serGraphNodeCount < m_graphNodeCount); serGraphNodeIndices[serGraphNodeCount++] = (uint32_t)i; @@ -316,7 +333,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c { uint32_t serLowerSupportChunkCount = 0; const float* graphNodeHealths = header->getLowerSupportChunkHealths(); - for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i) + for (Actor::GraphNodeIt i = *this; (bool)i; ++i) { const uint32_t graphNodeIndex = (uint32_t)i; serLowerSupportChunkHealths[serLowerSupportChunkCount++] = graphNodeHealths[graphNodeIndex]; @@ -329,7 +346,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c { if (offset >= bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } serLowerSupportChunkHealths[serLowerSupportChunkCount++] = subsupportHealths[(uint32_t)j - subsupportChunkCount]; @@ -343,7 +360,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c NVBLAST_ASSERT(m_firstVisibleChunkIndex >= subsupportChunkCount); if (offset >= bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } *serLowerSupportChunkHealths = subsupportHealths[m_firstVisibleChunkIndex - subsupportChunkCount]; @@ -358,7 +375,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c serHeader->m_bondHealthsOffset = (uint32_t)offset; float* serBondHealths = serHeader->getBondHealths(); const float* bondHealths = header->getBondHealths(); - for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i) + for (Actor::GraphNodeIt i = *this; (bool)i; ++i) { const uint32_t graphNodeIndex = (uint32_t)i; for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex) @@ -372,7 +389,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c { if (offset >= bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } const uint32_t adjacentBondIndex = graphAdjacentBondIndices[adjacentIndex]; @@ -391,12 +408,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c offset = align16(offset + m_graphNodeCount*sizeof(uint32_t)); if (offset > bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } uint32_t* serFastRoute = serHeader->getFastRoute(); const uint32_t* fastRoute = header->getFamilyGraph()->getFastRoute(); - for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i) + for (Actor::GraphNodeIt i = *this; (bool)i; ++i) { *serFastRoute++ = fastRoute[(uint32_t)i]; } @@ -408,12 +425,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c offset = align16(offset + m_graphNodeCount*sizeof(uint32_t)); if (offset > bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } uint32_t* serHopCounts = serHeader->getHopCounts(); const uint32_t* hopCounts = header->getFamilyGraph()->getHopCounts(); - for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i) + for (Actor::GraphNodeIt i = *this; (bool)i; ++i) { *serHopCounts++ = hopCounts[(uint32_t)i]; } @@ -426,7 +443,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c offset = align16(offset + FixedBoolArray::requiredMemorySize(serBondCount)); if (offset > bufferSize) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded."); return 0; // Buffer size insufficient } uint32_t serBondIndex = 0; @@ -434,7 +451,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c new (serEdgeRemovedArray)FixedBoolArray(serBondCount); serEdgeRemovedArray->fill(); // Reset bits as we find bonds const FixedBoolArray* edgeRemovedArray = header->getFamilyGraph()->getIsEdgeRemoved(); - for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i) + for (Actor::GraphNodeIt i = *this; (bool)i; ++i) { const uint32_t graphNodeIndex = (uint32_t)i; for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex) @@ -468,7 +485,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c uint32_t Actor::serializationRequiredStorage(NvBlastLog logFn) const { const Asset* asset = getAsset(); - const Nv::Blast::SupportGraph& graph = asset->m_graph; + const SupportGraph& graph = asset->m_graph; const uint32_t* graphChunkIndices = graph.getChunkIndices(); const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices(); @@ -515,7 +532,7 @@ uint32_t Actor::serializationRequiredStorage(NvBlastLog logFn) const if (dataSize > UINT32_MAX) { - NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::serializationRequiredStorage: Serialization block size exceeds 4GB. Returning 0.\n"); + NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::serializationRequiredStorage: Serialization block size exceeds 4GB. Returning 0.\n"); return 0; } @@ -533,13 +550,13 @@ extern "C" uint32_t NvBlastActorGetSerializationSize(const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetSerializationSize: NULL actor pointer input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetSerializationSize: NULL actor pointer input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetSerializationSize: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetSerializationSize: inactive actor pointer input."); return 0; } @@ -549,14 +566,14 @@ uint32_t NvBlastActorGetSerializationSize(const NvBlastActor* actor, NvBlastLog uint32_t NvBlastActorSerialize(void* buffer, uint32_t bufferSize, const NvBlastActor* actor, NvBlastLog logFn) { - NVBLAST_CHECK(buffer != nullptr, logFn, "NvBlastActorSerialize: NULL buffer pointer input.", return 0); - NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorSerialize: NULL actor pointer input.", return 0); + NVBLASTLL_CHECK(buffer != nullptr, logFn, "NvBlastActorSerialize: NULL buffer pointer input.", return 0); + NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorSerialize: NULL actor pointer input.", return 0); const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor); if (!a.isActive()) { - NVBLAST_LOG_ERROR(logFn, "NvBlastActorSerialize: inactive actor pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorSerialize: inactive actor pointer input."); return 0; } @@ -566,8 +583,8 @@ uint32_t NvBlastActorSerialize(void* buffer, uint32_t bufferSize, const NvBlastA NvBlastActor* NvBlastFamilyDeserializeActor(NvBlastFamily* family, const void* buffer, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL family input. No actor deserialized.", return nullptr); - NVBLAST_CHECK(buffer != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL buffer pointer input. No actor deserialized.", return nullptr); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL family input. No actor deserialized.", return nullptr); + NVBLASTLL_CHECK(buffer != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL buffer pointer input. No actor deserialized.", return nullptr); return Nv::Blast::Actor::deserialize(family, buffer, logFn); } diff --git a/sdk/lowlevel/source/NvBlastActorSerializationBlock.h b/sdk/lowlevel/source/NvBlastActorSerializationBlock.h index 1388a74..95e9842 100644 --- a/sdk/lowlevel/source/NvBlastActorSerializationBlock.h +++ b/sdk/lowlevel/source/NvBlastActorSerializationBlock.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 NVBLASTACTORSERIALIZATIONBLOCK_H #define NVBLASTACTORSERIALIZATIONBLOCK_H diff --git a/sdk/lowlevel/source/NvBlastAsset.cpp b/sdk/lowlevel/source/NvBlastAsset.cpp index 29fc6b0..354a3ac 100644 --- a/sdk/lowlevel/source/NvBlastAsset.cpp +++ b/sdk/lowlevel/source/NvBlastAsset.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 "NvBlastAssert.h" #include "NvBlastAsset.h" @@ -36,37 +54,37 @@ static bool solverAssetBuildValidateInput(void* mem, const NvBlastAssetDesc* des { if (mem == nullptr) { - NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL mem pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL mem pointer input."); return false; } if (desc == nullptr) { - NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL desc pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL desc pointer input."); return false; } if (desc->chunkCount == 0) { - NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: Zero chunk count not allowed."); + NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: Zero chunk count not allowed."); return false; } if (desc->chunkDescs == nullptr) { - NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL chunkDescs pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL chunkDescs pointer input."); return false; } if (desc->bondCount != 0 && desc->bondDescs == nullptr) { - NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: bondCount non-zero but NULL bondDescs pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: bondCount non-zero but NULL bondDescs pointer input."); return false; } if (scratch == nullptr) { - NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL scratch pointer input."); + NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL scratch pointer input."); return false; } @@ -111,7 +129,7 @@ Asset* initializeAsset(void* mem, NvBlastID id, uint32_t chunkCount, uint32_t gr // Restricting our data size to < 4GB so that we may use uint32_t offsets if (dataSize > (size_t)UINT32_MAX) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::allocateAsset: Asset data size will exceed 4GB. Instance not created.\n"); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::allocateAsset: Asset data size will exceed 4GB. Instance not created.\n"); return nullptr; } @@ -121,7 +139,7 @@ Asset* initializeAsset(void* mem, NvBlastID id, uint32_t chunkCount, uint32_t gr // Fill in fields const size_t graphOffset = NV_OFFSET_OF(Asset, m_graph); asset->m_header.dataType = NvBlastDataBlock::AssetDataBlock; - asset->m_header.formatVersion = NvBlastAssetDataFormat::Current; + asset->m_header.formatVersion = 0; // Not currently using this field asset->m_header.size = (uint32_t)dataSize; asset->m_header.reserved = 0; asset->m_ID = id; @@ -223,7 +241,7 @@ static bool testForValidTrees(uint32_t chunkCount, const NvBlastChunkDesc* chunk // Ensure there are no loops if (testForLoop(chunkDescs, i)) { - NVBLAST_LOG_WARNING(logFn, "testForValidTrees: loop found. Asset will not be created."); + NVBLASTLL_LOG_WARNING(logFn, "testForValidTrees: loop found. Asset will not be created."); return false; } } @@ -255,7 +273,7 @@ class BondsOrdered public: bool operator () (const BondSortData& bond0, const BondSortData& bond1) const { - return (bond0.m_c0 != bond1.m_c0) ? (bond0.m_c0 < bond1.m_c0) : (bond0.m_c1 < bond1.m_c1); + return (bond0.m_c0 != bond1.m_c0) ? (bond0.m_c0 < bond1.m_c0) : (bond0.m_c1 != bond1.m_c1 ? bond0.m_c1 < bond1.m_c1 : bond0.m_b < bond1.m_b); } }; @@ -273,6 +291,19 @@ size_t Asset::getMemorySize(const NvBlastAssetDesc* desc) graphNodeCount += (uint32_t)((desc->chunkDescs[i].flags & NvBlastChunkDesc::SupportFlag) != 0); } + for (uint32_t i = 0; i < desc->bondCount; ++i) + { + const NvBlastBondDesc& bondDesc = desc->bondDescs[i]; + const uint32_t chunkIndex0 = bondDesc.chunkIndices[0]; + const uint32_t chunkIndex1 = bondDesc.chunkIndices[1]; + if ((isInvalidIndex(chunkIndex0) && chunkIndex1 < desc->chunkCount) || + (isInvalidIndex(chunkIndex1) && chunkIndex0 < desc->chunkCount)) + { + ++graphNodeCount; // world node + break; + } + } + AssetDataOffsets offsets; return createAssetDataOffsets(offsets, desc->chunkCount, graphNodeCount, desc->bondCount); } @@ -280,7 +311,7 @@ size_t Asset::getMemorySize(const NvBlastAssetDesc* desc) size_t Asset::createRequiredScratch(const NvBlastAssetDesc* desc) { -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS if (desc == nullptr) { NVBLAST_ALWAYS_ASSERT(); @@ -292,14 +323,14 @@ size_t Asset::createRequiredScratch(const NvBlastAssetDesc* desc) return 16 + align16(desc->chunkCount*sizeof(char)) + align16(desc->chunkCount*sizeof(uint32_t)) + - align16(2 * desc->bondCount*sizeof(Nv::Blast::BondSortData)) + + align16(2 * desc->bondCount*sizeof(BondSortData)) + align16(desc->bondCount*sizeof(uint32_t)); } Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvBlastLog logFn) { -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS if (!solverAssetBuildValidateInput(mem, desc, scratch, logFn)) { return nullptr; @@ -308,7 +339,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB NV_UNUSED(solverAssetBuildValidateInput); #endif - NVBLAST_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "NvBlastCreateAsset: mem pointer not 16-byte aligned.", return nullptr); + NVBLASTLL_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "NvBlastCreateAsset: mem pointer not 16-byte aligned.", return nullptr); // Make sure we have valid trees before proceeding if (!testForValidTrees(desc->chunkCount, desc->chunkDescs, logFn)) @@ -319,20 +350,21 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB scratch = (void*)align16((size_t)scratch); // Bump to 16-byte alignment (see padding in NvBlastGetRequiredScratchForCreateAsset) // reserve chunkAnnotation on scratch - char* chunkAnnotation = reinterpret_cast<char*>(scratch); scratch = Nv::Blast::pointerOffset(scratch, align16(desc->chunkCount)); + char* chunkAnnotation = reinterpret_cast<char*>(scratch); scratch = pointerOffset(scratch, align16(desc->chunkCount)); // test for coverage, chunkAnnotation will be filled there. uint32_t leafChunkCount; uint32_t supportChunkCount; if (!ensureExactSupportCoverage(supportChunkCount, leafChunkCount, chunkAnnotation, desc->chunkCount, const_cast<NvBlastChunkDesc*>(desc->chunkDescs), true, logFn)) { + NVBLASTLL_LOG_ERROR(logFn, "NvBlastCreateAsset: support coverage is not exact. Asset will not be created. The Asset helper function NvBlastEnsureAssetExactSupportCoverage may be used to create exact coverage."); return nullptr; } // test for valid chunk order if (!testForValidChunkOrder(desc->chunkCount, desc->chunkDescs, chunkAnnotation, scratch)) { - NVBLAST_LOG_ERROR(logFn, "NvBlastCreateAsset: chunks order is invalid. Asset will not be created. Use Asset helper functions such as NvBlastBuildAssetDescChunkReorderMap to fix descriptor order."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastCreateAsset: chunks order is invalid. Asset will not be created. Use Asset helper functions such as NvBlastBuildAssetDescChunkReorderMap to fix descriptor order."); return nullptr; } @@ -348,7 +380,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB } // Create map from global indices to graph node indices and initialize to invalid values - uint32_t* graphNodeIndexMap = (uint32_t*)scratch; scratch = Nv::Blast::pointerOffset(scratch, align16(desc->chunkCount * sizeof(uint32_t))); + uint32_t* graphNodeIndexMap = (uint32_t*)scratch; scratch = pointerOffset(scratch, align16(desc->chunkCount * sizeof(uint32_t))); memset(graphNodeIndexMap, 0xFF, desc->chunkCount*sizeof(uint32_t)); // Fill graphNodeIndexMap @@ -363,7 +395,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB NVBLAST_ASSERT(graphNodeCount == supportChunkCount); // Scratch array for bond sorting, of size 2*desc->bondCount - Nv::Blast::BondSortData* bondSortArray = (Nv::Blast::BondSortData*)scratch; scratch = Nv::Blast::pointerOffset(scratch, align16(2 * desc->bondCount*sizeof(Nv::Blast::BondSortData))); + BondSortData* bondSortArray = (BondSortData*)scratch; scratch = pointerOffset(scratch, align16(2 * desc->bondCount*sizeof(BondSortData))); // Bond remapping array of size desc->bondCount uint32_t* bondMap = (uint32_t*)scratch; @@ -380,33 +412,56 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB // Construct temp array of chunk index pairs and bond indices. This array is symmetrized to hold the reversed chunk indices as well. uint32_t bondSortArraySize = 0; - Nv::Blast::BondSortData* t = bondSortArray; + BondSortData* t = bondSortArray; + bool addWorldNode = false; for (uint32_t i = 0; i < desc->bondCount; ++i) { const NvBlastBondDesc& bondDesc = desc->bondDescs[i]; const uint32_t chunkIndex0 = bondDesc.chunkIndices[0]; const uint32_t chunkIndex1 = bondDesc.chunkIndices[1]; - if (chunkIndex0 >= desc->chunkCount || chunkIndex1 >= desc->chunkCount || chunkIndex0 == chunkIndex1) + if ((chunkIndex0 >= desc->chunkCount && !isInvalidIndex(chunkIndex0)) || + (chunkIndex1 >= desc->chunkCount && !isInvalidIndex(chunkIndex1)) || + chunkIndex0 == chunkIndex1) { invalidFound = true; continue; } - const uint32_t graphIndex0 = graphNodeIndexMap[chunkIndex0]; - const uint32_t graphIndex1 = graphNodeIndexMap[chunkIndex1]; - if (Nv::Blast::isInvalidIndex(graphIndex0) || Nv::Blast::isInvalidIndex(graphIndex1)) + uint32_t graphIndex0; + if (!isInvalidIndex(chunkIndex0)) + { + graphIndex0 = graphNodeIndexMap[chunkIndex0]; + } + else + { + addWorldNode = true; + graphIndex0 = graphNodeCount; // Will set graphNodeCount = supportChunkCount + 1 + } + + uint32_t graphIndex1; + if (!isInvalidIndex(chunkIndex1)) + { + graphIndex1 = graphNodeIndexMap[chunkIndex1]; + } + else + { + addWorldNode = true; + graphIndex1 = graphNodeCount; // Will set graphNodeCount = supportChunkCount + 1 + } + + if (isInvalidIndex(graphIndex0) || isInvalidIndex(graphIndex1)) { nonSupportFound = true; continue; } - t[bondSortArraySize++] = Nv::Blast::BondSortData(graphIndex0, graphIndex1, i); - t[bondSortArraySize++] = Nv::Blast::BondSortData(graphIndex1, graphIndex0, i); + t[bondSortArraySize++] = BondSortData(graphIndex0, graphIndex1, i); + t[bondSortArraySize++] = BondSortData(graphIndex1, graphIndex0, i); } // Sort the temp array - std::sort(bondSortArray, bondSortArray + bondSortArraySize, Nv::Blast::BondsOrdered()); + std::sort(bondSortArray, bondSortArray + bondSortArraySize, BondsOrdered()); uint32_t symmetrizedBondCount = 0; for (uint32_t i = 0; i < bondSortArraySize; ++i) @@ -426,48 +481,55 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB bondCount = symmetrizedBondCount / 2; + // World node references found in bonds; add a world node + if (addWorldNode) + { + ++graphNodeCount; + } + // Report warnings if (invalidFound) { - NVBLAST_LOG_WARNING(logFn, "NvBlastCreateAsset: Invalid bonds found (non-existent or same chunks referenced) and removed from asset."); + NVBLASTLL_LOG_WARNING(logFn, "NvBlastCreateAsset: Invalid bonds found (non-existent or same chunks referenced) and removed from asset."); } if (duplicateFound) { - NVBLAST_LOG_WARNING(logFn, "NvBlastCreateAsset: Duplicate bonds found and removed from asset."); + NVBLASTLL_LOG_WARNING(logFn, "NvBlastCreateAsset: Duplicate bonds found and removed from asset."); } if (nonSupportFound) { - NVBLAST_LOG_WARNING(logFn, "NvBlastCreateAsset: Bonds referencing non-support chunks found and removed from asset."); + NVBLASTLL_LOG_WARNING(logFn, "NvBlastCreateAsset: Bonds referencing non-support chunks found and removed from asset."); } } // Allocate memory for asset NvBlastID id; memset(&id, 0, sizeof(NvBlastID)); // To do - create an actual id - Nv::Blast::Asset* asset = initializeAsset(mem, id, desc->chunkCount, supportChunkCount, leafChunkCount, firstSubsupportChunkIndex, bondCount, logFn); + Asset* asset = initializeAsset(mem, id, desc->chunkCount, graphNodeCount, leafChunkCount, firstSubsupportChunkIndex, bondCount, logFn); // Asset data pointers - Nv::Blast::SupportGraph& graph = asset->m_graph; + SupportGraph& graph = asset->m_graph; NvBlastChunk* chunks = asset->getChunks(); NvBlastBond* bonds = asset->getBonds(); uint32_t* subtreeLeafChunkCounts = asset->getSubtreeLeafChunkCounts(); // Create chunks uint32_t* graphChunkIndices = graph.getChunkIndices(); + memset(graphChunkIndices, 0xFF, graphNodeCount * sizeof(uint32_t)); // Ensures unmapped node indices go to invalidIndex - this is important for the world node, if added for (uint32_t i = 0; i < desc->chunkCount; ++i) { const NvBlastChunkDesc& chunkDesc = desc->chunkDescs[i]; - const uint32_t newChunkIndex = i; - NvBlastChunk& assetChunk = chunks[newChunkIndex]; + NvBlastChunk& assetChunk = chunks[i]; memcpy(assetChunk.centroid, chunkDesc.centroid, 3 * sizeof(float)); assetChunk.volume = chunkDesc.volume; - assetChunk.parentChunkIndex = Nv::Blast::isInvalidIndex(chunkDesc.parentChunkIndex) ? chunkDesc.parentChunkIndex : chunkDesc.parentChunkIndex; - assetChunk.firstChildIndex = Nv::Blast::invalidIndex<uint32_t>(); // Will be filled in below + assetChunk.parentChunkIndex = isInvalidIndex(chunkDesc.parentChunkIndex) ? chunkDesc.parentChunkIndex : chunkDesc.parentChunkIndex; + assetChunk.firstChildIndex = invalidIndex<uint32_t>(); // Will be filled in below assetChunk.childIndexStop = assetChunk.firstChildIndex; assetChunk.userData = chunkDesc.userData; - if (!Nv::Blast::isInvalidIndex(graphNodeIndexMap[newChunkIndex])) + const uint32_t graphNodeIndex = graphNodeIndexMap[i]; + if (!isInvalidIndex(graphNodeIndex)) { - graphChunkIndices[graphNodeIndexMap[newChunkIndex]] = newChunkIndex; + graphChunkIndices[graphNodeIndex] = i; } } @@ -478,7 +540,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB for (uint32_t i = 0; i < desc->chunkCount; ++i) { const uint32_t parentChunkIndex = chunks[i].parentChunkIndex; - if (!Nv::Blast::isInvalidIndex(parentChunkIndex)) + if (!isInvalidIndex(parentChunkIndex)) { if (chunks[parentChunkIndex].childIndexStop == chunks[parentChunkIndex].firstChildIndex) { @@ -495,32 +557,22 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB if (bondCount > 0) { // Create the lookup table from the sorted array - Nv::Blast::createIndexStartLookup<uint32_t>(graphAdjacencyPartition, 0, graphNodeCount - 1, &bondSortArray->m_c0, 2 * bondCount, sizeof(Nv::Blast::BondSortData)); + createIndexStartLookup<uint32_t>(graphAdjacencyPartition, 0, graphNodeCount - 1, &bondSortArray->m_c0, 2 * bondCount, sizeof(BondSortData)); // Write the adjacent chunk and bond index data uint32_t bondIndex = 0; for (uint32_t i = 0; i < 2 * bondCount; ++i) { - const Nv::Blast::BondSortData& bondSortData = bondSortArray[i]; + const BondSortData& bondSortData = bondSortArray[i]; graphAdjacentNodeIndices[i] = bondSortData.m_c1; const uint32_t oldBondIndex = bondSortData.m_b; const NvBlastBondDesc& bondDesc = desc->bondDescs[oldBondIndex]; - if (Nv::Blast::isInvalidIndex(bondMap[oldBondIndex])) + if (isInvalidIndex(bondMap[oldBondIndex])) { bonds[bondIndex] = bondDesc.bond; - // Our convention is that the bond normal points away from the lower-indexed chunk, towards the higher-indexed chunk. - // If our new (graph node) indexing would reverse this direction from the bond descriptor's indexing, we must flip the nomral. - const bool nodeIndicesOrdered = bondSortData.m_c0 < bondSortData.m_c1; - const bool descNodeIndicesOrdered = bondDesc.chunkIndices[0] < bondDesc.chunkIndices[1]; - if (descNodeIndicesOrdered && !nodeIndicesOrdered) - { - float* normal = bonds[bondIndex].normal; - normal[0] = -normal[0]; - normal[1] = -normal[1]; - normal[2] = -normal[2]; - } bondMap[oldBondIndex] = bondIndex++; } + NVBLAST_ASSERT(bondMap[oldBondIndex] < bondCount); graphAdjacentBondIndices[i] = bondMap[oldBondIndex]; } } @@ -535,7 +587,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB uint32_t* breadthFirstChunkIndices = graphNodeIndexMap; // Reusing graphNodeIndexMap ... graphNodeIndexMap may no longer be used for (uint32_t startChunkIndex = 0; startChunkIndex < desc->chunkCount; ++startChunkIndex) { - if (!Nv::Blast::isInvalidIndex(chunks[startChunkIndex].parentChunkIndex)) + if (!isInvalidIndex(chunks[startChunkIndex].parentChunkIndex)) { break; // Only iterate through root chunks at this level } @@ -637,7 +689,7 @@ bool Asset::ensureExactSupportCoverage(uint32_t& supportChunkCount, uint32_t& le if (redundantCoverage) { - NVBLAST_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had more than one support chunk. Some support chunks removed."); + NVBLASTLL_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had more than one support chunk. Some support chunks removed."); } if (insufficientCoverage) @@ -698,7 +750,7 @@ bool Asset::ensureExactSupportCoverage(uint32_t& supportChunkCount, uint32_t& le } } - NVBLAST_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had no support chunks. Support chunks added."); + NVBLASTLL_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had no support chunks. Support chunks added."); } // Apply changes and count the number of support chunks @@ -731,12 +783,12 @@ bool Asset::testForValidChunkOrder(uint32_t chunkCount, const NvBlastChunkDesc* const uint32_t parentChunkIndex = chunkDescs[i].parentChunkIndex; if (parentChunkIndex != currentParentChunkIndex) { - if (!Nv::Blast::isInvalidIndex(currentParentChunkIndex)) + if (!isInvalidIndex(currentParentChunkIndex)) { chunkMarks[currentParentChunkIndex] = 1; } currentParentChunkIndex = parentChunkIndex; - if (Nv::Blast::isInvalidIndex(currentParentChunkIndex)) + if (isInvalidIndex(currentParentChunkIndex)) { return false; } @@ -772,7 +824,7 @@ extern "C" size_t NvBlastGetRequiredScratchForCreateAsset(const NvBlastAssetDesc* desc, NvBlastLog logFn) { - NVBLAST_CHECK(desc != nullptr, logFn, "NvBlastGetRequiredScratchForCreateAsset: NULL desc pointer input.", return 0); + NVBLASTLL_CHECK(desc != nullptr, logFn, "NvBlastGetRequiredScratchForCreateAsset: NULL desc pointer input.", return 0); return Nv::Blast::Asset::createRequiredScratch(desc); } @@ -780,7 +832,7 @@ size_t NvBlastGetRequiredScratchForCreateAsset(const NvBlastAssetDesc* desc, NvB size_t NvBlastGetAssetMemorySize(const NvBlastAssetDesc* desc, NvBlastLog logFn) { - NVBLAST_CHECK(desc != nullptr, logFn, "NvBlastGetAssetMemorySize: NULL desc input.", return 0); + NVBLASTLL_CHECK(desc != nullptr, logFn, "NvBlastGetAssetMemorySize: NULL desc input.", return 0); return Nv::Blast::Asset::getMemorySize(desc); } @@ -794,7 +846,7 @@ NvBlastAsset* NvBlastCreateAsset(void* mem, const NvBlastAssetDesc* desc, void* size_t NvBlastAssetGetFamilyMemorySize(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFamilyMemorySize: NULL asset pointer input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFamilyMemorySize: NULL asset pointer input.", return 0); return Nv::Blast::getFamilyMemorySize(reinterpret_cast<const Nv::Blast::Asset*>(asset)); } @@ -802,7 +854,7 @@ size_t NvBlastAssetGetFamilyMemorySize(const NvBlastAsset* asset, NvBlastLog log NvBlastID NvBlastAssetGetID(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetID: NULL asset pointer input.", NvBlastID zero; memset(&zero, 0, sizeof(NvBlastID)); return zero); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetID: NULL asset pointer input.", NvBlastID zero; memset(&zero, 0, sizeof(NvBlastID)); return zero); return ((Nv::Blast::Asset*)asset)->m_ID; } @@ -810,8 +862,8 @@ NvBlastID NvBlastAssetGetID(const NvBlastAsset* asset, NvBlastLog logFn) bool NvBlastAssetSetID(NvBlastAsset* asset, const NvBlastID* id, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetSetID: NULL asset pointer input.", return false); - NVBLAST_CHECK(id != nullptr, logFn, "NvBlastAssetSetID: NULL id pointer input.", return false); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetSetID: NULL asset pointer input.", return false); + NVBLASTLL_CHECK(id != nullptr, logFn, "NvBlastAssetSetID: NULL id pointer input.", return false); ((Nv::Blast::Asset*)asset)->m_ID = *id; @@ -821,7 +873,7 @@ bool NvBlastAssetSetID(NvBlastAsset* asset, const NvBlastID* id, NvBlastLog logF uint32_t NvBlastAssetGetFormatVersion(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFormatVersion: NULL asset input.", return UINT32_MAX); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFormatVersion: NULL asset input.", return UINT32_MAX); return ((Nv::Blast::Asset*)asset)->m_header.formatVersion; } @@ -829,7 +881,7 @@ uint32_t NvBlastAssetGetFormatVersion(const NvBlastAsset* asset, NvBlastLog logF uint32_t NvBlastAssetGetSize(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSize: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSize: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->m_header.size; } @@ -837,15 +889,31 @@ uint32_t NvBlastAssetGetSize(const NvBlastAsset* asset, NvBlastLog logFn) uint32_t NvBlastAssetGetChunkCount(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkCount: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkCount: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->m_chunkCount; } +uint32_t NvBlastAssetGetSupportChunkCount(const NvBlastAsset* asset, NvBlastLog logFn) +{ + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSupportChunkCount: NULL asset input.", return 0); + + const Nv::Blast::Asset* a = reinterpret_cast<const Nv::Blast::Asset*>(asset); + const Nv::Blast::SupportGraph& graph = a->m_graph; + + if (graph.m_nodeCount == 0) + { + return 0; // This shouldn't happen + } + + return Nv::Blast::isInvalidIndex(graph.getChunkIndices()[graph.m_nodeCount - 1]) ? graph.m_nodeCount - 1 : graph.m_nodeCount; +} + + uint32_t NvBlastAssetGetLeafChunkCount(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetLeafChunkCount: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetLeafChunkCount: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->m_leafChunkCount; } @@ -853,7 +921,7 @@ uint32_t NvBlastAssetGetLeafChunkCount(const NvBlastAsset* asset, NvBlastLog log uint32_t NvBlastAssetGetFirstSubsupportChunkIndex(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFirstSubsupportChunkIndex: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFirstSubsupportChunkIndex: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->m_firstSubsupportChunkIndex; } @@ -861,7 +929,7 @@ uint32_t NvBlastAssetGetFirstSubsupportChunkIndex(const NvBlastAsset* asset, NvB uint32_t NvBlastAssetGetBondCount(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBondCount: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBondCount: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->m_bondCount; } @@ -869,7 +937,7 @@ uint32_t NvBlastAssetGetBondCount(const NvBlastAsset* asset, NvBlastLog logFn) const NvBlastSupportGraph NvBlastAssetGetSupportGraph(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSupportGraph: NULL asset input.", + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSupportGraph: NULL asset input.", NvBlastSupportGraph blank; blank.nodeCount = 0; blank.chunkIndices = blank.adjacencyPartition = blank.adjacentNodeIndices = blank.adjacentBondIndices = nullptr; return blank); const Nv::Blast::SupportGraph& supportGraph = static_cast<const Nv::Blast::Asset*>(asset)->m_graph; @@ -887,7 +955,7 @@ const NvBlastSupportGraph NvBlastAssetGetSupportGraph(const NvBlastAsset* asset, const uint32_t* NvBlastAssetGetChunkToGraphNodeMap(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkToGraphNodeMap: NULL asset input.", return nullptr); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkToGraphNodeMap: NULL asset input.", return nullptr); return static_cast<const Nv::Blast::Asset*>(asset)->getChunkToGraphNodeMap(); } @@ -895,7 +963,7 @@ const uint32_t* NvBlastAssetGetChunkToGraphNodeMap(const NvBlastAsset* asset, Nv const NvBlastChunk* NvBlastAssetGetChunks(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunks: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunks: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->getChunks(); } @@ -903,7 +971,7 @@ const NvBlastChunk* NvBlastAssetGetChunks(const NvBlastAsset* asset, NvBlastLog const NvBlastBond* NvBlastAssetGetBonds(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBonds: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBonds: NULL asset input.", return 0); return ((Nv::Blast::Asset*)asset)->getBonds(); } @@ -911,7 +979,7 @@ const NvBlastBond* NvBlastAssetGetBonds(const NvBlastAsset* asset, NvBlastLog lo uint32_t NvBlastAssetGetActorSerializationSizeUpperBound(const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: NULL asset input.", return 0); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: NULL asset input.", return 0); const Nv::Blast::Asset& solverAsset = *(const Nv::Blast::Asset*)asset; const uint32_t graphNodeCount = solverAsset.m_graph.m_nodeCount; @@ -921,7 +989,7 @@ uint32_t NvBlastAssetGetActorSerializationSizeUpperBound(const NvBlastAsset* ass if (upperBound > UINT32_MAX) { - NVBLAST_LOG_WARNING(logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: Serialization block size exceeds 4GB. Returning 0.\n"); + NVBLASTLL_LOG_WARNING(logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: Serialization block size exceeds 4GB. Returning 0.\n"); return 0; } diff --git a/sdk/lowlevel/source/NvBlastAsset.h b/sdk/lowlevel/source/NvBlastAsset.h index 30e8161..65f8b43 100644 --- a/sdk/lowlevel/source/NvBlastAsset.h +++ b/sdk/lowlevel/source/NvBlastAsset.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 NVBLASTASSET_H #define NVBLASTASSET_H diff --git a/sdk/lowlevel/source/NvBlastAssetHelper.cpp b/sdk/lowlevel/source/NvBlastAssetHelper.cpp index 0d6c5d2..cc3d643 100644 --- a/sdk/lowlevel/source/NvBlastAssetHelper.cpp +++ b/sdk/lowlevel/source/NvBlastAssetHelper.cpp @@ -1,17 +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. + #include "NvBlastAsset.h" #include "NvBlastIndexFns.h" #include "NvBlastAssert.h" #include "NvBlastMemory.h" +#include "NvBlastMath.h" +#include "NvBlastPreprocessorInternal.h" #include <algorithm> @@ -62,9 +82,9 @@ extern "C" bool NvBlastBuildAssetDescChunkReorderMap(uint32_t* chunkReorderMap, const NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, void* scratch, NvBlastLog logFn) { - NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return false); - NVBLAST_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return false); - NVBLAST_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL scratch input with non-zero chunkCount", return false); + NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return false); + NVBLASTLL_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return false); + NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL scratch input with non-zero chunkCount", return false); uint32_t* chunkMap = static_cast<uint32_t*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(uint32_t)); char* chunkAnnotation = static_cast<char*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(char)); @@ -73,7 +93,7 @@ bool NvBlastBuildAssetDescChunkReorderMap(uint32_t* chunkReorderMap, const NvBla uint32_t leafChunkCount; if (!Asset::ensureExactSupportCoverage(supportChunkCount, leafChunkCount, chunkAnnotation, chunkCount, const_cast<NvBlastChunkDesc*>(chunkDescs), true, logFn)) { - NVBLAST_LOG_ERROR(logFn, "NvBlastBuildAssetDescChunkReorderMap: chunk descriptors did not have exact coverage, map could not be built. Use NvBlastEnsureAssetExactSupportCoverage to fix descriptors."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastBuildAssetDescChunkReorderMap: chunk descriptors did not have exact coverage, map could not be built. Use NvBlastEnsureAssetExactSupportCoverage to fix descriptors."); return false; } @@ -108,14 +128,15 @@ void NvBlastApplyAssetDescChunkReorderMap NvBlastBondDesc* bondDescs, uint32_t bondCount, const uint32_t* chunkReorderMap, + bool keepBondNormalChunkOrder, NvBlastLog logFn ) { - NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return); - NVBLAST_CHECK(reorderedChunkDescs == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL reorderedChunkDescs input with non-zero chunkCount", return); - NVBLAST_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return); - NVBLAST_CHECK(bondCount == 0 || bondDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with non-zero bondCount", return); - NVBLAST_CHECK(bondDescs == nullptr || chunkReorderMap != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with NULL chunkReorderMap", return); + NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return); + NVBLASTLL_CHECK(reorderedChunkDescs == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL reorderedChunkDescs input with non-zero chunkCount", return); + NVBLASTLL_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return); + NVBLASTLL_CHECK(bondCount == 0 || bondDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with non-zero bondCount", return); + NVBLASTLL_CHECK(bondDescs == nullptr || chunkReorderMap != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with NULL chunkReorderMap", return); // Copy chunk descs if (reorderedChunkDescs) @@ -135,35 +156,58 @@ void NvBlastApplyAssetDescChunkReorderMap { for (uint32_t i = 0; i < bondCount; ++i) { - for (int j = 0; j < 2; ++j) + NvBlastBondDesc& bondDesc = bondDescs[i]; + uint32_t& index0 = bondDesc.chunkIndices[0]; + uint32_t& index1 = bondDesc.chunkIndices[1]; + const uint32_t newIndex0 = index0 < chunkCount ? chunkReorderMap[index0] : index0; + const uint32_t newIndex1 = index1 < chunkCount ? chunkReorderMap[index1] : index1; + if (keepBondNormalChunkOrder && (index0 < index1) != (newIndex0 < newIndex1)) { - uint32_t& index = bondDescs[i].chunkIndices[j]; - if (index < chunkCount) - { - index = chunkReorderMap[index]; - } + VecMath::mul(bondDesc.bond.normal, -1); } + index0 = newIndex0; + index1 = newIndex1; } } } -void NvBlastApplyAssetDescChunkReorderMapInplace(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, const uint32_t* chunkReorderMap, void* scratch, NvBlastLog logFn) +void NvBlastApplyAssetDescChunkReorderMapInPlace +( + NvBlastChunkDesc* chunkDescs, + uint32_t chunkCount, + NvBlastBondDesc* bondDescs, + uint32_t bondCount, + const uint32_t* chunkReorderMap, + bool keepBondNormalChunkOrder, + void* scratch, + NvBlastLog logFn +) { - NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInplace: NULL chunkDescs input with non-zero chunkCount", return); - NVBLAST_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInplace: NULL scratch input with non-zero chunkCount", return); + NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInPlace: NULL chunkDescs input with non-zero chunkCount", return); + NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInPlace: NULL scratch input with non-zero chunkCount", return); NvBlastChunkDesc* chunksTemp = static_cast<NvBlastChunkDesc*>(scratch); memcpy(chunksTemp, chunkDescs, sizeof(NvBlastChunkDesc) * chunkCount); - NvBlastApplyAssetDescChunkReorderMap(chunkDescs, chunksTemp, chunkCount, bondDescs, bondCount, chunkReorderMap, logFn); + NvBlastApplyAssetDescChunkReorderMap(chunkDescs, chunksTemp, chunkCount, bondDescs, bondCount, chunkReorderMap, keepBondNormalChunkOrder, logFn); } -bool NvBlastReorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap, void* scratch, NvBlastLog logFn) +bool NvBlastReorderAssetDescChunks +( + NvBlastChunkDesc* chunkDescs, + uint32_t chunkCount, + NvBlastBondDesc* bondDescs, + uint32_t bondCount, + uint32_t* chunkReorderMap, + bool keepBondNormalChunkOrder, + void* scratch, + NvBlastLog logFn +) { if (!NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap, chunkDescs, chunkCount, scratch, logFn)) { - NvBlastApplyAssetDescChunkReorderMapInplace(chunkDescs, chunkCount, bondDescs, bondCount, chunkReorderMap, scratch, logFn); + NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDescs, chunkCount, bondDescs, bondCount, chunkReorderMap, keepBondNormalChunkOrder, scratch, logFn); return false; } return true; @@ -172,8 +216,8 @@ bool NvBlastReorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkC bool NvBlastEnsureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, void* scratch, NvBlastLog logFn) { - NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL chunkDescs input with non-zero chunkCount", return false); - NVBLAST_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL scratch input with non-zero chunkCount", return false); + NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL chunkDescs input with non-zero chunkCount", return false); + NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL scratch input with non-zero chunkCount", return false); uint32_t supportChunkCount; uint32_t leafChunkCount; diff --git a/sdk/lowlevel/source/NvBlastChunkHierarchy.h b/sdk/lowlevel/source/NvBlastChunkHierarchy.h index e7e05c6..52380e8 100644 --- a/sdk/lowlevel/source/NvBlastChunkHierarchy.h +++ b/sdk/lowlevel/source/NvBlastChunkHierarchy.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 NVBLASTCHUNKHIERARCHY_H #define NVBLASTCHUNKHIERARCHY_H diff --git a/sdk/lowlevel/source/NvBlastFamily.cpp b/sdk/lowlevel/source/NvBlastFamily.cpp index 1f517b1..b0888c6 100644 --- a/sdk/lowlevel/source/NvBlastFamily.cpp +++ b/sdk/lowlevel/source/NvBlastFamily.cpp @@ -1,17 +1,35 @@ -/* -* 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 "NvBlastFamily.h" #include "NvBlastFamilyGraph.h" #include "NvBlastIndexFns.h" +#include "NvBlastTime.h" #include <new> @@ -36,7 +54,7 @@ struct FamilyDataOffsets static size_t createFamilyDataOffsets(FamilyDataOffsets& offsets, const Asset* asset) { - const Nv::Blast::SupportGraph& graph = asset->m_graph; + const SupportGraph& graph = asset->m_graph; NvBlastCreateOffsetStart(sizeof(FamilyHeader)); NvBlastCreateOffsetAlign16(offsets.m_actors, asset->getLowerSupportChunkCount() * sizeof(Actor)); @@ -52,7 +70,7 @@ static size_t createFamilyDataOffsets(FamilyDataOffsets& offsets, const Asset* a size_t getFamilyMemorySize(const Asset* asset) { -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS if (asset == nullptr) { NVBLAST_ALWAYS_ASSERT(); @@ -67,20 +85,20 @@ size_t getFamilyMemorySize(const Asset* asset) NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(mem != nullptr, logFn, "createFamily: NULL mem pointer input.", return nullptr); - NVBLAST_CHECK(asset != nullptr, logFn, "createFamily: NULL asset pointer input.", return nullptr); + NVBLASTLL_CHECK(mem != nullptr, logFn, "createFamily: NULL mem pointer input.", return nullptr); + NVBLASTLL_CHECK(asset != nullptr, logFn, "createFamily: NULL asset pointer input.", return nullptr); - NVBLAST_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "createFamily: mem pointer not 16-byte aligned.", return nullptr); + NVBLASTLL_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "createFamily: mem pointer not 16-byte aligned.", return nullptr); const Asset& solverAsset = *static_cast<const Asset*>(asset); if (solverAsset.m_chunkCount == 0) { - NVBLAST_LOG_ERROR(logFn, "createFamily: Asset has no chunks. Family not created.\n"); + NVBLASTLL_LOG_ERROR(logFn, "createFamily: Asset has no chunks. Family not created.\n"); return nullptr; } - const Nv::Blast::SupportGraph& graph = solverAsset.m_graph; + const SupportGraph& graph = solverAsset.m_graph; const uint32_t bondCount = solverAsset.getBondCount(); @@ -97,7 +115,7 @@ NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog log // Restricting our data size to < 4GB so that we may use uint32_t offsets if (dataSize > (size_t)UINT32_MAX) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::instanceAllocate: Instance data block size will exceed 4GB. Instance not created.\n"); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::instanceAllocate: Instance data block size will exceed 4GB. Instance not created.\n"); return nullptr; } @@ -107,7 +125,7 @@ NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog log // Fill in family header FamilyHeader* header = (FamilyHeader*)family; header->dataType = NvBlastDataBlock::FamilyDataBlock; - header->formatVersion = NvBlastFamilyDataFormat::Current; + header->formatVersion = 0; // Not currently using this field header->size = (uint32_t)dataSize; header->m_assetID = solverAsset.m_ID; header->m_actorCount = 0; @@ -150,6 +168,417 @@ NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog log return family; } + +//////// Family member methods //////// + +void FamilyHeader::fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks) +{ + const NvBlastChunk& chunk = chunks[chunkIndex]; + uint32_t numChildren = chunk.childIndexStop - chunk.firstChildIndex; + + if (numChildren > 0) + { + healthDamage /= numChildren; + for (uint32_t childIndex = chunk.firstChildIndex; childIndex < chunk.childIndexStop; childIndex++) + { + float& health = chunkHealths[childIndex - suboffset]; + if (health > 0.0f) + { + float remainingDamage = healthDamage - health; + health -= healthDamage; + + NVBLAST_ASSERT(chunks[childIndex].parentChunkIndex == chunkIndex); + + if (health <= 0.0f && remainingDamage > 0.0f) + { + fractureSubSupportNoEvents(childIndex, suboffset, remainingDamage, chunkHealths, chunks); + } + } + } + } +} + + +void FamilyHeader::fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount) +{ + const NvBlastChunk& chunk = chunks[chunkIndex]; + uint32_t numChildren = chunk.childIndexStop - chunk.firstChildIndex; + + if (numChildren > 0) + { + healthDamage /= numChildren; + for (uint32_t childIndex = chunk.firstChildIndex; childIndex < chunk.childIndexStop; childIndex++) + { + float& health = chunkHealths[childIndex - suboffset]; + if (health > 0.0f) + { + float remainingDamage = healthDamage - health; + health -= healthDamage; + + NVBLAST_ASSERT(chunks[childIndex].parentChunkIndex == chunkIndex); + + if (*currentIndex < maxCount) + { + NvBlastChunkFractureData& event = outBuffer[*currentIndex]; + event.userdata = chunks[childIndex].userData; + event.chunkIndex = childIndex; + event.health = health; + } + (*currentIndex)++; + + if (health <= 0.0f && remainingDamage > 0.0f) + { + fractureSubSupport(childIndex, suboffset, remainingDamage, chunkHealths, chunks, outBuffer, currentIndex, maxCount); + } + } + } + } + +} + + +void FamilyHeader::fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures, Actor* filterActor, NvBlastLog logFn) +{ + const SupportGraph& graph = m_asset->m_graph; + const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); + const uint32_t* adjacentBondIndices = graph.getAdjacentBondIndices(); + float* bondHealths = getBondHealths(); + float* chunkHealths = getLowerSupportChunkHealths(); + float* subChunkHealths = getSubsupportChunkHealths(); + const NvBlastChunk* chunks = m_asset->getChunks(); + + for (uint32_t i = 0; i < chunkFractureCount; ++i) + { + const NvBlastChunkFractureData& command = chunkFractures[i]; + const uint32_t chunkIndex = command.chunkIndex; + const uint32_t chunkHealthIndex = m_asset->getContiguousLowerSupportIndex(chunkIndex); + NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); + if (isInvalidIndex(chunkHealthIndex)) + { + continue; + } + float& health = chunkHealths[chunkHealthIndex]; + if (health > 0.0f && command.health > 0.0f) + { + Actor* actor = getGetChunkActor(chunkIndex); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: chunk fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t nodeIndex = m_asset->getChunkToGraphNodeMap()[chunkIndex]; + if (actor->getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) + { + for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) + { + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); + if (bondHealths[bondIndex] > 0.0f) + { + bondHealths[bondIndex] = 0.0f; + } + } + getFamilyGraph()->notifyNodeRemoved(actor->getIndex(), nodeIndex, &graph); + } + + health -= command.health; + + const float remainingDamage = -health; + + if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health + { + fractureSubSupportNoEvents(chunkIndex, m_asset->m_firstSubsupportChunkIndex, remainingDamage, subChunkHealths, chunks); + } + } + } + } +} + + +void FamilyHeader::fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn) +{ + const SupportGraph& graph = m_asset->m_graph; + const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); + const uint32_t* adjacentBondIndices = graph.getAdjacentBondIndices(); + float* bondHealths = getBondHealths(); + float* chunkHealths = getLowerSupportChunkHealths(); + float* subChunkHealths = getSubsupportChunkHealths(); + const NvBlastChunk* chunks = m_asset->getChunks(); + + for (uint32_t i = 0; i < chunkFractureCount; ++i) + { + const NvBlastChunkFractureData& command = commands[i]; + const uint32_t chunkIndex = command.chunkIndex; + const uint32_t chunkHealthIndex = m_asset->getContiguousLowerSupportIndex(chunkIndex); + NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); + if (isInvalidIndex(chunkHealthIndex)) + { + continue; + } + float& health = chunkHealths[chunkHealthIndex]; + if (health > 0.0f && command.health > 0.0f) + { + Actor* actor = getGetChunkActor(chunkIndex); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: chunk fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t nodeIndex = m_asset->getChunkToGraphNodeMap()[chunkIndex]; + if (actor->getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) + { + for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) + { + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); + if (bondHealths[bondIndex] > 0.0f) + { + bondHealths[bondIndex] = 0.0f; + } + } + getFamilyGraph()->notifyNodeRemoved(actor->getIndex(), nodeIndex, &graph); + } + + health -= command.health; + + if (*count < eventsSize) + { + NvBlastChunkFractureData& outEvent = events[*count]; + outEvent.userdata = chunks[chunkIndex].userData; + outEvent.chunkIndex = chunkIndex; + outEvent.health = health; + } + (*count)++; + + const float remainingDamage = -health; + + if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health + { + fractureSubSupport(chunkIndex, m_asset->m_firstSubsupportChunkIndex, remainingDamage, subChunkHealths, chunks, events, count, eventsSize); + } + } + } + } +} + + +void FamilyHeader::fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn) +{ + const SupportGraph& graph = m_asset->m_graph; + const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); + const uint32_t* adjacentBondIndices = graph.getAdjacentBondIndices(); + float* bondHealths = getBondHealths(); + float* chunkHealths = getLowerSupportChunkHealths(); + float* subChunkHealths = getSubsupportChunkHealths(); + const NvBlastChunk* chunks = m_asset->getChunks(); + + // + // First level Chunk Fractures + // + + for (uint32_t i = 0; i < chunkFractureCount; ++i) + { + const NvBlastChunkFractureData& command = inoutbuffer[i]; + const uint32_t chunkIndex = command.chunkIndex; + const uint32_t chunkHealthIndex = m_asset->getContiguousLowerSupportIndex(chunkIndex); + NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); + if (isInvalidIndex(chunkHealthIndex)) + { + continue; + } + float& health = chunkHealths[chunkHealthIndex]; + if (health > 0.0f && command.health > 0.0f) + { + Actor* actor = getGetChunkActor(chunkIndex); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: chunk fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t nodeIndex = m_asset->getChunkToGraphNodeMap()[chunkIndex]; + if (actor->getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) + { + for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) + { + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); + if (bondHealths[bondIndex] > 0.0f) + { + bondHealths[bondIndex] = 0.0f; + } + } + getFamilyGraph()->notifyNodeRemoved(actor->getIndex(), nodeIndex, &graph); + } + + health -= command.health; + + NvBlastChunkFractureData& outEvent = inoutbuffer[(*count)++]; + outEvent.userdata = chunks[chunkIndex].userData; + outEvent.chunkIndex = chunkIndex; + outEvent.health = health; + } + } + } + + // + // Hierarchical Chunk Fractures + // + + uint32_t commandedChunkFractures = *count; + + for (uint32_t i = 0; i < commandedChunkFractures; ++i) + { + NvBlastChunkFractureData& event = inoutbuffer[i]; + const uint32_t chunkIndex = event.chunkIndex; + + const float remainingDamage = -event.health; + if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health + { + fractureSubSupport(chunkIndex, m_asset->m_firstSubsupportChunkIndex, remainingDamage, subChunkHealths, chunks, inoutbuffer, count, eventsSize); + } + } +} + + +void FamilyHeader::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, Actor* filterActor, NvBlastLog logFn, NvBlastTimers* timers) +{ + NVBLASTLL_CHECK(commands != nullptr, logFn, "NvBlastActorApplyFracture: NULL commands pointer input.", return); + NVBLASTLL_CHECK(isValid(commands), logFn, "NvBlastActorApplyFracture: commands memory is NULL but size is > 0.", return); + NVBLASTLL_CHECK(eventBuffers == nullptr || isValid(eventBuffers), logFn, "NvBlastActorApplyFracture: eventBuffers memory is NULL but size is > 0.", + eventBuffers->bondFractureCount = 0; eventBuffers->chunkFractureCount = 0; return); + +#if NVBLASTLL_CHECK_PARAMS + if (eventBuffers != nullptr && eventBuffers->bondFractureCount == 0 && eventBuffers->chunkFractureCount == 0) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers do not provide any space."); + return; + } +#endif + +#if NV_PROFILE + Time time; +#else + NV_UNUSED(timers); +#endif + + // + // Chunk Fracture + // + + if (eventBuffers == nullptr || eventBuffers->chunkFractures == nullptr) + { + // immediate hierarchical fracture + fractureNoEvents(commands->chunkFractureCount, commands->chunkFractures, filterActor, logFn); + } + else if (eventBuffers->chunkFractures != commands->chunkFractures) + { + // immediate hierarchical fracture + uint32_t count = 0; + fractureWithEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractures, eventBuffers->chunkFractureCount, &count, filterActor, logFn); + + if (count > eventBuffers->chunkFractureCount) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Chunk events were lost."); + } + else + { + eventBuffers->chunkFractureCount = count; + } + } + else if (eventBuffers->chunkFractures == commands->chunkFractures) + { + // compacting first + uint32_t count = 0; + fractureInPlaceEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractureCount, &count, filterActor, logFn); + + if (count > eventBuffers->chunkFractureCount) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Chunk events were lost."); + } + else + { + eventBuffers->chunkFractureCount = count; + } + } + + // + // Bond Fracture + // + + uint32_t outCount = 0; + const uint32_t eventBufferSize = eventBuffers ? eventBuffers->bondFractureCount : 0; + + NvBlastBond* bonds = m_asset->getBonds(); + float* bondHealths = getBondHealths(); + const uint32_t* graphChunkIndices = m_asset->m_graph.getChunkIndices(); + for (uint32_t i = 0; i < commands->bondFractureCount; ++i) + { + const NvBlastBondFractureData& frac = commands->bondFractures[i]; + NVBLAST_ASSERT(frac.nodeIndex0 < m_asset->m_graph.m_nodeCount); + NVBLAST_ASSERT(frac.nodeIndex1 < m_asset->m_graph.m_nodeCount); + uint32_t chunkIndex0 = graphChunkIndices[frac.nodeIndex0]; + uint32_t chunkIndex1 = graphChunkIndices[frac.nodeIndex1]; + NVBLAST_ASSERT(!isInvalidIndex(chunkIndex0) || !isInvalidIndex(chunkIndex1)); + Actor* actor0 = !isInvalidIndex(chunkIndex0) ? getGetChunkActor(chunkIndex0) : nullptr; + Actor* actor1 = !isInvalidIndex(chunkIndex1) ? getGetChunkActor(chunkIndex1) : nullptr; + NVBLAST_ASSERT(actor0 != nullptr || actor1 != nullptr); + // If actors are not nullptr and different then bond is already broken + // One of actor can be nullptr which probably means it's 'world' node. + if (actor0 == actor1 || actor0 == nullptr || actor1 == nullptr) + { + Actor* actor = actor0 ? actor0 : actor1; + NVBLAST_ASSERT_WITH_MESSAGE(actor, "NvBlastActorApplyFracture: all actors in bond fracture command are nullptr, command will be safely ignored, but investigation is recommended."); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: bond fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t bondIndex = actor->damageBond(frac.nodeIndex0, frac.nodeIndex1, frac.health); + if (!isInvalidIndex(bondIndex)) + { + if (eventBuffers && eventBuffers->bondFractures) + { + if (outCount < eventBufferSize) + { + NvBlastBondFractureData& outEvent = eventBuffers->bondFractures[outCount]; + outEvent.userdata = bonds[bondIndex].userData; + outEvent.nodeIndex0 = frac.nodeIndex0; + outEvent.nodeIndex1 = frac.nodeIndex1; + outEvent.health = bondHealths[bondIndex]; + } + } + outCount++; + } + } + } + } + + if (eventBuffers && eventBuffers->bondFractures) + { + if (outCount > eventBufferSize) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Bond events were lost."); + } + else + { + eventBuffers->bondFractureCount = outCount; + } + } + +#if NV_PROFILE + if (timers != nullptr) + { + timers->fracture += time.getElapsedTicks(); + } +#endif + +} + + } // namespace Blast } // namespace Nv @@ -167,22 +596,29 @@ NvBlastFamily* NvBlastAssetCreateFamily(void* mem, const NvBlastAsset* asset, Nv uint32_t NvBlastFamilyGetFormatVersion(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetFormatVersion: NULL family pointer input.", return UINT32_MAX); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetFormatVersion: NULL family pointer input.", return UINT32_MAX); return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->formatVersion; } +const NvBlastAsset* NvBlastFamilyGetAsset(const NvBlastFamily* family, NvBlastLog logFn) +{ + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetAssetID: NULL family pointer input.", return nullptr); + return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_asset; +} + + void NvBlastFamilySetAsset(NvBlastFamily* family, const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilySetAsset: NULL family pointer input.", return); - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastFamilySetAsset: NULL asset pointer input.", return); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilySetAsset: NULL family pointer input.", return); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastFamilySetAsset: NULL asset pointer input.", return); Nv::Blast::FamilyHeader* header = reinterpret_cast<Nv::Blast::FamilyHeader*>(family); const Nv::Blast::Asset* solverAsset = reinterpret_cast<const Nv::Blast::Asset*>(asset); if (memcmp(&header->m_assetID, &solverAsset->m_ID, sizeof(NvBlastID))) { - NVBLAST_LOG_ERROR(logFn, "NvBlastFamilySetAsset: wrong asset. Passed asset ID doesn't match family asset ID."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastFamilySetAsset: wrong asset. Passed asset ID doesn't match family asset ID."); return; } @@ -192,47 +628,35 @@ void NvBlastFamilySetAsset(NvBlastFamily* family, const NvBlastAsset* asset, NvB uint32_t NvBlastFamilyGetSize(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetSize: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetSize: NULL family pointer input.", return 0); return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->size; } NvBlastID NvBlastFamilyGetAssetID(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetAssetID: NULL family pointer input.", return NvBlastID()); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetAssetID: NULL family pointer input.", return NvBlastID()); return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_assetID; } uint32_t NvBlastFamilyGetActorCount(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActorCount: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActorCount: NULL family pointer input.", return 0); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); - if (header->formatVersion != NvBlastFamilyDataFormat::Current) - { - NVBLAST_LOG_ERROR(logFn, "NvBlastFamilyGetActorCount: wrong family format. Family must be converted to current version."); - return 0; - } - return header->m_actorCount; } uint32_t NvBlastFamilyGetActors(NvBlastActor** actors, uint32_t actorsSize, const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(actors != nullptr, logFn, "NvBlastFamilyGetActors: NULL actors pointer input.", return 0); - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActors: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(actors != nullptr, logFn, "NvBlastFamilyGetActors: NULL actors pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActors: NULL family pointer input.", return 0); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); - if (header->formatVersion != NvBlastFamilyDataFormat::Current) - { - NVBLAST_LOG_ERROR(logFn, "NvBlastFamilyGetActors: wrong family format. Family must be converted to current version."); - return 0; - } - // Iterate through active actors and write to supplied array const uint32_t familyActorCount = header->getActorBufferSize(); Nv::Blast::Actor* familyActor = header->getActors(); @@ -251,43 +675,20 @@ uint32_t NvBlastFamilyGetActors(NvBlastActor** actors, uint32_t actorsSize, cons NvBlastActor* NvBlastFamilyGetChunkActor(const NvBlastFamily* family, uint32_t chunkIndex, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetChunkActor: NULL family pointer input.", return nullptr); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetChunkActor: NULL family pointer input.", return nullptr); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); - NVBLAST_CHECK(header->m_asset != nullptr, logFn, "NvBlastFamilyGetChunkActor: NvBlastFamily has null asset set.", return nullptr); - - const Nv::Blast::Asset& solverAsset = *static_cast<const Nv::Blast::Asset*>(header->m_asset); - NVBLAST_CHECK(chunkIndex < solverAsset.m_chunkCount, logFn, "NvBlastFamilyGetChunkActor: bad value of chunkIndex for the given family's asset.", return nullptr); - - // get actorIndex from chunkIndex - uint32_t actorIndex; - if (chunkIndex < solverAsset.getUpperSupportChunkCount()) - { - actorIndex = header->getChunkActorIndices()[chunkIndex]; - } - else - { - actorIndex = chunkIndex - (solverAsset.getUpperSupportChunkCount() - solverAsset.m_graph.m_nodeCount); - } + NVBLASTLL_CHECK(header->m_asset != nullptr, logFn, "NvBlastFamilyGetChunkActor: NvBlastFamily has null asset set.", return nullptr); + NVBLASTLL_CHECK(chunkIndex < header->m_asset->m_chunkCount, logFn, "NvBlastFamilyGetChunkActor: bad value of chunkIndex for the given family's asset.", return nullptr); - // get actor from actorIndex - if (!Nv::Blast::isInvalidIndex(actorIndex)) - { - NVBLAST_ASSERT(actorIndex < header->getActorBufferSize()); - Nv::Blast::Actor* actor = &header->getActors()[actorIndex]; - if (actor->isActive()) - { - return actor; - } - } - return nullptr; + return header->getGetChunkActor(chunkIndex); } uint32_t NvBlastFamilyGetMaxActorCount(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetMaxActorCount: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetMaxActorCount: NULL family pointer input.", return 0); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); return header->getActorBufferSize(); } diff --git a/sdk/lowlevel/source/NvBlastFamily.h b/sdk/lowlevel/source/NvBlastFamily.h index d1cb069..99a7e98 100644 --- a/sdk/lowlevel/source/NvBlastFamily.h +++ b/sdk/lowlevel/source/NvBlastFamily.h @@ -1,18 +1,35 @@ -/* -* 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 NVBLASTFAMILY_H #define NVBLASTFAMILY_H -#include "NvBlastPreprocessorInternal.h" #include "NvBlastAsset.h" #include "NvBlastPreprocessor.h" #include "NvBlastDLink.h" @@ -164,6 +181,139 @@ struct FamilyHeader : public NvBlastDataBlock \return true iff the indexed actor is active. */ bool isActorActive(uint32_t index) const; + + /** + Retrieve the actor from an index. If actor is inactive nullptr is returned. + + \param[in] index The index of an actor. + + \return A pointer to the indexed actor if the actor is active, nullptr otherwise. + */ + Actor* getActorByIndex(uint32_t index) const; + + /** + Retrieve the index of an actor associated with the given chunk. + + \param[in] chunkIndex The index of chunk. + + \return the index of associated actor in the FamilyHeader's getActors() array. + */ + uint32_t getGetChunkActorIndex(uint32_t chunkIndex) const; + + /** + Retrieve the index of an actor associated with the given node. + + \param[in] nodeIndex The index of node. + + \return the index of associated actor in the FamilyHeader's getActors() array. + */ + uint32_t getGetNodeActorIndex(uint32_t nodeIndex) const; + + /** + Retrieve an actor associated with the given chunk. + + \param[in] chunkIndex The index of chunk. + + \return A pointer to the actor if the actor is active, nullptr otherwise. + */ + Actor* getGetChunkActor(uint32_t chunkIndex) const; + + /** + Retrieve an actor associated with the given node. + + \param[in] nodeIndex The index of node. + + \return A pointer to the actor if the actor is active, nullptr otherwise. + */ + Actor* getGetNodeActor(uint32_t nodeIndex) const; + + + //////// Fracturing methods //////// + + /** + Hierarchically distribute damage to child chunks. + + \param chunkIndex asset chunk index to hierarchically damage + \param suboffset index of the first sub-support health + \param healthDamage damage strength to apply + \param chunkHealths instance chunk healths + \param chunks asset chunk collection + */ + void fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks); + + /** + Hierarchically distribute damage to child chunks, recording a fracture event for each health damage applied. + + If outBuffer is too small, events are dropped but the chunks are still damaged. + + \param chunkIndex asset chunk index to hierarchically damage + \param suboffset index of the first sub-support health + \param healthDamage damage strength to apply + \param chunkHealths instance chunk healths + \param chunks asset chunk collection + \param outBuffer target buffer for fracture events + \param currentIndex current position in outBuffer - returns the number of damaged chunks + \param maxCount capacity of outBuffer + \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands + \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + */ + void fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount); + + /** + Apply chunk fracture commands hierarchically. + + \param chunkFractureCount number of chunk fracture commands to apply + \param chunkFractures array of chunk fracture commands + \param filterActor pointer to the actor to filter commands corresponding to other actors. May be NULL to apply all commands + \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + */ + void fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures, Actor* filterActor, NvBlastLog logFn); + + /** + Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied. + + If events array is too small, events are dropped but the chunks are still damaged. + + \param chunkFractureCount number of chunk fracture commands to apply + \param commands array of chunk fracture commands + \param events target buffer for fracture events + \param eventsSize number of available entries in 'events' + \param count returns the number of damaged chunks + \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands + \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + + */ + void fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn); + + /** + Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied. + + In-Place version: fracture commands are replaced by fracture events. + + If inoutbuffer array is too small, events are dropped but the chunks are still damaged. + + \param chunkFractureCount number of chunk fracture commands to apply + \param inoutbuffer array of chunk fracture commands to be replaced by events + \param eventsSize number of available entries in inoutbuffer + \param count returns the number of damaged chunks + \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands + \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + + */ + void fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn); + + /** + See NvBlastActorApplyFracture + + \param[in,out] eventBuffers Target buffers to hold applied fracture events. May be NULL, in which case events are not reported. + To avoid data loss, provide an entry for every lower-support chunk and every bond in the original actor. + \param[in,out] actor The NvBlastActor to apply fracture to. + \param[in] commands The fracture commands to process. + \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands + \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL. + \param[in,out] timers If non-NULL this struct will be filled out with profiling information for the step, in profile build configurations. + */ + void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, Actor* filterActor, NvBlastLog logFn, NvBlastTimers* timers); }; } // namespace Blast @@ -221,6 +371,52 @@ NV_INLINE bool FamilyHeader::isActorActive(uint32_t index) const } +NV_INLINE Actor* FamilyHeader::getActorByIndex(uint32_t index) const +{ + NVBLAST_ASSERT(index < getActorBufferSize()); + Actor& actor = getActors()[index]; + return actor.isActive() ? &actor : nullptr; +} + + +NV_INLINE uint32_t FamilyHeader::getGetChunkActorIndex(uint32_t chunkIndex) const +{ + NVBLAST_ASSERT(m_asset); + NVBLAST_ASSERT(chunkIndex < m_asset->m_chunkCount); + if (chunkIndex < m_asset->getUpperSupportChunkCount()) + { + return getChunkActorIndices()[chunkIndex]; + } + else + { + return chunkIndex - (m_asset->getUpperSupportChunkCount() - m_asset->m_graph.m_nodeCount); + } +} + + +NV_INLINE uint32_t FamilyHeader::getGetNodeActorIndex(uint32_t nodeIndex) const +{ + NVBLAST_ASSERT(m_asset); + NVBLAST_ASSERT(nodeIndex < m_asset->m_graph.m_nodeCount); + const uint32_t chunkIndex = m_asset->m_graph.getChunkIndices()[nodeIndex]; + return isInvalidIndex(chunkIndex) ? chunkIndex : getChunkActorIndices()[chunkIndex]; +} + + +NV_INLINE Actor* FamilyHeader::getGetChunkActor(uint32_t chunkIndex) const +{ + uint32_t actorIndex = getGetChunkActorIndex(chunkIndex); + return !isInvalidIndex(actorIndex) ? getActorByIndex(actorIndex) : nullptr; +} + + +NV_INLINE Actor* FamilyHeader::getGetNodeActor(uint32_t nodeIndex) const +{ + uint32_t actorIndex = getGetNodeActorIndex(nodeIndex); + return !isInvalidIndex(actorIndex) ? getActorByIndex(actorIndex) : nullptr; +} + + //////// Global functions //////// /** diff --git a/sdk/lowlevel/source/NvBlastFamilyGraph.cpp b/sdk/lowlevel/source/NvBlastFamilyGraph.cpp index 08ed83d..9379a32 100644 --- a/sdk/lowlevel/source/NvBlastFamilyGraph.cpp +++ b/sdk/lowlevel/source/NvBlastFamilyGraph.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 "NvBlastFamilyGraph.h" diff --git a/sdk/lowlevel/source/NvBlastFamilyGraph.h b/sdk/lowlevel/source/NvBlastFamilyGraph.h index 9fa331a..1242487 100644 --- a/sdk/lowlevel/source/NvBlastFamilyGraph.h +++ b/sdk/lowlevel/source/NvBlastFamilyGraph.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 NVBLASTFAMILYGRAPH_H #define NVBLASTFAMILYGRAPH_H @@ -18,7 +36,6 @@ #include "NvBlastFixedBoolArray.h" #include "NvBlastMath.h" #include "NvBlastFixedPriorityQueue.h" -#include "NvBlastPreprocessorInternal.h" #include "NvBlastMemory.h" diff --git a/sdk/lowlevel/source/NvBlastSupportGraph.h b/sdk/lowlevel/source/NvBlastSupportGraph.h index 9ee3fc9..b8c2368 100644 --- a/sdk/lowlevel/source/NvBlastSupportGraph.h +++ b/sdk/lowlevel/source/NvBlastSupportGraph.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 NVBLASTSUPPORTGRAPH_H #define NVBLASTSUPPORTGRAPH_H #include "NvBlastIndexFns.h" -#include "NvBlastPreprocessorInternal.h" #include "NvBlastMemory.h" namespace Nv diff --git a/sdk/profiler/NvBlastProfiler.cpp b/sdk/profiler/NvBlastProfiler.cpp deleted file mode 100644 index 3e82396..0000000 --- a/sdk/profiler/NvBlastProfiler.cpp +++ /dev/null @@ -1,91 +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 "NvBlastProfilerInternal.h" -#include "PxProfiler.h" - -#if NV_PROFILE || NV_CHECKED || NV_DEBUG - -#if NV_NVTX -#include "nvToolsExt.h" -NV_INLINE void platformZoneStart(const char* name) { nvtxRangePush(name); } -NV_INLINE void platformZoneEnd(const char*) { 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(const char*) { } - -#endif - -static const uint64_t blastContextId = 0xb1a57; -static physx::PxProfilerCallback* sCallback = nullptr; -static bool sPlatform = false; -static NvBlastProfilerDetail::Level sDetail = NvBlastProfilerDetail::LOW; - -void NvBlastProfilerSetCallback(physx::PxProfilerCallback* pcb) -{ - sCallback = pcb; -} - -void NvBlastProfilerEnablePlatform(bool enable) -{ - sPlatform = enable; -} - -void NvBlastProfilerBegin(const char* name, NvBlastProfilerDetail::Level level) -{ - if (level <= sDetail) - { - if (sCallback != nullptr) - { - sCallback->zoneStart(name, false, blastContextId); - } - - if (sPlatform) - { - platformZoneStart(name); - } - } -} - -void NvBlastProfilerEnd(const char* name, NvBlastProfilerDetail::Level level) -{ - if (level <= sDetail) - { - if (sCallback != nullptr) - { - sCallback->zoneEnd(nullptr, name, false, blastContextId); - } - - if (sPlatform) - { - platformZoneEnd(name); - } - } -} - -void NvBlastProfilerSetDetail(NvBlastProfilerDetail::Level level) -{ - sDetail = level; -} - -#else - -void NvBlastProfilerSetCallback(physx::PxProfilerCallback*) {} -void NvBlastProfilerEnablePlatform(bool) {} -void NvBlastProfilerSetDetail(NvBlastProfilerDetail::Level) {} - -#endif //NV_PROFILE diff --git a/sdk/profiler/NvBlastProfilerInternal.h b/sdk/profiler/NvBlastProfilerInternal.h deleted file mode 100644 index 9be3c87..0000000 --- a/sdk/profiler/NvBlastProfilerInternal.h +++ /dev/null @@ -1,58 +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 NVBLASTPROFILERINTERNAL_H -#define NVBLASTPROFILERINTERNAL_H - -#include "NvBlastPreprocessor.h" -#include "NvBlastProfiler.h" - -#if NV_PROFILE || NV_CHECKED || NV_DEBUG - -void NvBlastProfilerBegin(const char* name, NvBlastProfilerDetail::Level); -void NvBlastProfilerEnd(const char* name, NvBlastProfilerDetail::Level); - -class ProfileScope -{ -public: - ProfileScope(const char* name, NvBlastProfilerDetail::Level level) :m_name(name), m_level(level) - { - NvBlastProfilerBegin(m_name, m_level); - } - - ~ProfileScope() - { - NvBlastProfilerEnd(m_name, m_level); - } - -private: - const char* m_name; - NvBlastProfilerDetail::Level m_level; -}; - -#define PERF_BLAST_PREFIX "Blast: " -#define PERF_ZONE_BEGIN(name) NvBlastProfilerBegin(PERF_BLAST_PREFIX name, NvBlastProfilerDetail::HIGH) -#define PERF_ZONE_END(name) NvBlastProfilerEnd(PERF_BLAST_PREFIX name, NvBlastProfilerDetail::HIGH) -#define PERF_SCOPE(name, detail) ProfileScope PX_CONCAT(_scope,__LINE__) (PERF_BLAST_PREFIX name, detail) -#define PERF_SCOPE_L(name) PERF_SCOPE(name, NvBlastProfilerDetail::LOW) -#define PERF_SCOPE_M(name) PERF_SCOPE(name, NvBlastProfilerDetail::MEDIUM) -#define PERF_SCOPE_H(name) PERF_SCOPE(name, NvBlastProfilerDetail::HIGH) - -#else - -#define PERF_ZONE_BEGIN(name) -#define PERF_ZONE_END(name) -#define PERF_SCOPE_L(name) -#define PERF_SCOPE_M(name) -#define PERF_SCOPE_H(name) - -#endif - -#endif diff --git a/sdk/toolkit/include/NvBlastTk.h b/sdk/toolkit/include/NvBlastTk.h index 6471165..1f4f579 100644 --- a/sdk/toolkit/include/NvBlastTk.h +++ b/sdk/toolkit/include/NvBlastTk.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 NVBLASTTK_H #define NVBLASTTK_H diff --git a/sdk/toolkit/include/NvBlastTkActor.h b/sdk/toolkit/include/NvBlastTkActor.h index a810ee1..453e4c4 100644 --- a/sdk/toolkit/include/NvBlastTkActor.h +++ b/sdk/toolkit/include/NvBlastTkActor.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 NVBLASTTKACTOR_H #define NVBLASTTKACTOR_H @@ -230,6 +248,15 @@ public: \return the number of TkJoint pointers written to the joints array. */ virtual uint32_t getJoints(TkJoint** joints, uint32_t jointsSize) const = 0; + + /** + Whether or not this actor is bound to the world using a bond with an invalid chunk index to represent the NRF. + + NOTE: Wrapper function over low-level function call NvBlastActorIsBoundToWorld. + + \return true iff this actor contains the "world" support graph node, created when a bond contains the UINT32_MAX value for one of their chunkIndices. + */ + virtual bool isBoundToWorld() const = 0; }; } // namespace Blast diff --git a/sdk/toolkit/include/NvBlastTkAsset.h b/sdk/toolkit/include/NvBlastTkAsset.h index 987da7d..1d8426b 100644 --- a/sdk/toolkit/include/NvBlastTkAsset.h +++ b/sdk/toolkit/include/NvBlastTkAsset.h @@ -1,17 +1,35 @@ -/* -* 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 NVBLASTTKASSET_H #define NVBLASTTKASSET_H -#include "NvBlastTkSerializable.h" +#include "NvBlastTkIdentifiable.h" #include "NvBlastTypes.h" #include "PxVec3.h" @@ -38,7 +56,7 @@ struct TkAssetJointDesc The static data associated with a destructible actor. TkAsset encapsulates an NvBlastAsset. In addition to the NvBlastAsset, the TkAsset stores joint descriptors (see TkAssetJointDesc). */ -class TkAsset : public TkSerializable +class TkAsset : public TkIdentifiable { public: /** @@ -115,7 +133,7 @@ public: The number of internal TkJoint objects that will be created when this asset is instanced into a TkActor (see TkFramework::createActor). These joints will not trigger TkJointUpdateEvent events until this actor is split into actors such that a joint connects two actors. At this time the actor's family - will dispatch a TkJointUpdateEvent::External event during a call to TkGroup::sync() (see TkGroup). + will dispatch a TkJointUpdateEvent::External event during a call to TkGroup::endProcess() (see TkGroup). \return the number of descriptors for internal joints. */ diff --git a/sdk/toolkit/include/NvBlastTkEvent.h b/sdk/toolkit/include/NvBlastTkEvent.h index 1e640f1..765d4d2 100644 --- a/sdk/toolkit/include/NvBlastTkEvent.h +++ b/sdk/toolkit/include/NvBlastTkEvent.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 NVBLASTTKEVENT_H #define NVBLASTTKEVENT_H diff --git a/sdk/toolkit/include/NvBlastTkFamily.h b/sdk/toolkit/include/NvBlastTkFamily.h index be6edd6..119d308 100644 --- a/sdk/toolkit/include/NvBlastTkFamily.h +++ b/sdk/toolkit/include/NvBlastTkFamily.h @@ -1,17 +1,35 @@ -/* -* 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 NVBLASTTKFAMILY_H #define NVBLASTTKFAMILY_H -#include "NvBlastTkSerializable.h" +#include "NvBlastTkIdentifiable.h" // Forward declarations @@ -34,7 +52,7 @@ The TkFamily is associated with the TkActor that is instanced from a TkAsset, as by spliting TkActors within the family. It encapsulates an NvBlastFamily, and also holds a material which will be used by default on all TkActors during damage functions. */ -class TkFamily : public TkSerializable +class TkFamily : public TkIdentifiable { public: /** diff --git a/sdk/toolkit/include/NvBlastTkFramework.h b/sdk/toolkit/include/NvBlastTkFramework.h index 353eebd..51ee743 100644 --- a/sdk/toolkit/include/NvBlastTkFramework.h +++ b/sdk/toolkit/include/NvBlastTkFramework.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 NVBLASTTKFRAMEWORK_H #define NVBLASTTKFRAMEWORK_H @@ -24,13 +42,7 @@ // Forward declarations namespace physx { -class PxErrorCallback; -class PxAllocatorCallback; class PxTransform; -namespace general_PxIOStream2 -{ -class PxFileBuf; -} } @@ -47,25 +59,12 @@ struct TkGroupDesc; class TkGroup; class TkActor; class TkJoint; -class TkSerializable; class TkIdentifiable; struct TkAssetJointDesc; /** -Descriptor for framework creation. - -The TkFramework uses PxShared callbacks for messages and allocation. -*/ -struct TkFrameworkDesc -{ - physx::PxErrorCallback* errorCallback; //!< User-defined message callback (see PxErrorCallback) - physx::PxAllocatorCallback* allocatorCallback; //!< User-defined allocation callback (see PxAllocatorCallback) -}; - - -/** Descriptor for asset creation Used to create a TkAsset. This may be used by an authoring tool to describe the asset to be created. @@ -165,41 +164,7 @@ public: Release this framework and all contained objects. Global singleton is set to NULL. */ - virtual void release() = 0; - - /** - Access to the error callback set by the user. - */ - virtual physx::PxErrorCallback& getErrorCallback() const = 0; - - /** - Access to the allocator callback set by the user. - */ - virtual physx::PxAllocatorCallback& getAllocatorCallback() const = 0; - - /** - Access to a log function which can be used in Blast low-level calls. - This function uses the user-supplied PxErrorCallback (see TkFrameworkDesc). - */ - virtual NvBlastLog getLogFn() const = 0; - - /** - Deserialize an object from the given stream. Only objects derived from TkSerializable may be serialized and - deserialized. Use the parent class method TkIdentifiable::getType() to know the type to which to cast the object. - - Notes for different classes: - - TkAsset: deserializing a serialized TkAsset will recreate the asset in memory with the same NvBlastID (see - TkIdentifiable::getID()) as the original asset. - - TkFamily: deserializing a serialized TkFamily will generate all TkActor and TkJoint objects that were originally - contained in the family. The TkAsset which generated the family must exist at the time the family is deserialized. - - \param[in] stream User-defined stream object. - - \return pointer the deserialized object if successful, or NULL if unsuccessful. - */ - virtual TkSerializable* deserialize(physx::general_PxIOStream2::PxFileBuf& stream) = 0; + virtual void release() = 0; /** To find the type information for a given TkIdentifiable-derived class, use this funtion with the TkTypeIndex::Enum @@ -209,7 +174,7 @@ public: \return type object associated with the object's class. */ - virtual const TkType* getType(TkTypeIndex::Enum typeIndex) const = 0; + virtual const TkType* getType(TkTypeIndex::Enum typeIndex) const = 0; /** Look up an object derived from TkIdentifiable by its ID. @@ -218,7 +183,7 @@ public: \return pointer the object if it exists, NULL otherwise. */ - virtual TkIdentifiable* findObjectByID(const NvBlastID& id) const = 0; + virtual TkIdentifiable* findObjectByID(const NvBlastID& id) const = 0; /** The number of TkIdentifiable-derived objects in the framework of the given type. @@ -227,7 +192,7 @@ public: \return the number of objects that currently exist of the given type. */ - virtual uint32_t getObjectCount(const TkType& type) const = 0; + virtual uint32_t getObjectCount(const TkType& type) const = 0; /** Retrieve an array of pointers (into the user-supplied buffer) to TkIdentifiable-derived objects of the given type. @@ -239,7 +204,7 @@ public: \return the number of TkIdentifiable pointers written to the buffer. */ - virtual uint32_t getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart = 0) const = 0; + virtual uint32_t getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart = 0) const = 0; //////// Asset creation //////// /** @@ -249,15 +214,16 @@ public: This function may modify both the chunkDescs and bondDescs array, since rearranging chunk descriptors requires re-indexing within the bond descriptors. - \param[in] chunkDescs Array of chunk descriptors of size chunkCount. It will be updated accordingly. - \param[in] chunkCount The number of chunk descriptors. - \param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. - \param[in] bondCount The number of bond descriptors. - \param[in] chunkReorderMap If not NULL, must be a pointer to a uint32_t array of size desc.chunkCount. Maps old chunk indices to the reordered chunk indices. + \param[in] chunkDescs Array of chunk descriptors of size chunkCount. It will be updated accordingly. + \param[in] chunkCount The number of chunk descriptors. + \param[in] bondDescs Array of bond descriptors of size chunkCount. It will be updated accordingly. + \param[in] bondCount The number of bond descriptors. + \param[in] chunkReorderMap If not NULL, must be a pointer to a uint32_t array of size desc.chunkCount. Maps old chunk indices to the reordered chunk indices. + \param[in] keepBondNormalChunkOrder If true, bond normals will be flipped if their chunk index order was reveresed by the reorder map. \return true iff the chunks did not require reordering (chunkReorderMap is the identity map). */ - virtual bool reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap = nullptr) const = 0; + virtual bool reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap = nullptr, bool keepBondNormalChunkOrder = false) const = 0; /** Helper function to ensure (check and update) support coverage of chunks, required for asset creation via the createAsset function. @@ -271,7 +237,7 @@ public: \return true iff coverage was already exact. */ - virtual bool ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const = 0; + virtual bool ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const = 0; /** Create an asset from the given descriptor. @@ -280,7 +246,7 @@ public: \return the created asset, if the descriptor was valid and memory was available for the operation. Otherwise, returns NULL. */ - virtual TkAsset* createAsset(const TkAssetDesc& desc) = 0; + virtual TkAsset* createAsset(const TkAssetDesc& desc) = 0; /** Create an asset from a low-level NvBlastAsset. @@ -292,7 +258,7 @@ public: \return the created asset, if memory was available for the operation. Otherwise, returns NULL. */ - virtual TkAsset* createAsset(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs = nullptr, uint32_t jointDescCount = 0, bool ownsAsset = false) = 0; + virtual TkAsset* createAsset(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs = nullptr, uint32_t jointDescCount = 0, bool ownsAsset = false) = 0; //////// Group creation //////// /** @@ -304,7 +270,7 @@ public: \return the created group, if the descriptor was valid and memory was available for the operation. Otherwise, returns NULL. */ - virtual TkGroup* createGroup(const TkGroupDesc& desc) = 0; + virtual TkGroup* createGroup(const TkGroupDesc& desc) = 0; //////// Actor creation //////// /** @@ -314,7 +280,7 @@ public: \return the created actor, if the descriptor was valid and memory was available for the operation. Otherwise, returns NULL. */ - virtual TkActor* createActor(const TkActorDesc& desc) = 0; + virtual TkActor* createActor(const TkActorDesc& desc) = 0; //////// Joint creation //////// /** @@ -329,13 +295,13 @@ public: \return the created joint, if the descriptor was valid and memory was available for the operation. Otherwise, returns NULL. */ - virtual TkJoint* createJoint(const TkJointDesc& desc) = 0; + virtual TkJoint* createJoint(const TkJointDesc& desc) = 0; protected: /** Destructor is virtual and not public - use the release() method instead of explicitly deleting the TkFramework */ - virtual ~TkFramework() {} + virtual ~TkFramework() {} }; } // namespace Blast @@ -347,11 +313,9 @@ protected: /** Create a new TkFramework. This creates a global singleton, and will fail if a TkFramework object already exists. -\param[in] desc The descriptor used to create the new framework (see TkFrameworkDesc). - \return the new TkFramework if successful, NULL otherwise. */ -NVBLAST_API Nv::Blast::TkFramework* NvBlastTkFrameworkCreate(const Nv::Blast::TkFrameworkDesc& desc); +NVBLAST_API Nv::Blast::TkFramework* NvBlastTkFrameworkCreate(); /** diff --git a/sdk/toolkit/include/NvBlastTkGroup.h b/sdk/toolkit/include/NvBlastTkGroup.h index 585cccb..2e5ee3e 100644 --- a/sdk/toolkit/include/NvBlastTkGroup.h +++ b/sdk/toolkit/include/NvBlastTkGroup.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 NVBLASTTKGROUP_H #define NVBLASTTKGROUP_H @@ -14,13 +32,6 @@ #include "NvBlastTkIdentifiable.h" -// Forward declarations -namespace physx -{ -class PxTaskManager; -} - - namespace Nv { namespace Blast @@ -31,12 +42,12 @@ class TkActor; /** -Descriptor for a TkGroup. It uses the PxShared PxTaskManager interface to dispatch PxLightCpuTask. -@see TkWorker +Descriptor for a TkGroup. TkGroup uses a number of TkGroupWorker to process its actors. +@see TkGroupWorker, TkGroup::setWorkerCount */ struct TkGroupDesc { - physx::PxTaskManager* pxTaskManager; //!< User-defined task manager + uint32_t workerCount; //!< The number of expected TkWorkers to process the TkGroup concurrently. }; @@ -53,14 +64,39 @@ struct TkGroupStats /** +A worker as provided by TkGroup::acquireWorker(). It manages the necessary memory for parallel processing. +The group can be processed concurrently by calling process() from different threads using a different TkGroupWorker each. + +TkActors that have been damaged with applyFracture() such that they may be split into separate +actors are split by this function. TkActors that have damage queued through the actor's damage() function +will be fractured and split by this function. +*/ +class TkGroupWorker +{ +public: + /** + Process a job of this worker's TkGroup. + + /param[in] jobId a job id in the range (0, TkGroup::startProcess()] + */ + virtual void process(uint32_t jobId) = 0; +}; + + +/** A group is a processing unit, to which the user may add TkActors. New actors generated from splitting a TkActor are automatically put into the same group. However, any actor may be removed from its group and placed into another group (or no group) by the user's choice. When the group's process function is called, all actors' damage buffers will be processed and turned into fracture events and the actor is split if applicable. -This work is done in separate (possibly multiple) threads. The sync function waits for the processing threads to finish -and dispatches events for processing that actually occurred. + +This work can be done in multiple threads with the help of TkGroupWorker: +Instead of calling the process function, commence the procedure with startProcess which returns the number of jobs to process. +Each concurrent thread uses an acquired TkGroupWorker to process the jobs. +Over the whole procedure, each job must be processed once and only once. +Jobs can be processed in any order. TkGroupWorkers can be returned and acquired later by another task. +After processing every job and returning all the workers to the group, endProcess concludes the procedure. */ class TkGroup : public TkIdentifiable { @@ -72,14 +108,14 @@ public: \return true if successful, false otherwise. */ - virtual bool addActor(TkActor& actor) = 0; + virtual bool addActor(TkActor& actor) = 0; /** The number of actors currently in this group. \return the number of TkActors that currently exist in this group. */ - virtual uint32_t getActorCount() const = 0; + virtual uint32_t getActorCount() const = 0; /** Retrieve an array of pointers (into the user-supplied buffer) to actors. @@ -90,32 +126,57 @@ public: \return the number of TkActor pointers written to the buffer. */ - virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const = 0; + virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const = 0; /** - TkActors that have been damaged with applyFracture() such that they may be split into separate - actors are split by this function. TkActors that have damage queued through the actor's damage() function - will be fractured and split by this function. - Fracture and splitting work will be run on different threads provided through TkGroupDesc::pxTaskManager. - All work is done asynchronously, and the results are gathered by the sync() function. + Lock this group for processing concurrently with TkGroupWorker. The group is unlocked again with the endProcess() function. - Note: The number of threads provided by pxTaskManager must not change over the group's lifetime. - - \return true if processing may be launched (this group is not currently processing), false otherwise. + \return The number of jobs to process. TkGroupWorker::process must be called once for each jobID from 0 to this number-1. + See TkGroup::process for a single threaded example. */ - virtual bool process() = 0; + virtual uint32_t startProcess() = 0; /** - If all threads spawned by process() have finished, and sync() has not yet been called since, then this - function gathers the results of the split operations on the actors in this group. Events will be dispatched + Unlock this group after all jobs were processed with TkGroupWorker. All workers must have been returned with returnWorker(). + This function gathers the results of the split operations on the actors in this group. Events will be dispatched to notify listeners of new and deleted actors. - \param[in] block If true, this function waits until all threads have completed execution, then performs the gather and dispatch work. - If false, this function will perform the gather and dispatch work only if threads have completed execution, otherwise it returns immediately. + Note that groups concurrently dispatching events for the same TkFamily require synchronization in the TkFamily's Listener. + However, concurrent use of endProcess is not recommended in this version. It should be called from the main thread. - \return true if gather and dispatch work have been performed, false otherwise. + \return true if the group was processing */ - virtual bool sync(bool block = true) = 0; + virtual bool endProcess() = 0; + + /** + Set the expected number of concurrent worker threads that will process this group concurrently. + */ + virtual void setWorkerCount(uint32_t workerCount) = 0; + + /** + \return The total amount of workers allocated for this group. + */ + virtual uint32_t getWorkerCount() const = 0; + + /** + Acquire one worker to process the group concurrently on a thread. + The worker must be returned with returnWorker() before endProcess() is called on its group. + + \return A worker for this group (at most getWorkerCount) or nullptr if none is available. + */ + virtual TkGroupWorker* acquireWorker() = 0; + + /** + Return a worker previously acquired with acquireWorker() to this TkGroup. + + \param[in] The TkGroupWorker previously acquired from this TkGroup. + */ + virtual void returnWorker(TkGroupWorker*) = 0; + + /** + Helper function to process the group synchronously on a single thread. + */ + virtual void process(); /** For profile builds only, request stats of the last successful processing. Inactive in other builds. @@ -123,11 +184,27 @@ public: \param[in] stats The struct to be filled in. */ - virtual void getStats(TkGroupStats& stats) const = 0; + virtual void getStats(TkGroupStats& stats) const = 0; }; } // namespace Blast } // namespace Nv +NV_INLINE void Nv::Blast::TkGroup::process() +{ + uint32_t jobCount = startProcess(); + if (jobCount > 0) + { + TkGroupWorker* worker = acquireWorker(); + for (uint32_t i = 0; i < jobCount; i++) + { + worker->process(i); + } + returnWorker(worker); + } + endProcess(); +} + + #endif // ifndef NVBLASTTKGROUP_H diff --git a/sdk/toolkit/include/NvBlastTkIdentifiable.h b/sdk/toolkit/include/NvBlastTkIdentifiable.h index 6efe954..a36bc61 100644 --- a/sdk/toolkit/include/NvBlastTkIdentifiable.h +++ b/sdk/toolkit/include/NvBlastTkIdentifiable.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 NVBLASTTKIDENTIFIABLE_H #define NVBLASTTKIDENTIFIABLE_H @@ -52,6 +70,11 @@ public: \return the static type data for this object type. */ virtual const TkType& getType() const = 0; + + /** + Integer field available to the user which may be serialized. + */ + uint64_t userIntData; }; } // namespace Blast diff --git a/sdk/toolkit/include/NvBlastTkJoint.h b/sdk/toolkit/include/NvBlastTkJoint.h index 1fc41c0..d1f8ce4 100644 --- a/sdk/toolkit/include/NvBlastTkJoint.h +++ b/sdk/toolkit/include/NvBlastTkJoint.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 NVBLASTTKJOINT_H #define NVBLASTTKJOINT_H diff --git a/sdk/toolkit/include/NvBlastTkObject.h b/sdk/toolkit/include/NvBlastTkObject.h index 085e859..90a3b27 100644 --- a/sdk/toolkit/include/NvBlastTkObject.h +++ b/sdk/toolkit/include/NvBlastTkObject.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 NVBLASTTKOBJECT_H #define NVBLASTTKOBJECT_H diff --git a/sdk/toolkit/include/NvBlastTkSerializable.h b/sdk/toolkit/include/NvBlastTkSerializable.h deleted file mode 100644 index 93b9b47..0000000 --- a/sdk/toolkit/include/NvBlastTkSerializable.h +++ /dev/null @@ -1,60 +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 NVBLASTTKSERIALIZABLE_H -#define NVBLASTTKSERIALIZABLE_H - - -#include "NvBlastTkIdentifiable.h" - - -// Forward declarations -namespace physx -{ -namespace general_PxIOStream2 -{ -class PxFileBuf; -} -} - - -namespace Nv -{ -namespace Blast -{ - -/** -TkSerializable objects support the serialize interface, and are returned by TkFramework::deserialize. -*/ -class TkSerializable : public TkIdentifiable -{ -public: - /** - Write the object data to the user-defined PxFileBuf stream. - - \param[in] stream User-defined stream object. - - \return true if serialization was successful, false otherwise. - */ - virtual bool serialize(physx::general_PxIOStream2::PxFileBuf& stream) const = 0; - - // Data - - /** - Integer field available to the user. This data is serialized. - */ - uint64_t userIntData; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKSERIALIZABLE_H diff --git a/sdk/toolkit/include/NvBlastTkType.h b/sdk/toolkit/include/NvBlastTkType.h index 6f3afbf..ebb6436 100644 --- a/sdk/toolkit/include/NvBlastTkType.h +++ b/sdk/toolkit/include/NvBlastTkType.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 NVBLASTTKTYPE_H #define NVBLASTTKTYPE_H diff --git a/sdk/toolkit/source/NvBlastTkActorImpl.cpp b/sdk/toolkit/source/NvBlastTkActorImpl.cpp index 028e0f1..e6c6ec7 100644 --- a/sdk/toolkit/source/NvBlastTkActorImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkActorImpl.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 "NvBlastPreprocessor.h" @@ -22,12 +40,8 @@ #include "NvBlastMemory.h" #include "Px.h" -#include "PxFileBuf.h" -#include "PxAllocatorCallback.h" #include "PxTransform.h" -using namespace physx::general_PxIOStream2; - namespace Nv { @@ -41,11 +55,11 @@ TkActorImpl* TkActorImpl::create(const TkActorDesc& desc) TkFamilyImpl* family = TkFamilyImpl::create(asset); NvBlastFamily* familyLL = family->getFamilyLLInternal(); - TkArray<char>::type scratch((uint32_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(familyLL, TkFrameworkImpl::get()->log)); - NvBlastActor* actorLL = NvBlastFamilyCreateFirstActor(familyLL, &desc, scratch.begin(), TkFrameworkImpl::get()->log); + Array<char>::type scratch((uint32_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(familyLL, logLL)); + NvBlastActor* actorLL = NvBlastFamilyCreateFirstActor(familyLL, &desc, scratch.begin(), logLL); if (actorLL == nullptr) { - NVBLASTTK_LOG_ERROR("TkActorImpl::create: low-level actor could not be created."); + NVBLAST_LOG_ERROR("TkActorImpl::create: low-level actor could not be created."); return nullptr; } @@ -126,7 +140,7 @@ void TkActorImpl::release() if (m_actorLL != nullptr) { - NvBlastActorDeactivate(m_actorLL, TkFrameworkImpl::get()->log); + NvBlastActorDeactivate(m_actorLL, logLL); } if (m_family != nullptr) @@ -170,13 +184,13 @@ TkGroup* TkActorImpl::removeFromGroup() { if (m_group == nullptr) { - NVBLASTTK_LOG_WARNING("TkActorImpl::removeFromGroup: actor not in a group."); + NVBLAST_LOG_WARNING("TkActorImpl::removeFromGroup: actor not in a group."); return nullptr; } if (m_group->isProcessing()) { - NVBLASTTK_LOG_ERROR("TkActorImpl::removeFromGroup: cannot alter Group while processing."); + NVBLAST_LOG_ERROR("TkActorImpl::removeFromGroup: cannot alter Group while processing."); return nullptr; } @@ -200,37 +214,37 @@ const TkAsset* TkActorImpl::getAsset() const uint32_t TkActorImpl::getVisibleChunkCount() const { - return NvBlastActorGetVisibleChunkCount(m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetVisibleChunkCount(m_actorLL, logLL); } uint32_t TkActorImpl::getVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize) const { - return NvBlastActorGetVisibleChunkIndices(visibleChunkIndices, visibleChunkIndicesSize, m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetVisibleChunkIndices(visibleChunkIndices, visibleChunkIndicesSize, m_actorLL, logLL); } uint32_t TkActorImpl::getGraphNodeCount() const { - return NvBlastActorGetGraphNodeCount(m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetGraphNodeCount(m_actorLL, logLL); } uint32_t TkActorImpl::getGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize) const { - return NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeIndicesSize, m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeIndicesSize, m_actorLL, logLL); } const float* TkActorImpl::getBondHealths() const { - return NvBlastActorGetBondHealths(m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetBondHealths(m_actorLL, logLL); } uint32_t TkActorImpl::getSplitMaxActorCount() const { - return NvBlastActorGetMaxActorCountForSplit(m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetMaxActorCountForSplit(m_actorLL, logLL); } @@ -268,21 +282,21 @@ TkActorImpl::operator Nv::Blast::TkActorData() const void TkActorImpl::damage(const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams) { - PERF_SCOPE_L("TkActor::damage"); + BLAST_PROFILE_SCOPE_L("TkActor::damage"); if (m_group == nullptr) { - NVBLASTTK_LOG_WARNING("TkActor::damage: actor is not in a group, cannot fracture."); + NVBLAST_LOG_WARNING("TkActor::damage: actor is not in a group, cannot fracture."); return; } if (m_group->isProcessing()) { - NVBLASTTK_LOG_WARNING("TkActor::damage: group is being processed, cannot fracture this actor."); + NVBLAST_LOG_WARNING("TkActor::damage: group is being processed, cannot fracture this actor."); return; } - if (NvBlastActorCanFracture(m_actorLL, TkFrameworkImpl::get()->log)) + if (NvBlastActorCanFracture(m_actorLL, logLL)) { m_damageBuffer.pushBack(DamageData(program, programParams)); makePending(); @@ -298,21 +312,21 @@ void TkActorImpl::damage(const NvBlastDamageProgram& program, const void* damage void TkActorImpl::damage(const NvBlastDamageProgram& program, const void* damageDesc, uint32_t descSize, const void* material) { - PERF_SCOPE_L("TkActor::damage"); + BLAST_PROFILE_SCOPE_L("TkActor::damage"); if (m_group == nullptr) { - NVBLASTTK_LOG_WARNING("TkActor::damage: actor is not in a group, cannot fracture."); + NVBLAST_LOG_WARNING("TkActor::damage: actor is not in a group, cannot fracture."); return; } if (m_group->isProcessing()) { - NVBLASTTK_LOG_WARNING("TkActor::damage: group is being processed, cannot fracture this actor."); + NVBLAST_LOG_WARNING("TkActor::damage: group is being processed, cannot fracture this actor."); return; } - if (NvBlastActorCanFracture(m_actorLL, TkFrameworkImpl::get()->log)) + if (NvBlastActorCanFracture(m_actorLL, logLL)) { bool appended = false; for (auto& damageData : m_damageBuffer) @@ -336,30 +350,30 @@ void TkActorImpl::damage(const NvBlastDamageProgram& program, const void* damage void TkActorImpl::generateFracture(NvBlastFractureBuffers* commands, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams) const { - PERF_SCOPE_L("TkActor::generateFracture"); + BLAST_PROFILE_SCOPE_L("TkActor::generateFracture"); if (m_group && m_group->isProcessing()) { - NVBLASTTK_LOG_WARNING("TkActor::generateFracture: group is being processed, cannot fracture this actor."); + NVBLAST_LOG_WARNING("TkActor::generateFracture: group is being processed, cannot fracture this actor."); return; } // const context, must make m_timers mutable otherwise - NvBlastActorGenerateFracture(commands, m_actorLL, program, programParams, TkFrameworkImpl::get()->log, const_cast<NvBlastTimers*>(&m_timers)); + NvBlastActorGenerateFracture(commands, m_actorLL, program, programParams, logLL, const_cast<NvBlastTimers*>(&m_timers)); } void TkActorImpl::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands) { - PERF_SCOPE_L("TkActor::applyFracture"); + BLAST_PROFILE_SCOPE_L("TkActor::applyFracture"); if (m_group && m_group->isProcessing()) { - NVBLASTTK_LOG_WARNING("TkActor::applyFracture: group is being processed, cannot fracture this actor."); + NVBLAST_LOG_WARNING("TkActor::applyFracture: group is being processed, cannot fracture this actor."); return; } - NvBlastActorApplyFracture(eventBuffers, m_actorLL, commands, TkFrameworkImpl::get()->log, &m_timers); + NvBlastActorApplyFracture(eventBuffers, m_actorLL, commands, logLL, &m_timers); if (commands->chunkFractureCount > 0 || commands->bondFractureCount > 0) { @@ -393,6 +407,12 @@ uint32_t TkActorImpl::getJoints(TkJoint** joints, uint32_t jointsSize) const } +bool TkActorImpl::isBoundToWorld() const +{ + return NvBlastActorIsBoundToWorld(m_actorLL, logLL); +} + + //////// TkActorImpl::DamageData methods //////// static bool operator==(const NvBlastDamageProgram& lhs, const NvBlastDamageProgram& rhs) diff --git a/sdk/toolkit/source/NvBlastTkActorImpl.h b/sdk/toolkit/source/NvBlastTkActorImpl.h index 4d65660..33fde68 100644 --- a/sdk/toolkit/source/NvBlastTkActorImpl.h +++ b/sdk/toolkit/source/NvBlastTkActorImpl.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 NVBLASTTKACTORIMPL_H #define NVBLASTTKACTORIMPL_H @@ -98,6 +116,8 @@ public: virtual uint32_t getJointCount() const override; virtual uint32_t getJoints(TkJoint** joints, uint32_t jointsSize) const override; + + virtual bool isBoundToWorld() const override; // End TkActor // Begin TkObject @@ -215,7 +235,7 @@ private: const void* m_material; //!< for Buffered type const NvBlastProgramParams* m_programParams; //!< for Plain type }; - TkArray<char>::type m_damageDescs; + Array<char>::type m_damageDescs; uint32_t m_damageDescCount; }; @@ -247,7 +267,7 @@ private: TkGroupImpl* m_group; //!< The TkGroupImpl (if any) to which this actor belongs uint32_t m_groupJobIndex; //!< The index of this actor's job within its group's job list physx::PxFlags<TkActorFlag::Enum, char> m_flags; //!< Status flags for this actor - TkArray<DamageData>::type m_damageBuffer; //!< Buffered damage input + Array<DamageData>::type m_damageBuffer; //!< Buffered damage input uint32_t m_jointCount; //!< The number of joints referenced in m_jointList DList m_jointList; //!< A doubly-linked list of joint references @@ -276,7 +296,7 @@ NV_INLINE TkFamilyImpl& TkActorImpl::getFamilyImpl() const NV_INLINE uint32_t TkActorImpl::getIndexInternal() const { NVBLAST_ASSERT(isActive()); - return NvBlastActorGetIndex(m_actorLL, TkFrameworkImpl::get()->log); + return NvBlastActorGetIndex(m_actorLL, logLL); } @@ -343,7 +363,7 @@ NV_INLINE void TkActorImpl::DamageData::generateFracture(NvBlastFractureBuffers* { if (getType() == Plain) { - NvBlastActorGenerateFracture(commandBuffers, actorLL, m_program, m_programParams, TkFrameworkImpl::get()->log, timers); + NvBlastActorGenerateFracture(commandBuffers, actorLL, m_program, m_programParams, logLL, timers); } else { @@ -352,7 +372,7 @@ NV_INLINE void TkActorImpl::DamageData::generateFracture(NvBlastFractureBuffers* m_damageDescCount, m_material, }; - NvBlastActorGenerateFracture(commandBuffers, actorLL, m_program, &programParams, TkFrameworkImpl::get()->log, timers); + NvBlastActorGenerateFracture(commandBuffers, actorLL, m_program, &programParams, logLL, timers); } } diff --git a/sdk/toolkit/source/NvBlastTkAllocator.cpp b/sdk/toolkit/source/NvBlastTkAllocator.cpp deleted file mode 100644 index b1c2c65..0000000 --- a/sdk/toolkit/source/NvBlastTkAllocator.cpp +++ /dev/null @@ -1,22 +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 "NvBlastTkAllocator.h" - - -namespace Nv -{ -namespace Blast -{ - -physx::PxAllocatorCallback* TkAllocator::s_allocatorCallback = nullptr; - -} // namespace Blast -} // namespace Nv diff --git a/sdk/toolkit/source/NvBlastTkAllocator.h b/sdk/toolkit/source/NvBlastTkAllocator.h deleted file mode 100644 index abc7b16..0000000 --- a/sdk/toolkit/source/NvBlastTkAllocator.h +++ /dev/null @@ -1,49 +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 NVBLASTTKALLOCATOR_H -#define NVBLASTTKALLOCATOR_H - -#include "PxAllocatorCallback.h" - - -namespace Nv -{ -namespace Blast -{ - -/** -An allocator which can be used in PxShared containers. -*/ -class TkAllocator -{ -public: - TkAllocator(const char* = 0) - { - } - - void* allocate(size_t size, const char* file, int line) - { - return s_allocatorCallback->allocate(size, nullptr, file, line); - } - - void deallocate(void* ptr) - { - return s_allocatorCallback->deallocate(ptr); - } - - static physx::PxAllocatorCallback* s_allocatorCallback; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTTKALLOCATOR_H diff --git a/sdk/toolkit/source/NvBlastTkArray.h b/sdk/toolkit/source/NvBlastTkArray.h deleted file mode 100644 index c07dc11..0000000 --- a/sdk/toolkit/source/NvBlastTkArray.h +++ /dev/null @@ -1,41 +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 NVBLASTTKARRAY_H -#define NVBLASTTKARRAY_H - - -#include "NvBlastTkAllocator.h" -#include "PsInlineArray.h" - - -namespace Nv -{ -namespace Blast -{ - -template <class T> -struct TkArray -{ - typedef physx::shdfnd::Array<T, TkAllocator> type; -}; - - -template <class T, uint32_t N> -struct TkInlineArray -{ - typedef physx::shdfnd::InlineArray<T, N, TkAllocator> type; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTTKARRAY_H diff --git a/sdk/toolkit/source/NvBlastTkAssetImpl.cpp b/sdk/toolkit/source/NvBlastTkAssetImpl.cpp index 577d46b..2088ce8 100644 --- a/sdk/toolkit/source/NvBlastTkAssetImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkAssetImpl.cpp @@ -1,12 +1,29 @@ -/* -* 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 "NvBlastTkFrameworkImpl.h" @@ -17,11 +34,6 @@ #include "NvBlastMemory.h" #include "Px.h" -#include "PxFileBuf.h" -#include "PxAllocatorCallback.h" - - -using namespace physx::general_PxIOStream2; namespace Nv @@ -31,7 +43,7 @@ namespace Blast //////// Static data //////// -NVBLASTTK_DEFINE_TYPE_SERIALIZABLE(Asset); +NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Asset); //////// Member functions //////// @@ -52,7 +64,7 @@ TkAssetImpl::~TkAssetImpl() { if (m_assetLL != nullptr && m_ownsAsset) { - TkFrameworkImpl::get()->free(m_assetLL); + NVBLAST_FREE(m_assetLL); } } @@ -65,43 +77,43 @@ const NvBlastAsset* TkAssetImpl::getAssetLL() const uint32_t TkAssetImpl::getChunkCount() const { - return NvBlastAssetGetChunkCount(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetChunkCount(m_assetLL, logLL); } uint32_t TkAssetImpl::getLeafChunkCount() const { - return NvBlastAssetGetLeafChunkCount(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetLeafChunkCount(m_assetLL, logLL); } uint32_t TkAssetImpl::getBondCount() const { - return NvBlastAssetGetBondCount(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetBondCount(m_assetLL, logLL); } const NvBlastChunk* TkAssetImpl::getChunks() const { - return NvBlastAssetGetChunks(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetChunks(m_assetLL, logLL); } const NvBlastBond* TkAssetImpl::getBonds() const { - return NvBlastAssetGetBonds(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetBonds(m_assetLL, logLL); } const NvBlastSupportGraph TkAssetImpl::getGraph() const { - return NvBlastAssetGetSupportGraph(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetSupportGraph(m_assetLL, logLL); } uint32_t TkAssetImpl::getDataSize() const { - return NvBlastAssetGetSize(m_assetLL, TkFrameworkImpl::get()->log); + return NvBlastAssetGetSize(m_assetLL, logLL); } @@ -124,7 +136,7 @@ void TkAssetImpl::release() if (num) { - TkArray<TkIdentifiable*>::type dependents(num); + Array<TkIdentifiable*>::type dependents(num); TkFrameworkImpl::get()->getObjects(dependents.begin(), dependents.size(), tkType); for (TkObject* o : dependents) @@ -137,93 +149,22 @@ void TkAssetImpl::release() } } - NVBLASTTK_DELETE(this, TkAssetImpl); -} - - -bool TkAssetImpl::serialize(PxFileBuf& stream) const -{ - TkFrameworkImpl::get()->serializeHeader(*this, stream); - - // Asset data - const uint32_t assetSize = NvBlastAssetGetSize(m_assetLL, TkFrameworkImpl::get()->log); - stream.storeDword(assetSize); - stream.write(m_assetLL, assetSize); - - // Joint descs - stream.storeDword((uint32_t)m_jointDescs.size()); - for (uint32_t i = 0; i < m_jointDescs.size(); ++i) - { - const TkAssetJointDesc& jointDesc = m_jointDescs[i]; - stream.storeDword(jointDesc.nodeIndices[0]); - stream.storeDword(jointDesc.nodeIndices[1]); - stream.storeFloat(jointDesc.attachPositions[0].x); - stream.storeFloat(jointDesc.attachPositions[0].y); - stream.storeFloat(jointDesc.attachPositions[0].z); - stream.storeFloat(jointDesc.attachPositions[1].x); - stream.storeFloat(jointDesc.attachPositions[1].y); - stream.storeFloat(jointDesc.attachPositions[1].z); - } - - return true; + NVBLAST_DELETE(this, TkAssetImpl); } //////// Static functions //////// -TkSerializable* TkAssetImpl::deserialize(PxFileBuf& stream, const NvBlastID& id) -{ - // Allocate - TkAssetImpl* asset = NVBLASTTK_NEW(TkAssetImpl)(id); - if (asset == nullptr) - { - NVBLASTTK_LOG_ERROR("TkAssetImpl::deserialize: asset allocation failed."); - return nullptr; - } - - // Asset data - const uint32_t assetSize = stream.readDword(); - asset->m_assetLL = static_cast<NvBlastAsset*>(TkFrameworkImpl::get()->alloc(assetSize)); - asset->m_ownsAsset = true; - stream.read(asset->m_assetLL, assetSize); - - // Joint descs - const uint32_t jointDescCount = stream.readDword(); - asset->m_jointDescs.resize(jointDescCount); - for (uint32_t i = 0; i < asset->m_jointDescs.size(); ++i) - { - TkAssetJointDesc& jointDesc = asset->m_jointDescs[i]; - jointDesc.nodeIndices[0] = stream.readDword(); - jointDesc.nodeIndices[1] = stream.readDword(); - jointDesc.attachPositions[0].x = stream.readFloat(); - jointDesc.attachPositions[0].y = stream.readFloat(); - jointDesc.attachPositions[0].z = stream.readFloat(); - jointDesc.attachPositions[1].x = stream.readFloat(); - jointDesc.attachPositions[1].y = stream.readFloat(); - jointDesc.attachPositions[1].z = stream.readFloat(); - } - - - if (asset->m_assetLL == nullptr) - { - asset->release(); - asset = nullptr; - } - - return asset; -} - - TkAssetImpl* TkAssetImpl::create(const TkAssetDesc& desc) { - TkAssetImpl* asset = NVBLASTTK_NEW(TkAssetImpl); + TkAssetImpl* asset = NVBLAST_NEW(TkAssetImpl); - TkArray<char>::type scratch((uint32_t)NvBlastGetRequiredScratchForCreateAsset(&desc, TkFrameworkImpl::get()->log)); - void* mem = TkFrameworkImpl::get()->alloc(NvBlastGetAssetMemorySize(&desc, TkFrameworkImpl::get()->log)); - asset->m_assetLL = NvBlastCreateAsset(mem, &desc, scratch.begin(), TkFrameworkImpl::get()->log); + Array<char>::type scratch((uint32_t)NvBlastGetRequiredScratchForCreateAsset(&desc, logLL)); + void* mem = NVBLAST_ALLOC_NAMED(NvBlastGetAssetMemorySize(&desc, logLL), "TkAssetImpl::create"); + asset->m_assetLL = NvBlastCreateAsset(mem, &desc, scratch.begin(), logLL); if (asset->m_assetLL == nullptr) { - NVBLASTTK_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created."); + NVBLAST_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created."); asset->release(); return nullptr; } @@ -239,20 +180,20 @@ TkAssetImpl* TkAssetImpl::create(const TkAssetDesc& desc) const uint32_t c1 = bondDesc.chunkIndices[1]; if (c0 >= desc.chunkCount || c1 >= desc.chunkCount) { - NVBLASTTK_LOG_WARNING("TkAssetImpl::create: joint flag set for badly described bond. No joint descriptor created."); + NVBLAST_LOG_WARNING("TkAssetImpl::create: joint flag set for badly described bond. No joint descriptor created."); continue; } if (!asset->addJointDesc(c0, c1)) { - NVBLASTTK_LOG_WARNING("TkAssetImpl::create: no bond corresponds to the user-described bond indices. No joint descriptor created."); + NVBLAST_LOG_WARNING("TkAssetImpl::create: no bond corresponds to the user-described bond indices. No joint descriptor created."); } } } } asset->m_ownsAsset = true; -// asset->setID(NvBlastAssetGetID(asset->m_assetLL, TkFrameworkImpl::get()->log)); // Keeping LL and Tk IDs distinct +// asset->setID(NvBlastAssetGetID(asset->m_assetLL, logLL)); // Keeping LL and Tk IDs distinct return asset; } @@ -260,19 +201,19 @@ TkAssetImpl* TkAssetImpl::create(const TkAssetDesc& desc) TkAssetImpl* TkAssetImpl::create(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs, uint32_t jointDescCount, bool ownsAsset) { - TkAssetImpl* asset = NVBLASTTK_NEW(TkAssetImpl); + TkAssetImpl* asset = NVBLAST_NEW(TkAssetImpl); //NOTE: Why are we passing in a const NvBlastAsset* and then discarding the const? asset->m_assetLL = const_cast<NvBlastAsset*>(assetLL); if (asset->m_assetLL == nullptr) { - NVBLASTTK_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created."); + NVBLAST_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created."); asset->release(); return nullptr; } asset->m_ownsAsset = ownsAsset; - asset->setID(NvBlastAssetGetID(asset->m_assetLL, TkFrameworkImpl::get()->log)); + asset->setID(NvBlastAssetGetID(asset->m_assetLL, logLL)); asset->m_jointDescs.resize(jointDescCount); for (uint32_t i = 0; i < asset->m_jointDescs.size(); ++i) @@ -290,16 +231,16 @@ bool TkAssetImpl::addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1) return false; } - const uint32_t upperSupportChunkCount = NvBlastAssetGetFirstSubsupportChunkIndex(m_assetLL, TkFrameworkImpl::get()->log); + const uint32_t upperSupportChunkCount = NvBlastAssetGetFirstSubsupportChunkIndex(m_assetLL, logLL); if (chunkIndex0 >= upperSupportChunkCount || chunkIndex1 >= upperSupportChunkCount) { return false; } - const uint32_t* chunkToGraphNodeMap = NvBlastAssetGetChunkToGraphNodeMap(m_assetLL, TkFrameworkImpl::get()->log); + const uint32_t* chunkToGraphNodeMap = NvBlastAssetGetChunkToGraphNodeMap(m_assetLL, logLL); const uint32_t node0 = chunkToGraphNodeMap[chunkIndex0]; const uint32_t node1 = chunkToGraphNodeMap[chunkIndex1]; - const NvBlastSupportGraph graph = NvBlastAssetGetSupportGraph(m_assetLL, TkFrameworkImpl::get()->log); + const NvBlastSupportGraph graph = NvBlastAssetGetSupportGraph(m_assetLL, logLL); if (node0 >= graph.nodeCount && node1 >= graph.nodeCount) { return false; @@ -317,12 +258,12 @@ bool TkAssetImpl::addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1) } } - if (bondIndex >= NvBlastAssetGetBondCount(m_assetLL, TkFrameworkImpl::get()->log)) + if (bondIndex >= NvBlastAssetGetBondCount(m_assetLL, logLL)) { return false; } - const NvBlastBond& bond = NvBlastAssetGetBonds(m_assetLL, TkFrameworkImpl::get()->log)[bondIndex]; + const NvBlastBond& bond = NvBlastAssetGetBonds(m_assetLL, logLL)[bondIndex]; TkAssetJointDesc jointDesc; jointDesc.attachPositions[0] = jointDesc.attachPositions[1] = physx::PxVec3(bond.centroid[0], bond.centroid[1], bond.centroid[2]); diff --git a/sdk/toolkit/source/NvBlastTkAssetImpl.h b/sdk/toolkit/source/NvBlastTkAssetImpl.h index ae68af8..491263a 100644 --- a/sdk/toolkit/source/NvBlastTkAssetImpl.h +++ b/sdk/toolkit/source/NvBlastTkAssetImpl.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 NVBLASTTKASSETIMPL_H #define NVBLASTTKASSETIMPL_H @@ -16,7 +34,7 @@ #include "NvBlastTkJoint.h" #include "NvBlastTkAsset.h" #include "NvBlastTkTypeImpl.h" -#include "NvBlastTkArray.h" +#include "NvBlastArray.h" // Forward declarations @@ -34,28 +52,11 @@ Implementation of TkAsset NVBLASTTK_IMPL_DECLARE(Asset) { public: - /** - 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 - }; - TkAssetImpl(); TkAssetImpl(const NvBlastID& id); ~TkAssetImpl(); - NVBLASTTK_IMPL_DEFINE_SERIALIZABLE('A', 'S', 'S', 'T'); + NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('A', 'S', 'S', 'T'); // Public methods @@ -131,7 +132,7 @@ private: bool addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1); NvBlastAsset* m_assetLL; //!< The underlying low-level asset. - TkArray<TkAssetJointDesc>::type m_jointDescs; //!< The array of internal joint descriptors. + Array<TkAssetJointDesc>::type m_jointDescs; //!< The array of internal joint descriptors. bool m_ownsAsset; //!< Whether or not this asset should release its low-level asset upon its own release. }; diff --git a/sdk/toolkit/source/NvBlastTkCommon.h b/sdk/toolkit/source/NvBlastTkCommon.h index edc1a91..31eac7a 100644 --- a/sdk/toolkit/source/NvBlastTkCommon.h +++ b/sdk/toolkit/source/NvBlastTkCommon.h @@ -1,25 +1,39 @@ -/* -* 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 NVBLASTTKCOMMON_H #define NVBLASTTKCOMMON_H -#include "NvPreprocessor.h" +#include "NvBlastGlobals.h" #include "NvBlastTkGUID.h" -// Macro to load a uint32_t (or larger) with four characters -#define NVBLASTTK_FOURCC(_a, _b, _c, _d) ( (uint32_t)(_a) | (uint32_t)(_b)<<8 | (uint32_t)(_c)<<16 | (uint32_t)(_d)<<24 ) - - // Macro to define standard object classes. An intermediate class is defined which holds common implementations. #define NVBLASTTK_IMPL_DECLARE(_name) \ class Tk##_name##Type : public Tk##_name \ @@ -82,29 +96,12 @@ class Tk##_name##Impl final : public Tk##_name##Type /* Enums */ \ \ /* Generate a ClassID enum used to identify this TkIdentifiable. */ \ - enum { ClassID = NVBLASTTK_FOURCC(_id0, _id1, _id2, _id3) } - - -// Macro to declare standard object interfaces, enums, etc (serializable version) -#define NVBLASTTK_IMPL_DEFINE_SERIALIZABLE(_id0, _id1, _id2, _id3) \ - NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE(_id0, _id1, _id2, _id3); \ - \ - /* Begin TkSerializable */ \ - virtual bool serialize(physx::general_PxIOStream2::PxFileBuf& stream) const override; \ - /* End TkSerializable */ \ - \ - /* Static deserialization function, called by TkFrameworkImpl::deserialize after header data */ \ - static TkSerializable* deserialize(physx::general_PxIOStream2::PxFileBuf& stream, const NvBlastID& id) + enum { ClassID = NVBLAST_FOURCC(_id0, _id1, _id2, _id3) } // Macro to define class type data #define NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(_name) \ - TkTypeImpl Tk##_name##Type::s_type("Tk" #_name, Tk##_name##Impl::ClassID, 0, nullptr) - - -// Macro to define class type data (serializable version) -#define NVBLASTTK_DEFINE_TYPE_SERIALIZABLE(_name) \ - TkTypeImpl Tk##_name##Type::s_type("Tk" #_name, Tk##_name##Impl::ClassID, Tk##_name##Impl::Version::Current, Tk##_name##Impl::deserialize) + TkTypeImpl Tk##_name##Type::s_type("Tk" #_name, Tk##_name##Impl::ClassID, 0) #endif // ifndef NVBLASTTKCOMMON_H diff --git a/sdk/toolkit/source/NvBlastTkEventQueue.h b/sdk/toolkit/source/NvBlastTkEventQueue.h index 00a1a61..9422111 100644 --- a/sdk/toolkit/source/NvBlastTkEventQueue.h +++ b/sdk/toolkit/source/NvBlastTkEventQueue.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 NVBLASTTKEVENTQUEUE_H #define NVBLASTTKEVENTQUEUE_H @@ -17,7 +35,6 @@ #include <mutex> #include <atomic> -#include "PxAllocatorCallback.h" #include "NvBlastTkFrameworkImpl.h" #include "NvBlastAssert.h" @@ -50,7 +67,7 @@ public: Peek events queue for dispatch. Do not use in protected state. */ - operator const TkArray<TkEvent>::type&() + operator const Array<TkEvent>::type&() { NVBLAST_ASSERT(m_allowAllocs); NVBLAST_ASSERT(m_currentEvent == m_events.size()); @@ -83,7 +100,7 @@ public: m_currentEvent = 0; for (void* mem : m_memory) { - NVBLASTTK_FREE(mem); + NVBLAST_FREE(mem); } m_memory.clear(); m_currentData = 0; @@ -186,13 +203,13 @@ public: /** Proxy function to dispatch events to this queue's listeners. */ - void dispatch(const TkArray<TkEvent>::type& events) const + void dispatch(const Array<TkEvent>::type& events) const { if (events.size()) { for (TkEventListener* l : m_listeners) { - PERF_SCOPE_M("TkEventQueue::dispatch"); + BLAST_PROFILE_SCOPE_M("TkEventQueue::dispatch"); l->receive(events.begin(), events.size()); } } @@ -207,21 +224,21 @@ private: void* memory = nullptr; if (size > 0) { - memory = NVBLASTTK_ALLOC(size, "TkEventQueue Data"); + memory = NVBLAST_ALLOC_NAMED(size, "TkEventQueue Data"); m_memory.pushBack(memory); } return memory; } - TkArray<TkEvent>::type m_events; //!< holds events - TkArray<void*>::type m_memory; //!< holds allocated data memory blocks + Array<TkEvent>::type m_events; //!< holds events + Array<void*>::type m_memory; //!< holds allocated data memory blocks std::atomic<uint32_t> m_currentEvent; //!< reference index for event insertion std::atomic<uint32_t> m_currentData; //!< reference index for data insertion size_t m_poolCapacity; //!< size of the currently active memory block (m_pool) uint8_t* m_pool; //!< the current memory block allocData() uses bool m_allowAllocs; //!< assert guard - TkInlineArray<TkEventListener*,4>::type m_listeners; //!< objects to dispatch to + InlineArray<TkEventListener*,4>::type m_listeners; //!< objects to dispatch to }; } // namespace Blast diff --git a/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp b/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp index 33baafe..4879535 100644 --- a/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkFamilyImpl.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 "NvBlastTkFrameworkImpl.h" #include "NvBlastTkFamilyImpl.h" @@ -16,14 +34,10 @@ #include "NvBlastTkJointImpl.h" #include "Px.h" -#include "PxFileBuf.h" -#include "PxAllocatorCallback.h" #include "NvBlastIndexFns.h" #include "NvBlastMemory.h" -using namespace physx::general_PxIOStream2; - namespace Nv { @@ -32,7 +46,7 @@ namespace Blast //////// Static data //////// -NVBLASTTK_DEFINE_TYPE_SERIALIZABLE(Family); +NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Family); //////// Member functions //////// @@ -51,12 +65,12 @@ TkFamilyImpl::~TkFamilyImpl() { if (m_familyLL != nullptr) { - uint32_t familyActorCount = NvBlastFamilyGetActorCount(m_familyLL, TkFrameworkImpl::get()->log); + uint32_t familyActorCount = NvBlastFamilyGetActorCount(m_familyLL, logLL); if (familyActorCount != 0) { - NVBLASTTK_LOG_WARNING("TkFamilyImpl::~TkFamilyImpl(): family actor count is not 0."); + NVBLAST_LOG_WARNING("TkFamilyImpl::~TkFamilyImpl(): family actor count is not 0."); } - TkFrameworkImpl::get()->free(m_familyLL); + NVBLAST_FREE(m_familyLL); } } @@ -73,7 +87,7 @@ void TkFamilyImpl::release() m_actors.clear(); - NVBLASTTK_DELETE(this, TkFamilyImpl); + NVBLAST_DELETE(this, TkFamilyImpl); } @@ -112,7 +126,7 @@ uint32_t TkFamilyImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t uint32_t actorCount = getActorCount(); if (actorCount <= indexStart) { - NVBLASTTK_LOG_WARNING("TkFamilyImpl::getActors: indexStart beyond end of actor list."); + NVBLAST_LOG_WARNING("TkFamilyImpl::getActors: indexStart beyond end of actor list."); return 0; } @@ -146,22 +160,22 @@ uint32_t TkFamilyImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t } -NV_INLINE bool areLLActorsEqual(const NvBlastActor* actor0, const NvBlastActor* actor1, TkArray<uint32_t>::type& scratch) +NV_INLINE bool areLLActorsEqual(const NvBlastActor* actor0, const NvBlastActor* actor1, Array<uint32_t>::type& scratch) { - if (NvBlastActorGetGraphNodeCount(actor0, TkFrameworkImpl::get()->log) != NvBlastActorGetGraphNodeCount(actor1, TkFrameworkImpl::get()->log)) + if (NvBlastActorGetGraphNodeCount(actor0, logLL) != NvBlastActorGetGraphNodeCount(actor1, logLL)) { return false; } - const uint32_t chunkCount = NvBlastActorGetVisibleChunkCount(actor0, TkFrameworkImpl::get()->log); - if (chunkCount != NvBlastActorGetVisibleChunkCount(actor1, TkFrameworkImpl::get()->log)) + const uint32_t chunkCount = NvBlastActorGetVisibleChunkCount(actor0, logLL); + if (chunkCount != NvBlastActorGetVisibleChunkCount(actor1, logLL)) { return false; } scratch.resize(chunkCount * 2); - NvBlastActorGetVisibleChunkIndices(scratch.begin(), chunkCount, actor0, TkFrameworkImpl::get()->log); - NvBlastActorGetVisibleChunkIndices(scratch.begin() + chunkCount, chunkCount, actor1, TkFrameworkImpl::get()->log); + NvBlastActorGetVisibleChunkIndices(scratch.begin(), chunkCount, actor0, logLL); + NvBlastActorGetVisibleChunkIndices(scratch.begin() + chunkCount, chunkCount, actor1, logLL); return memcmp(scratch.begin(), scratch.begin() + chunkCount, chunkCount * sizeof(uint32_t)) == 0; } @@ -170,21 +184,21 @@ void TkFamilyImpl::reinitialize(const NvBlastFamily* newFamily, TkGroup* group) { NVBLAST_ASSERT(newFamily); #if NV_ENABLE_ASSERTS - NvBlastID id0 = NvBlastFamilyGetAssetID(m_familyLL, TkFrameworkImpl::get()->log); - NvBlastID id1 = NvBlastFamilyGetAssetID(newFamily, TkFrameworkImpl::get()->log); + NvBlastID id0 = NvBlastFamilyGetAssetID(m_familyLL, logLL); + NvBlastID id1 = NvBlastFamilyGetAssetID(newFamily, logLL); NVBLAST_ASSERT(TkGUIDsEqual(&id0, &id1)); #endif - NVBLAST_ASSERT(NvBlastFamilyGetSize(m_familyLL, TkFrameworkImpl::get()->log) == NvBlastFamilyGetSize(newFamily, TkFrameworkImpl::get()->log)); + NVBLAST_ASSERT(NvBlastFamilyGetSize(m_familyLL, logLL) == NvBlastFamilyGetSize(newFamily, logLL)); // alloc and init new family - const uint32_t blockSize = NvBlastFamilyGetSize(newFamily, TkFrameworkImpl::get()->log); - NvBlastFamily* newFamilyCopy = (NvBlastFamily*)TkFrameworkImpl::get()->alloc(blockSize); + const uint32_t blockSize = NvBlastFamilyGetSize(newFamily, logLL); + NvBlastFamily* newFamilyCopy = (NvBlastFamily*)NVBLAST_ALLOC_NAMED(blockSize, "TkFamilyImpl::reinitialize"); memcpy(newFamilyCopy, newFamily, blockSize); - NvBlastFamilySetAsset(newFamilyCopy, m_asset->getAssetLL(), TkFrameworkImpl::get()->log); + NvBlastFamilySetAsset(newFamilyCopy, m_asset->getAssetLL(), logLL); // get actors from new family - TkArray<NvBlastActor*>::type newLLActors(NvBlastFamilyGetActorCount(newFamilyCopy, TkFrameworkImpl::get()->log)); - uint32_t actorCount = NvBlastFamilyGetActors(newLLActors.begin(), newLLActors.size(), newFamilyCopy, TkFrameworkImpl::get()->log); + Array<NvBlastActor*>::type newLLActors(NvBlastFamilyGetActorCount(newFamilyCopy, logLL)); + uint32_t actorCount = NvBlastFamilyGetActors(newLLActors.begin(), newLLActors.size(), newFamilyCopy, logLL); // reset actor families to nullptr (we use it as a flag later) for (TkActorImpl& actor : m_actors) @@ -197,17 +211,17 @@ void TkFamilyImpl::reinitialize(const NvBlastFamily* newFamily, TkGroup* group) // prepare split event with new actors auto newActorsSplitEvent = getQueue().allocData<TkSplitEvent>(); - TkArray<TkActor*>::type children(actorCount); + Array<TkActor*>::type children(actorCount); children.resizeUninitialized(0); newActorsSplitEvent->children = children.begin(); // scratch - TkArray<uint32_t>::type scratch(m_asset->getChunkCount()); + Array<uint32_t>::type scratch(m_asset->getChunkCount()); for (uint32_t i = 0; i < actorCount; ++i) { NvBlastActor* newLLActor = newLLActors[i]; - uint32_t actorIndex = NvBlastActorGetIndex(newLLActor, TkFrameworkImpl::get()->log); + uint32_t actorIndex = NvBlastActorGetIndex(newLLActor, logLL); TkActorImpl& tkActor = *getActorByIndex(actorIndex); tkActor.m_family = this; @@ -281,7 +295,7 @@ void TkFamilyImpl::reinitialize(const NvBlastFamily* newFamily, TkGroup* group) } // replace family - TkFrameworkImpl::get()->free(m_familyLL); + NVBLAST_FREE(m_familyLL); m_familyLL = newFamilyCopy; // update joints @@ -299,13 +313,13 @@ void TkFamilyImpl::reinitialize(const NvBlastFamily* newFamily, TkGroup* group) TkActorImpl* TkFamilyImpl::getActorByChunk(uint32_t chunk) { - if (chunk >= NvBlastAssetGetChunkCount(m_asset->getAssetLLInternal(), TkFrameworkImpl::get()->log)) + if (chunk >= NvBlastAssetGetChunkCount(m_asset->getAssetLLInternal(), logLL)) { - NVBLASTTK_LOG_WARNING("TkFamilyImpl::getActorByChunk: invalid chunk index. Returning NULL."); + NVBLAST_LOG_WARNING("TkFamilyImpl::getActorByChunk: invalid chunk index. Returning NULL."); return nullptr; } - NvBlastActor* actorLL = NvBlastFamilyGetChunkActor(m_familyLL, chunk, TkFrameworkImpl::get()->log); + NvBlastActor* actorLL = NvBlastFamilyGetChunkActor(m_familyLL, chunk, logLL); return actorLL ? getActorByActorLL(actorLL) : nullptr; } @@ -441,293 +455,24 @@ const TkAsset* TkFamilyImpl::getAsset() const } -bool TkFamilyImpl::serialize(PxFileBuf& stream) const -{ - TkFrameworkImpl::get()->serializeHeader(*this, stream); - - if (m_material != nullptr) - { - NVBLASTTK_LOG_WARNING("TkFamilyImpl::serialize(): Material pointer is not nullptr, it will be lost during serialization."); - } - - NVBLASTTK_CHECK_ERROR(m_asset != nullptr, "TkFamilyImpl::serialize(): TkFamily asset is nullptr, can't be serialized.", return false); - NVBLASTTK_CHECK_ERROR(m_familyLL != nullptr, "TkFamilyImpl::serialize(): TkFamily family is nullptr, can't be serialized.", return false); - - // Asset ID - const NvBlastID& assetID = m_asset->getID(); - NVBLASTTK_CHECK_ERROR(!TkGUIDIsZero(&assetID), "TkFamilyImpl::serialize(): Associated asset doesn't have an ID set.", return false); - stream.write(&assetID, sizeof(NvBlastID)); - - // Family - const uint32_t familySize = NvBlastFamilyGetSize(m_familyLL, TkFrameworkImpl::get()->log); - stream.storeDword(familySize); - stream.write(m_familyLL, familySize); - - //// Joints //// - - // Internal joint data - stream.storeDword(m_internalJointCount); - - // External joint family ID list - stream.storeDword(m_jointSets.size()); - for (uint32_t i = 0; i < m_jointSets.size(); ++i) - { - const JointSet* jointSet = m_jointSets[i]; - stream.write(&jointSet->m_familyID, sizeof(NvBlastID)); - } - - // Actor joint lists - TkJointImpl* internalJoints = getInternalJoints(); - for (uint32_t actorNum = 0; actorNum < m_actors.size(); ++actorNum) - { - const TkActorImpl& actor = m_actors[actorNum]; - if (!actor.isActive()) - { - continue; // We may need a better way of iterating through active actors - } - - stream.storeDword(actor.getJointCount()); - - for (TkActorImpl::JointIt j(actor); (bool)j; ++j) - { - TkJointImpl* joint = *j; - - const TkJointData& jointData = joint->getDataInternal(); - NVBLAST_ASSERT(jointData.actors[0] == &actor || jointData.actors[1] == &actor); - - const uint32_t attachmentFlags = (uint32_t)(jointData.actors[0] == &actor) | (uint32_t)(jointData.actors[1] == &actor) << 1; - stream.storeDword(attachmentFlags); - - const TkActorImpl* otherActor = static_cast<const TkActorImpl*>(jointData.actors[(attachmentFlags >> 1) ^ 1]); - - if (joint->m_owner == this) - { - // Internal joint - write internal joint index - const uint32_t jointIndex = static_cast<uint32_t>(joint - internalJoints); - stream.storeDword(jointIndex); - if (otherActor != nullptr && otherActor->getIndexInternal() < actorNum) // No need to write the joint data, it has already been written - { - continue; - } - } - else - { - // External joint - write external family index and joint information - stream.storeDword(invalidIndex<uint32_t>()); // Denotes external joint - - const FamilyIDMap::Entry* e = m_familyIDMap.find(getFamilyID(otherActor)); - NVBLASTTK_CHECK_ERROR(e != nullptr, "TkFamilyImpl::deserialize(): Bad data - attached family's ID not recorded.", return false); - - stream.storeDword(e->second); // Write family ID index - } - - // Write joint data - for (int side = 0; side < 2; ++side) - { - stream.storeDword(jointData.chunkIndices[side]); - const physx::PxVec3& attachPosition = jointData.attachPositions[side]; - stream.storeFloat(attachPosition.x); stream.storeFloat(attachPosition.y); stream.storeFloat(attachPosition.z); - } - } - } - - return true; -} - - //////// Static functions //////// -TkSerializable* TkFamilyImpl::deserialize(PxFileBuf& stream, const NvBlastID& id) -{ - // Asset resolve - NvBlastID assetID; - stream.read(&assetID, sizeof(NvBlastID)); - TkIdentifiable* object = TkFrameworkImpl::get()->findObjectByIDInternal(assetID); - NVBLASTTK_CHECK_ERROR(object && object->getType() == TkAssetImpl::s_type, "TkFamilyImpl::deserialize: can't find asset with corresponding ID.", return nullptr); - TkAssetImpl* asset = static_cast<TkAssetImpl*>(object); - - // Allocate - TkFamilyImpl* family = NVBLASTTK_NEW(TkFamilyImpl)(id); - NVBLASTTK_CHECK_ERROR(family != nullptr, "TkFamilyImpl::deserialize: family allocation failed.", return nullptr); - - // associate with found asset - family->m_asset = asset; - - // Family - const uint32_t familySize = stream.readDword(); - family->m_familyLL = static_cast<NvBlastFamily*>(TkFrameworkImpl::get()->alloc(familySize)); - stream.read(family->m_familyLL, familySize); - - if (family->m_familyLL == nullptr) - { - NVBLASTTK_LOG_ERROR("TkFamilyImpl::deserialize: low-level family could not be created."); - family->release(); - return nullptr; - } - -#if NV_ENABLE_ASSERTS && 0 - NvBlastID id = NvBlastFamilyGetAssetID(family->m_familyLL, TkFrameworkImpl::get()->log); - NVBLAST_ASSERT(TkGUIDsEqual(&id, &assetID)); -#endif - - // preallocate actors - uint32_t maxActorCount = NvBlastFamilyGetMaxActorCount(family->m_familyLL, TkFrameworkImpl::get()->log); - family->m_actors.resize(maxActorCount); - - // get actors from family - TkArray<NvBlastActor*>::type newLLActors(NvBlastFamilyGetActorCount(family->m_familyLL, TkFrameworkImpl::get()->log)); - uint32_t actorCount = NvBlastFamilyGetActors(newLLActors.begin(), newLLActors.size(), family->m_familyLL, TkFrameworkImpl::get()->log); - - // fill actors - for (uint32_t i = 0; i < actorCount; ++i) - { - NvBlastActor* newLLActor = newLLActors[i]; - uint32_t actorIndex = NvBlastActorGetIndex(newLLActor, TkFrameworkImpl::get()->log); - TkActorImpl& tkActor = *family->getActorByIndex(actorIndex); - - tkActor.m_family = family; - tkActor.m_actorLL = newLLActor; - } - - //// Create joints //// - - // internal - family->m_internalJointCount = stream.readDword(); - family->m_internalJointBuffer.resize(family->m_internalJointCount * sizeof(TkJointImpl), '\0'); - TkJointImpl* internalJoints = family->getInternalJoints(); - - // external joint family ID list - const uint32_t jointSetCount = stream.readDword(); - family->m_jointSets.resize(jointSetCount); - for (uint32_t i = 0; i < jointSetCount; ++i) - { - family->m_jointSets[i] = NVBLASTTK_NEW(JointSet); - stream.read(&family->m_jointSets[i]->m_familyID, sizeof(NvBlastID)); - family->m_familyIDMap[family->m_jointSets[i]->m_familyID] = i; - } - - // fill actor joint lists - for (uint32_t actorNum = 0; actorNum < family->m_actors.size(); ++actorNum) - { - TkActorImpl& actor = family->m_actors[actorNum]; - if (!actor.isActive()) - { - continue; // We may need a better way of iterating through active actors - } - - // Read joint information - uint32_t jointCount = stream.readDword(); - while (jointCount--) - { - const uint32_t attachmentFlags = stream.readDword(); - const uint32_t jointIndex = stream.readDword(); - if (!isInvalidIndex(jointIndex)) - { - // Internal joint - TkJointImpl& joint = internalJoints[jointIndex]; - TkJointData& jointData = joint.getDataWritable(); - - // Initialize joint if it has not been encountered yet - NVBLAST_ASSERT((joint.m_links[0].m_joint == nullptr) == (joint.m_links[1].m_joint == nullptr)); - if (joint.m_links[0].m_joint == nullptr) - { - new (&joint) TkJointImpl; - joint.m_owner = family; - for (int side = 0; side < 2; ++side) - { - jointData.chunkIndices[side] = stream.readDword(); - physx::PxVec3& attachPosition = jointData.attachPositions[side]; - attachPosition.x = stream.readFloat(); attachPosition.y = stream.readFloat(); attachPosition.z = stream.readFloat(); - } - } - - if (attachmentFlags & 1) - { - jointData.actors[0] = &actor; - actor.addJoint(joint.m_links[0]); - } - - if (attachmentFlags & 2) - { - jointData.actors[1] = &actor; - if (jointData.actors[0] != jointData.actors[1]) - { - actor.addJoint(joint.m_links[1]); - } - } - } - else - { - // External joint - const uint32_t otherFamilyIndex = stream.readDword(); - NVBLASTTK_CHECK_ERROR(otherFamilyIndex < family->m_jointSets.size(), "TkFamilyImpl::deserialize: family allocation failed.", return nullptr); - const NvBlastID& otherFamilyID = family->m_jointSets[otherFamilyIndex]->m_familyID; - TkFamilyImpl* otherFamily = static_cast<TkFamilyImpl*>(TkFrameworkImpl::get()->findObjectByIDInternal(otherFamilyID)); - - TkJointDesc jointDesc; - for (int side = 0; side < 2; ++side) - { - jointDesc.chunkIndices[side] = stream.readDword(); - physx::PxVec3& attachPosition = jointDesc.attachPositions[side]; - attachPosition.x = stream.readFloat(); attachPosition.y = stream.readFloat(); attachPosition.z = stream.readFloat(); - } - - NVBLASTTK_CHECK_ERROR(attachmentFlags != 3, "TkFamilyImpl::deserialize: both attached actors are the same in an external joint.", return nullptr); - - const uint32_t attachmentIndex = attachmentFlags >> 1; - - TkJointImpl** jointHandle = family->createExternalJointHandle(otherFamilyID, jointDesc.chunkIndices[attachmentIndex], jointDesc.chunkIndices[attachmentIndex ^ 1]); - NVBLASTTK_CHECK_ERROR(jointHandle != nullptr, "TkFamilyImpl::deserialize: joint handle could not be created.", return nullptr); - - if (otherFamily == nullptr) - { - // Other family does not exist yet, we'll create the joint - jointDesc.families[attachmentIndex] = family; - jointDesc.families[attachmentIndex ^ 1] = nullptr; - - TkJointImpl* joint = NVBLASTTK_NEW(TkJointImpl)(jointDesc, nullptr); - NVBLASTTK_CHECK_ERROR(joint != nullptr, "TkFamilyImpl::deserialize: joint createion failed.", return nullptr); - - *jointHandle = joint; - - actor.addJoint(joint->m_links[attachmentIndex]); - } - else - { - // Other family exists, and should have created the joint - TkJointImpl* joint = otherFamily->findExternalJoint(family, ExternalJointKey(jointDesc.chunkIndices[attachmentIndex ^ 1], jointDesc.chunkIndices[attachmentIndex])); - NVBLASTTK_CHECK_ERROR(joint != nullptr, "TkFamilyImpl::deserialize: other family should have created joint, but did not.", return nullptr); - - *jointHandle = joint; - - // Add the joint to its actor(s) - joint->getDataWritable().actors[attachmentIndex] = &actor; - actor.addJoint(joint->m_links[attachmentIndex]); - } - } - } - } - - return family; -} - - TkFamilyImpl* TkFamilyImpl::create(const TkAssetImpl* asset) { - TkFamilyImpl* family = NVBLASTTK_NEW(TkFamilyImpl); + TkFamilyImpl* family = NVBLAST_NEW(TkFamilyImpl); family->m_asset = asset; - void* mem = TkFrameworkImpl::get()->alloc(NvBlastAssetGetFamilyMemorySize(asset->getAssetLL(), TkFrameworkImpl::get()->log)); - family->m_familyLL = NvBlastAssetCreateFamily(mem, asset->getAssetLL(), TkFrameworkImpl::get()->log); + void* mem = NVBLAST_ALLOC_NAMED(NvBlastAssetGetFamilyMemorySize(asset->getAssetLL(), logLL), "TkFamilyImpl::create"); + family->m_familyLL = NvBlastAssetCreateFamily(mem, asset->getAssetLL(), logLL); //family->addListener(*TkFrameworkImpl::get()); if (family->m_familyLL == nullptr) { - NVBLASTTK_LOG_ERROR("TkFamilyImpl::create: low-level family could not be created."); + NVBLAST_LOG_ERROR("TkFamilyImpl::create: low-level family could not be created."); family->release(); return nullptr; } - uint32_t maxActorCount = NvBlastFamilyGetMaxActorCount(family->m_familyLL, TkFrameworkImpl::get()->log); + uint32_t maxActorCount = NvBlastFamilyGetMaxActorCount(family->m_familyLL, logLL); family->m_actors.resize(maxActorCount); family->m_internalJointBuffer.resize(asset->getJointDescCountInternal() * sizeof(TkJointImpl), 0); @@ -749,8 +494,8 @@ TkJointImpl** TkFamilyImpl::createExternalJointHandle(const NvBlastID& otherFami } else { - jointSet = NVBLASTTK_NEW(JointSet); - NVBLASTTK_CHECK_ERROR(jointSet != nullptr, "TkFamilyImpl::addExternalJoint: failed to create joint set for other family ID.", return nullptr); + jointSet = NVBLAST_NEW(JointSet); + NVBLAST_CHECK_ERROR(jointSet != nullptr, "TkFamilyImpl::addExternalJoint: failed to create joint set for other family ID.", return nullptr); jointSet->m_familyID = otherFamilyID; otherFamilyIndex = m_jointSets.size(); m_familyIDMap[otherFamilyID] = otherFamilyIndex; @@ -759,7 +504,7 @@ TkJointImpl** TkFamilyImpl::createExternalJointHandle(const NvBlastID& otherFami const ExternalJointKey key(chunkIndex0, chunkIndex1); const bool jointExists = jointSet->m_joints.find(key) != nullptr; - NVBLASTTK_CHECK_WARNING(!jointExists, "TkFamilyImpl::addExternalJoint: joint already added.", return nullptr); + NVBLAST_CHECK_WARNING(!jointExists, "TkFamilyImpl::addExternalJoint: joint already added.", return nullptr); return &jointSet->m_joints[key]; } @@ -771,13 +516,13 @@ bool TkFamilyImpl::deleteExternalJointHandle(TkJointImpl*& joint, const NvBlastI if (jointSetIndexEntry != nullptr) { const uint32_t jointSetIndex = jointSetIndexEntry->second; - TkHashMap<ExternalJointKey, TkJointImpl*>::type::Entry e; + HashMap<ExternalJointKey, TkJointImpl*>::type::Entry e; if (m_jointSets[jointSetIndex]->m_joints.erase(ExternalJointKey(chunkIndex0, chunkIndex1), e)) { // Delete the joint set if it is empty if (m_jointSets[jointSetIndex]->m_joints.size() == 0) { - NVBLASTTK_DELETE(m_jointSets[jointSetIndex], JointSet); + NVBLAST_DELETE(m_jointSets[jointSetIndex], JointSet); m_jointSets.replaceWithLast(jointSetIndex); m_familyIDMap.erase(otherFamilyID); if (jointSetIndex < m_jointSets.size()) @@ -801,7 +546,7 @@ TkJointImpl* TkFamilyImpl::findExternalJoint(const TkFamilyImpl* otherFamily, Ex const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(getFamilyID(otherFamily)); if (jointSetIndexEntry != nullptr) { - const TkHashMap<ExternalJointKey, TkJointImpl*>::type::Entry* e = m_jointSets[jointSetIndexEntry->second]->m_joints.find(key); + const HashMap<ExternalJointKey, TkJointImpl*>::type::Entry* e = m_jointSets[jointSetIndexEntry->second]->m_joints.find(key); if (e != nullptr) { return e->second; diff --git a/sdk/toolkit/source/NvBlastTkFamilyImpl.h b/sdk/toolkit/source/NvBlastTkFamilyImpl.h index 571ee75..577326b 100644 --- a/sdk/toolkit/source/NvBlastTkFamilyImpl.h +++ b/sdk/toolkit/source/NvBlastTkFamilyImpl.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 NVBLASTTKFAMILYIMPL_H #define NVBLASTTKFAMILYIMPL_H @@ -18,8 +36,8 @@ #include "NvBlastTkActorImpl.h" #include "NvBlastTkEventQueue.h" -#include "NvBlastTkHashSet.h" -#include "NvBlastTkHashMap.h" +#include "NvBlastHashSet.h" +#include "NvBlastHashMap.h" #include "NvBlast.h" #include "NvBlastAssert.h" @@ -42,28 +60,11 @@ class TkAssetImpl; NVBLASTTK_IMPL_DECLARE(Family) { public: - /** - 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 - }; - TkFamilyImpl(); TkFamilyImpl(const NvBlastID& id); ~TkFamilyImpl(); - NVBLASTTK_IMPL_DEFINE_SERIALIZABLE('A', 'C', 'T', 'F'); + NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('A', 'C', 'T', 'F'); // Begin TkFamily virtual const NvBlastFamily* getFamilyLL() const override; @@ -108,7 +109,7 @@ public: void updateJoints(TkActorImpl* actor, TkEventQueue* alternateQueue = nullptr); - TkArray<TkActorImpl>::type& getActorsInternal(); + Array<TkActorImpl>::type& getActorsInternal(); uint32_t getInternalJointCount() const; @@ -122,7 +123,7 @@ public: TkActorImpl* getActorByChunk(uint32_t chunkIndex); - typedef physx::shdfnd::Pair<uint32_t, uint32_t> ExternalJointKey; //!< The chunk indices within the TkFamily joined by the joint. This chunks will be a supports chunks. + typedef physx::shdfnd::Pair<uint32_t, uint32_t> ExternalJointKey; //!< The chunk indices within the TkFamily objects joined by the joint. These chunks will be support chunks. TkJointImpl* findExternalJoint(const TkFamilyImpl* otherFamily, ExternalJointKey key) const; @@ -132,16 +133,16 @@ private: struct JointSet { NvBlastID m_familyID; - TkHashMap<ExternalJointKey, TkJointImpl*>::type m_joints; + HashMap<ExternalJointKey, TkJointImpl*>::type m_joints; }; - typedef TkHashMap<NvBlastID, uint32_t>::type FamilyIDMap; + typedef HashMap<NvBlastID, uint32_t>::type FamilyIDMap; NvBlastFamily* m_familyLL; - TkArray<TkActorImpl>::type m_actors; + Array<TkActorImpl>::type m_actors; uint32_t m_internalJointCount; - TkArray<uint8_t>::type m_internalJointBuffer; - TkArray<JointSet*>::type m_jointSets; + Array<uint8_t>::type m_internalJointBuffer; + Array<JointSet*>::type m_jointSets; FamilyIDMap m_familyIDMap; const TkAssetImpl* m_asset; const void* m_material; @@ -168,7 +169,7 @@ NV_INLINE uint32_t TkFamilyImpl::getActorCountInternal() const { NVBLAST_ASSERT(m_familyLL != nullptr); - return NvBlastFamilyGetActorCount(m_familyLL, TkFrameworkImpl::get()->log); + return NvBlastFamilyGetActorCount(m_familyLL, logLL); } @@ -181,7 +182,7 @@ NV_INLINE TkActorImpl* TkFamilyImpl::getActorByIndex(uint32_t index) NV_INLINE TkActorImpl* TkFamilyImpl::getActorByActorLL(const NvBlastActor* actorLL) { - uint32_t index = NvBlastActorGetIndex(actorLL, TkFrameworkImpl::get()->log); + uint32_t index = NvBlastActorGetIndex(actorLL, logLL); return getActorByIndex(index); } @@ -198,7 +199,7 @@ NV_INLINE void TkFamilyImpl::setMaterial(const void* material) } -NV_INLINE TkArray<TkActorImpl>::type& TkFamilyImpl::getActorsInternal() +NV_INLINE Array<TkActorImpl>::type& TkFamilyImpl::getActorsInternal() { return m_actors; } diff --git a/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp b/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp index 6201101..f409785 100644 --- a/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkFrameworkImpl.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 "NvBlastAssert.h" @@ -18,16 +36,13 @@ #include "NvBlastTkJointImpl.h" #include "NvBlastTkTypeImpl.h" -#include "PxAllocatorCallback.h" -#include "PxErrorCallback.h" -#include "PxFileBuf.h" +#include "NvBlastGlobals.h" #include <algorithm> using namespace physx; using namespace physx::shdfnd; -using namespace physx::general_PxIOStream2; NV_INLINE bool operator < (const NvBlastID& id1, const NvBlastID& id2) @@ -83,13 +98,11 @@ bool TkFrameworkImpl::set(TkFrameworkImpl* framework) { if (framework != nullptr) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::set: framework already set. Pass NULL to this function to destroy framework."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::set: framework already set. Pass NULL to this function to destroy framework."); return false; } - PxAllocatorCallback& allocator = s_framework->getAllocatorCallbackInternal(); - s_framework->~TkFrameworkImpl(); - allocator.deallocate(s_framework); + NVBLAST_DELETE(s_framework, TkFrameworkImpl); } s_framework = framework; @@ -98,70 +111,11 @@ bool TkFrameworkImpl::set(TkFrameworkImpl* framework) } -void TkFrameworkImpl::log(int type, const char* msg, const char* file, int line) -{ - if (s_framework == nullptr) - { - return; - } - - PxErrorCode::Enum pxErrorCode = PxErrorCode::eNO_ERROR; - switch (type) - { - case NvBlastMessage::Error: pxErrorCode = PxErrorCode::eINVALID_OPERATION; break; - case NvBlastMessage::Warning: pxErrorCode = PxErrorCode::eDEBUG_WARNING; break; - case NvBlastMessage::Info: pxErrorCode = PxErrorCode::eDEBUG_INFO; break; - case NvBlastMessage::Debug: pxErrorCode = PxErrorCode::eNO_ERROR; break; - } - - s_framework->getErrorCallback().reportError(pxErrorCode, msg, file, line); -} - - -void* TkFrameworkImpl::alloc(size_t size) -{ - if (s_framework == nullptr) - { - return nullptr; - } - - NV_COMPILE_TIME_ASSERT(Alignment > 0 && Alignment <= 256); - - unsigned char* mem = reinterpret_cast<unsigned char*>(s_framework->m_allocatorCallback->allocate(size + (size_t)Alignment, "NvBlast", __FILE__, __LINE__)); - - const unsigned char offset = (unsigned char)((uintptr_t)Alignment - (uintptr_t)mem % (size_t)Alignment - 1); - mem += offset; - *mem++ = offset; - - return mem; -} - - -void TkFrameworkImpl::free(void* mem) -{ - if (s_framework == nullptr) - { - return; - } - - unsigned char* ptr = reinterpret_cast<unsigned char*>(mem); - const unsigned char offset = *--ptr; - - return s_framework->m_allocatorCallback->deallocate(ptr - offset); -} - - //////// TkFrameworkImpl methods //////// -TkFrameworkImpl::TkFrameworkImpl(const TkFrameworkDesc& desc) +TkFrameworkImpl::TkFrameworkImpl() : TkFramework() - , m_errorCallback(desc.errorCallback) - , m_allocatorCallback(desc.allocatorCallback) { - // Static create() function should ensure these pointers are not NULL - NVBLAST_ASSERT(m_errorCallback != nullptr); - NVBLAST_ASSERT(m_allocatorCallback != nullptr); - // Register types m_types.resize(TkTypeIndex::TypeCount); m_objects.resize(TkTypeIndex::TypeCount); @@ -179,7 +133,7 @@ TkFrameworkImpl::~TkFrameworkImpl() void TkFrameworkImpl::release() { // Special release of joints, which are not TkIdentifiable: - TkArray<TkJointImpl*>::type joints; // Since the EraseIterator is not exposed + Array<TkJointImpl*>::type joints; // Since the EraseIterator is not exposed joints.reserve(m_joints.size()); for (auto j = m_joints.getIterator(); !j.done(); ++j) { @@ -195,75 +149,6 @@ void TkFrameworkImpl::release() NVBLASTTK_RELEASE_TYPE(Group); NVBLASTTK_RELEASE_TYPE(Asset); set(nullptr); - Nv::Blast::TkAllocator::s_allocatorCallback = nullptr; -} - - -physx::PxErrorCallback& TkFrameworkImpl::getErrorCallback() const -{ - return getErrorCallbackInternal(); -} - - -physx::PxAllocatorCallback& TkFrameworkImpl::getAllocatorCallback() const -{ - return getAllocatorCallbackInternal(); -} - - -NvBlastLog TkFrameworkImpl::getLogFn() const -{ - return TkFrameworkImpl::log; -} - - -TkSerializable* TkFrameworkImpl::deserialize(PxFileBuf& stream) -{ - // Read framework ID - if (stream.readDword() != ClassID) - { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::deserialize: stream does not contain a BlastTk object."); - return nullptr; - } - - // Read object class ID and get class type data - const auto it = m_typeIDToIndex.find(stream.readDword()); - if (it == nullptr) - { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::deserialize: BlastTk object type unrecognized."); - return nullptr; - } - - const uint32_t index = (*it).second; - NVBLAST_ASSERT(index < m_types.size()); - - const TkTypeImpl* type = m_types[index]; - - // Read object class version and ensure it's current - if (stream.readDword() != type->getVersionInternal()) - { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::deserialize: BlastTk object version does not equal the current version for the loaded type."); - return nullptr; - } - - // Object ID - NvBlastID id; - stream.read(&id, sizeof(NvBlastID)); - - // Serializable user data - const uint32_t lsq = stream.readDword(); - const uint32_t msq = stream.readDword(); - - // All checks out, deserialize - TkSerializable* object = type->getDeserializeFn()(stream, id); - - // Set serializable user data if deserialization was successful - if (object != nullptr) - { - object->userIntData = static_cast<uint64_t>(msq) << 32 | static_cast<uint64_t>(lsq); - } - - return object; } @@ -271,7 +156,7 @@ const TkType* TkFrameworkImpl::getType(TkTypeIndex::Enum typeIndex) const { if (typeIndex < 0 || typeIndex >= TkTypeIndex::TypeCount) { - NVBLASTTK_LOG_WARNING("TkFrameworkImpl::getType: invalid typeIndex."); + NVBLAST_LOG_WARNING("TkFrameworkImpl::getType: invalid typeIndex."); return nullptr; } @@ -285,7 +170,7 @@ TkIdentifiable* TkFrameworkImpl::findObjectByID(const NvBlastID& id) const if (object == nullptr) { - NVBLASTTK_LOG_WARNING("TkFrameworkImpl::findObjectByID: object not found."); + NVBLAST_LOG_WARNING("TkFrameworkImpl::findObjectByID: object not found."); } return object; @@ -298,7 +183,7 @@ uint32_t TkFrameworkImpl::getObjectCount(const TkType& type) const if (index >= m_objects.size()) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized."); return 0; } @@ -313,7 +198,7 @@ uint32_t TkFrameworkImpl::getObjects(TkIdentifiable** buffer, uint32_t bufferSiz if (index >= m_objects.size()) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized."); return 0; } @@ -322,7 +207,7 @@ uint32_t TkFrameworkImpl::getObjects(TkIdentifiable** buffer, uint32_t bufferSiz uint32_t objectCount = objectArray.size(); if (objectCount <= indexStart) { - NVBLASTTK_LOG_WARNING("TkFrameworkImpl::getObjects: indexStart beyond end of object list."); + NVBLAST_LOG_WARNING("TkFrameworkImpl::getObjects: indexStart beyond end of object list."); return 0; } @@ -338,15 +223,15 @@ uint32_t TkFrameworkImpl::getObjects(TkIdentifiable** buffer, uint32_t bufferSiz } -bool TkFrameworkImpl::reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap /*= nullptr*/) const +bool TkFrameworkImpl::reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap /*= nullptr*/, bool keepBondNormalChunkOrder /*= false*/) const { - uint32_t* map = chunkReorderMap != nullptr ? chunkReorderMap : static_cast<uint32_t*>(NVBLASTTK_ALLOC(chunkCount * sizeof(uint32_t), "reorderAssetDescChunks:chunkReorderMap")); - void* scratch = NVBLASTTK_ALLOC(chunkCount * sizeof(NvBlastChunkDesc), "reorderAssetDescChunks:scratch"); - const bool result = NvBlastReorderAssetDescChunks(chunkDescs, chunkCount, bondDescs, bondCount, map, scratch, log); - NVBLASTTK_FREE(scratch); + uint32_t* map = chunkReorderMap != nullptr ? chunkReorderMap : static_cast<uint32_t*>(NVBLAST_ALLOC_NAMED(chunkCount * sizeof(uint32_t), "reorderAssetDescChunks:chunkReorderMap")); + void* scratch = NVBLAST_ALLOC_NAMED(chunkCount * sizeof(NvBlastChunkDesc), "reorderAssetDescChunks:scratch"); + const bool result = NvBlastReorderAssetDescChunks(chunkDescs, chunkCount, bondDescs, bondCount, map, keepBondNormalChunkOrder, scratch, logLL); + NVBLAST_FREE(scratch); if (chunkReorderMap == nullptr) { - NVBLASTTK_FREE(map); + NVBLAST_FREE(map); } return result; } @@ -354,9 +239,9 @@ bool TkFrameworkImpl::reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint3 bool TkFrameworkImpl::ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const { - void* scratch = NVBLASTTK_ALLOC(chunkCount, "ensureAssetExactSupportCoverage:scratch"); - const bool result = NvBlastEnsureAssetExactSupportCoverage(chunkDescs, chunkCount, scratch, log); - NVBLASTTK_FREE(scratch); + void* scratch = NVBLAST_ALLOC_NAMED(chunkCount, "ensureAssetExactSupportCoverage:scratch"); + const bool result = NvBlastEnsureAssetExactSupportCoverage(chunkDescs, chunkCount, scratch, logLL); + NVBLAST_FREE(scratch); return result; } @@ -366,7 +251,7 @@ TkAsset* TkFrameworkImpl::createAsset(const TkAssetDesc& desc) TkAssetImpl* asset = TkAssetImpl::create(desc); if (asset == nullptr) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset."); } return asset; @@ -378,7 +263,7 @@ TkAsset* TkFrameworkImpl::createAsset(const NvBlastAsset* assetLL, Nv::Blast::Tk TkAssetImpl* asset = TkAssetImpl::create(assetLL, jointDescs, jointDescCount, ownsAsset); if (asset == nullptr) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset."); } return asset; @@ -390,7 +275,7 @@ TkGroup* TkFrameworkImpl::createGroup(const TkGroupDesc& desc) TkGroupImpl* group = TkGroupImpl::create(desc); if (group == nullptr) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::createGroup: failed to create group."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::createGroup: failed to create group."); } return group; @@ -402,7 +287,7 @@ TkActor* TkFrameworkImpl::createActor(const TkActorDesc& desc) TkActor* actor = TkActorImpl::create(desc); if (actor == nullptr) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::createActor: failed to create actor."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::createActor: failed to create actor."); } return actor; @@ -417,35 +302,35 @@ TkJoint* TkFrameworkImpl::createJoint(const TkJointDesc& desc) TkFamilyImpl* family0 = static_cast<TkFamilyImpl*>(desc.families[0]); TkFamilyImpl* family1 = static_cast<TkFamilyImpl*>(desc.families[1]); - NVBLASTTK_CHECK_ERROR(family0 != nullptr || family1 != nullptr, "TkFrameworkImpl::createJoint: at least one family in the TkJointDesc must be valid.", return nullptr); + NVBLAST_CHECK_ERROR(family0 != nullptr || family1 != nullptr, "TkFrameworkImpl::createJoint: at least one family in the TkJointDesc must be valid.", return nullptr); - NVBLASTTK_CHECK_ERROR(family0 == nullptr || desc.chunkIndices[0] < family0->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is invalid.", return nullptr); - NVBLASTTK_CHECK_ERROR(family1 == nullptr || desc.chunkIndices[1] < family1->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is invalid.", return nullptr); + NVBLAST_CHECK_ERROR(family0 == nullptr || desc.chunkIndices[0] < family0->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is invalid.", return nullptr); + NVBLAST_CHECK_ERROR(family1 == nullptr || desc.chunkIndices[1] < family1->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is invalid.", return nullptr); const bool actorsAreTheSame = family0 == family1 && family0->getActorByChunk(desc.chunkIndices[0]) == family1->getActorByChunk(desc.chunkIndices[1]); - NVBLASTTK_CHECK_ERROR(!actorsAreTheSame, "TkFrameworkImpl::createJoint: the chunks listed in the TkJointDesc must be in different actors.", return nullptr); + NVBLAST_CHECK_ERROR(!actorsAreTheSame, "TkFrameworkImpl::createJoint: the chunks listed in the TkJointDesc must be in different actors.", return nullptr); if (family0 != nullptr) { - const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family0->getAssetImpl()->getAssetLLInternal(), log)[desc.chunkIndices[0]]); - NVBLASTTK_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is not a support chunk in the asset for desc.families[0]. Joint not created.", return nullptr); + const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family0->getAssetImpl()->getAssetLLInternal(), logLL)[desc.chunkIndices[0]]); + NVBLAST_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is not a support chunk in the asset for desc.families[0]. Joint not created.", return nullptr); handle0 = family0->createExternalJointHandle(getFamilyID(family1), desc.chunkIndices[0], desc.chunkIndices[1]); - NVBLASTTK_CHECK_ERROR(handle0 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[0]. Joint not created.", return nullptr); + NVBLAST_CHECK_ERROR(handle0 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[0]. Joint not created.", return nullptr); } if (family1 != nullptr) { - const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family1->getAssetImpl()->getAssetLLInternal(), log)[desc.chunkIndices[1]]); - NVBLASTTK_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is not a support chunk in the asset for desc.families[1]. Joint not created.", return nullptr); + const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family1->getAssetImpl()->getAssetLLInternal(), logLL)[desc.chunkIndices[1]]); + NVBLAST_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is not a support chunk in the asset for desc.families[1]. Joint not created.", return nullptr); if (family1 != family0) { handle1 = family1->createExternalJointHandle(getFamilyID(family0), desc.chunkIndices[1], desc.chunkIndices[0]); - NVBLASTTK_CHECK_ERROR(handle1 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[1]. Joint not created.", return nullptr); + NVBLAST_CHECK_ERROR(handle1 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[1]. Joint not created.", return nullptr); } } - TkJointImpl* joint = NVBLASTTK_NEW(TkJointImpl)(desc, nullptr); - NVBLASTTK_CHECK_ERROR(joint != nullptr, "TkFrameworkImpl::createJoint: failed to create joint.", return nullptr); + TkJointImpl* joint = NVBLAST_NEW(TkJointImpl)(desc, nullptr); + NVBLAST_CHECK_ERROR(joint != nullptr, "TkFrameworkImpl::createJoint: failed to create joint.", return nullptr); const TkJointData& jointData = joint->getDataInternal(); @@ -468,28 +353,6 @@ TkJoint* TkFrameworkImpl::createJoint(const TkJointDesc& desc) } -bool TkFrameworkImpl::serializeHeader(const TkSerializable& object, PxFileBuf& stream) -{ - const TkTypeImpl& type = static_cast<const TkTypeImpl&>(object.getType()); - - // Tk framework identifier - stream.storeDword(ClassID); - - // Object header - stream.storeDword(type.getID()); - stream.storeDword(type.getVersionInternal()); - - // Object ID - stream.write(&object.getID(), sizeof(NvBlastID)); - - // Serializable user data - stream.storeDword(static_cast<uint32_t>(object.userIntData & 0xFFFFFFFF)); - stream.storeDword(static_cast<uint32_t>(object.userIntData >> 32)); - - return true; -} - - void TkFrameworkImpl::onCreate(TkIdentifiable& object) { const TkTypeImpl& type = static_cast<const TkTypeImpl&>(object.getType()); @@ -500,7 +363,7 @@ void TkFrameworkImpl::onCreate(TkIdentifiable& object) { if (!isInvalidIndex(index)) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::addObject: object type unrecognized."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::addObject: object type unrecognized."); } return; } @@ -529,7 +392,7 @@ void TkFrameworkImpl::onDestroy(TkIdentifiable& object) { if (!isInvalidIndex(index)) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::removeObject: object type unrecognized."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::removeObject: object type unrecognized."); } return; } @@ -541,13 +404,13 @@ void TkFrameworkImpl::onDestroy(TkIdentifiable& object) void TkFrameworkImpl::onCreate(TkJointImpl& joint) { - NVBLASTTK_CHECK_ERROR(m_joints.insert(&joint), "TkFrameworkImpl::onCreate: Joint already tracked.", return); + NVBLAST_CHECK_ERROR(m_joints.insert(&joint), "TkFrameworkImpl::onCreate: Joint already tracked.", return); } void TkFrameworkImpl::onDestroy(TkJointImpl& joint) { - NVBLASTTK_CHECK_ERROR(m_joints.erase(&joint), "TkFrameworkImpl::onDestroy: Joint not tracked.", return); + NVBLAST_CHECK_ERROR(m_joints.erase(&joint), "TkFrameworkImpl::onDestroy: Joint not tracked.", return); } @@ -557,7 +420,7 @@ void TkFrameworkImpl::onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev { if (!m_IDToObject.erase(IDPrev)) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with previous ID doesn't exist."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with previous ID doesn't exist."); } } @@ -566,7 +429,7 @@ void TkFrameworkImpl::onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev auto& value = m_IDToObject[IDCurr]; if (value != nullptr) { - NVBLASTTK_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with new ID already exists."); + NVBLAST_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with new ID already exists."); return; } value = &object; @@ -579,28 +442,15 @@ void TkFrameworkImpl::onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev //////// Global API implementation //////// -Nv::Blast::TkFramework* NvBlastTkFrameworkCreate(const Nv::Blast::TkFrameworkDesc& desc) +Nv::Blast::TkFramework* NvBlastTkFrameworkCreate() { - if (desc.errorCallback == nullptr) - { - return nullptr; - } - - if (desc.allocatorCallback == nullptr) - { - desc.errorCallback->reportError(PxErrorCode::eINVALID_OPERATION, "TkFramework::create: NULL allocator given in descriptor.", __FILE__, __LINE__); - return nullptr; - } - if (Nv::Blast::TkFrameworkImpl::get() != nullptr) { - desc.errorCallback->reportError(PxErrorCode::eINVALID_OPERATION, "TkFramework::create: framework already created. Use TkFramework::get() to access.", __FILE__, __LINE__); + NVBLAST_LOG_ERROR("TkFramework::create: framework already created. Use TkFramework::get() to access."); return nullptr; } - Nv::Blast::TkAllocator::s_allocatorCallback = desc.allocatorCallback; - - Nv::Blast::TkFrameworkImpl* framework = new (desc.allocatorCallback->allocate(sizeof(Nv::Blast::TkFrameworkImpl), "TkFrameworkImpl", __FILE__, __LINE__)) Nv::Blast::TkFrameworkImpl(desc); + Nv::Blast::TkFrameworkImpl* framework = NVBLAST_NEW(Nv::Blast::TkFrameworkImpl) (); Nv::Blast::TkFrameworkImpl::set(framework); return Nv::Blast::TkFrameworkImpl::get(); diff --git a/sdk/toolkit/source/NvBlastTkFrameworkImpl.h b/sdk/toolkit/source/NvBlastTkFrameworkImpl.h index ceeff06..98fd4da 100644 --- a/sdk/toolkit/source/NvBlastTkFrameworkImpl.h +++ b/sdk/toolkit/source/NvBlastTkFrameworkImpl.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 NVBLASTTKFRAMEWORKIMPL_H #define NVBLASTTKFRAMEWORKIMPL_H @@ -16,45 +34,9 @@ #include "NvBlastTkCommon.h" -#include "NvBlastTkArray.h" -#include "NvBlastTkHashMap.h" -#include "NvBlastTkHashSet.h" - - -//////// Log macros that use the TkFrameworkImpl::log function //////// - -#define NVBLASTTK_LOG_ERROR(_msg) NVBLAST_LOG_ERROR(TkFrameworkImpl::log, _msg) -#define NVBLASTTK_LOG_WARNING(_msg) NVBLAST_LOG_WARNING(TkFrameworkImpl::log, _msg) -#define NVBLASTTK_LOG_INFO(_msg) NVBLAST_LOG_INFO(TkFrameworkImpl::log, _msg) -#define NVBLASTTK_LOG_DEBUG(_msg) NVBLAST_LOG_DEBUG(TkFrameworkImpl::log, _msg) - -#define NVBLASTTK_CHECK(_expr, _messageType, _msg, _onFail) \ - { \ - if(!(_expr)) \ - { \ - TkFrameworkImpl::log(_messageType, _msg, __FILE__, __LINE__); \ - { _onFail; }; \ - } \ - } - -#define NVBLASTTK_CHECK_ERROR(_expr, _msg, _onFail) NVBLASTTK_CHECK(_expr, NvBlastMessage::Error, _msg, _onFail) -#define NVBLASTTK_CHECK_WARNING(_expr, _msg, _onFail) NVBLASTTK_CHECK(_expr, NvBlastMessage::Warning, _msg, _onFail) -#define NVBLASTTK_CHECK_INFO(_expr, _msg, _onFail) NVBLASTTK_CHECK(_expr, NvBlastMessage::Info, _msg, _onFail) -#define NVBLASTTK_CHECK_DEBUG(_expr, _msg, _onFail) NVBLASTTK_CHECK(_expr, NvBlastMessage::Debug, _msg, _onFail) - - -//////// Allocator macros //////// - -#define NVBLASTTK_ALLOC(_size, _name) TkFrameworkImpl::get()->getAllocatorCallbackInternal().allocate(_size, _name, __FILE__, __LINE__) -#define NVBLASTTK_FREE(_mem) TkFrameworkImpl::get()->getAllocatorCallbackInternal().deallocate(_mem) - -#define NVBLASTTK_NEW(T) new (NVBLASTTK_ALLOC(sizeof(T), #T)) T -#define NVBLASTTK_DELETE(obj, T) \ - (obj)->~T(); \ - NVBLASTTK_FREE(obj) - - - +#include "NvBlastArray.h" +#include "NvBlastHashMap.h" +#include "NvBlastHashSet.h" namespace Nv @@ -72,20 +54,12 @@ Implementation of TkFramework class TkFrameworkImpl : public TkFramework { public: - TkFrameworkImpl(const TkFrameworkDesc& desc); + TkFrameworkImpl(); ~TkFrameworkImpl(); // Begin TkFramework virtual void release() override; - virtual physx::PxErrorCallback& getErrorCallback() const override; - - virtual physx::PxAllocatorCallback& getAllocatorCallback() const override; - - virtual NvBlastLog getLogFn() const override; - - virtual TkSerializable* deserialize(physx::general_PxIOStream2::PxFileBuf& stream) override; - virtual const TkType* getType(TkTypeIndex::Enum typeIndex) const override; virtual TkIdentifiable* findObjectByID(const NvBlastID& id) const override; @@ -94,7 +68,7 @@ public: virtual uint32_t getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart = 0) const override; - virtual bool reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap = nullptr) const override; + virtual bool reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap = nullptr, bool keepBondNormalChunkOrder = false) const override; virtual bool ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const override; @@ -111,16 +85,6 @@ public: // Public methods /** - Access to the error callback set by the user. - */ - physx::PxErrorCallback& getErrorCallbackInternal() const; - - /** - Access to the allocator callback set by the user. - */ - physx::PxAllocatorCallback& getAllocatorCallbackInternal() const; - - /** To be called by any TkIdentifiable object when it is created, so the framework can track it. */ void onCreate(TkIdentifiable& object); @@ -150,11 +114,6 @@ public: */ TkIdentifiable* findObjectByIDInternal(const NvBlastID& id) const; - /** - Serialize a TkSerializable's standard header data, including its type ID, type version, object ID, and TkObject::userIntData. - */ - bool serializeHeader(const TkSerializable& object, physx::general_PxIOStream2::PxFileBuf& stream); - // Access to singleton /** Retrieve the global singleton. */ @@ -163,50 +122,28 @@ public: /** Set the global singleton, if it's not already set, or set it to NULL. Returns true iff successful. */ static bool set(TkFrameworkImpl* framework); - // Blast LL context functions - static void log(int type, const char* msg, const char* file, int line); //!< A function with the NvBlastLog signature which can be used in NvBlast low-level function calls - static void* alloc(size_t size); //!< A function with the std::malloc signature which returns 16-byte aligned memory - static void free(void* mem); //!< A function with the std::free signature which can deallocate memory created by alloc - private: // Enums - enum { Alignment = 16 }; //!< Memory alignment used for allocations - enum { ClassID = NVBLASTTK_FOURCC('T', 'K', 'F', 'W') }; //!< TkFramework identifier token, used in serialization + enum { ClassID = NVBLAST_FOURCC('T', 'K', 'F', 'W') }; //!< TkFramework identifier token, used in serialization // Static data static TkFrameworkImpl* s_framework; //!< Global (singleton) object pointer - // Callbacks - physx::PxErrorCallback* m_errorCallback; //!< User-supplied error callback - physx::PxAllocatorCallback* m_allocatorCallback; //!< User-supplied allocator callback - // Types - TkInlineArray<const TkTypeImpl*, TkTypeIndex::TypeCount>::type m_types; //!< TkIdentifiable static type data - TkHashMap<uint32_t, uint32_t>::type m_typeIDToIndex; //!< Map to type data keyed by ClassID + InlineArray<const TkTypeImpl*, TkTypeIndex::TypeCount>::type m_types; //!< TkIdentifiable static type data + HashMap<uint32_t, uint32_t>::type m_typeIDToIndex; //!< Map to type data keyed by ClassID // Objects and object names - TkHashMap<NvBlastID, TkIdentifiable*>::type m_IDToObject; //!< Map to all TkIdentifiable objects, keyed by NvBlastID - TkInlineArray<TkArray<TkIdentifiable*>::type, TkTypeIndex::TypeCount>::type m_objects; //!< Catalog of all TkIdentifiable objects, grouped by type. (Revisit implementation.) + HashMap<NvBlastID, TkIdentifiable*>::type m_IDToObject; //!< Map to all TkIdentifiable objects, keyed by NvBlastID + InlineArray<Array<TkIdentifiable*>::type, TkTypeIndex::TypeCount>::type m_objects; //!< Catalog of all TkIdentifiable objects, grouped by type. (Revisit implementation.) // Track external joints (to do: make this a pool) - TkHashSet<TkJointImpl*>::type m_joints; //!< All internal joints + HashSet<TkJointImpl*>::type m_joints; //!< All internal joints }; //////// TkFrameworkImpl inline methods //////// -NV_INLINE physx::PxErrorCallback& TkFrameworkImpl::getErrorCallbackInternal() const -{ - return *m_errorCallback; -} - - -NV_INLINE physx::PxAllocatorCallback& TkFrameworkImpl::getAllocatorCallbackInternal() const -{ - return *m_allocatorCallback; -} - - NV_INLINE TkIdentifiable* TkFrameworkImpl::findObjectByIDInternal(const NvBlastID& id) const { const auto entry = m_IDToObject.find(id); diff --git a/sdk/toolkit/source/NvBlastTkGUID.h b/sdk/toolkit/source/NvBlastTkGUID.h index a770092..c11b48b 100644 --- a/sdk/toolkit/source/NvBlastTkGUID.h +++ b/sdk/toolkit/source/NvBlastTkGUID.h @@ -3,15 +3,28 @@ // // Notice // NVIDIA Corporation and its licensors retain all intellectual property and -/* -* 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. -*/ +// 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 NVBLASTTKGUID_H #define NVBLASTTKGUID_H diff --git a/sdk/toolkit/source/NvBlastTkGroupImpl.cpp b/sdk/toolkit/source/NvBlastTkGroupImpl.cpp index d9a4b29..caa2e76 100644 --- a/sdk/toolkit/source/NvBlastTkGroupImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkGroupImpl.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 "NvPreprocessor.h" @@ -20,17 +38,11 @@ #include "NvBlastTkAssetImpl.h" #include "NvBlastTkTaskImpl.h" -#include "Px.h" -#include "PxFileBuf.h" -#include "PxAllocatorCallback.h" -#include "task/PxCpuDispatcher.h" - #undef max #undef min #include <algorithm> using namespace physx; -using namespace physx::general_PxIOStream2; namespace Nv @@ -43,19 +55,9 @@ namespace Blast NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Group); -//////// Local (static) functions //////// - -static uint32_t getNumThreads(PxTaskManager* tm) -{ - if (tm == nullptr) return 0; - if (tm->getCpuDispatcher() == nullptr) return 0; - return tm->getCpuDispatcher()->getWorkerCount(); -} - - //////// Member functions //////// -TkGroupImpl::TkGroupImpl() : m_actorCount(0), m_isProcessing(false), m_sync(0) +TkGroupImpl::TkGroupImpl() : m_actorCount(0), m_isProcessing(false) { #if NV_PROFILE memset(&m_stats, 0, sizeof(TkGroupStats)); @@ -75,7 +77,7 @@ void TkGroupImpl::release() if (isProcessing()) { // abort all processing? - NVBLASTTK_LOG_ERROR("TkGroup::release: cannot release Group while processing."); + NVBLAST_LOG_ERROR("TkGroup::release: cannot release Group while processing."); NVBLAST_ALWAYS_ASSERT_MESSAGE("TkGroup::release: cannot release Group while processing."); return; } @@ -92,7 +94,7 @@ void TkGroupImpl::release() } SharedMemory* mem = it->second; mem->release(); - NVBLASTTK_DELETE(mem, SharedMemory); + NVBLAST_DELETE(mem, SharedMemory); } m_sharedMemory.clear(); @@ -102,7 +104,7 @@ void TkGroupImpl::release() m_chunkEventDataBlock.release(); m_splitScratchBlock.release(); - NVBLASTTK_DELETE(this, TkGroupImpl); + NVBLAST_DELETE(this, TkGroupImpl); } @@ -128,13 +130,13 @@ bool TkGroupImpl::addActor(TkActor& actor) TkActorImpl& tkActor = static_cast<TkActorImpl&>(actor); if (tkActor.getGroup() != nullptr) { - NVBLASTTK_LOG_ERROR("TkGroup::addActor: actor already belongs to a Group. Remove from current group first."); + NVBLAST_LOG_ERROR("TkGroup::addActor: actor already belongs to a Group. Remove from current group first."); return false; } if (isProcessing()) { - NVBLASTTK_LOG_ERROR("TkGroup::addActor: cannot alter Group while processing."); + NVBLAST_LOG_ERROR("TkGroup::addActor: cannot alter Group while processing."); return false; } @@ -155,29 +157,24 @@ bool TkGroupImpl::addActor(TkActor& actor) // the actor belongs to a family not involved in this group yet // shared memory must be allocated and temporary buffers adjusted accordingly - PERF_ZONE_BEGIN("family memory"); - mem = NVBLASTTK_NEW(SharedMemory); + BLAST_PROFILE_ZONE_BEGIN("family memory"); + mem = NVBLAST_NEW(SharedMemory); mem->allocate(family); m_sharedMemory[&family] = mem; - PERF_ZONE_END("family memory"); + BLAST_PROFILE_ZONE_END("family memory"); - PERF_ZONE_BEGIN("group memory"); + BLAST_PROFILE_ZONE_BEGIN("group memory"); - const uint32_t numThreads = getNumThreads(m_pxTaskManager); - // one worker always exists, even if it is the main thread (when numThreads is 0) - const uint32_t numWorkers = std::max(numThreads, (uint32_t)1); - - // the number of threads could have changed, however this is unexpected and handled in process() + const uint32_t workerCount = m_workers.size(); - - NvBlastLog theLog = TkFrameworkImpl::get()->log; + NvBlastLog theLog = logLL; // this group's tasks will use one temporary buffer each, which is of max size of, for all families involved const size_t requiredScratch = NvBlastActorGetRequiredScratchForSplit(tkActor.getActorLL(), theLog); if (static_cast<size_t>(m_splitScratchBlock.numElementsPerBlock()) < requiredScratch) { m_splitScratchBlock.release(); - m_splitScratchBlock.allocate(static_cast<uint32_t>(requiredScratch), numWorkers); + m_splitScratchBlock.allocate(static_cast<uint32_t>(requiredScratch), workerCount); } // generate and apply fracture may create an entry for each bond @@ -185,9 +182,9 @@ bool TkGroupImpl::addActor(TkActor& actor) if (m_bondTempDataBlock.numElementsPerBlock() < bondCount) { m_bondTempDataBlock.release(); - m_bondTempDataBlock.allocate(bondCount, numWorkers); + m_bondTempDataBlock.allocate(bondCount, workerCount); m_bondEventDataBlock.release(); - m_bondEventDataBlock.allocate(bondCount, numWorkers); + m_bondEventDataBlock.allocate(bondCount, workerCount); } // apply fracture may create an entry for each lower-support chunk @@ -199,11 +196,11 @@ bool TkGroupImpl::addActor(TkActor& actor) if (m_chunkTempDataBlock.numElementsPerBlock() < chunkCount) { m_chunkTempDataBlock.release(); - m_chunkTempDataBlock.allocate(chunkCount, numWorkers); + m_chunkTempDataBlock.allocate(chunkCount, workerCount); m_chunkEventDataBlock.release(); - m_chunkEventDataBlock.allocate(chunkCount, numWorkers); + m_chunkEventDataBlock.allocate(chunkCount, workerCount); } - PERF_ZONE_END("group memory"); + BLAST_PROFILE_ZONE_END("group memory"); } mem->addReference(); @@ -213,12 +210,12 @@ bool TkGroupImpl::addActor(TkActor& actor) uint32_t TkGroupImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart /* = 0 */) const { - PERF_SCOPE_L("TkGroup::getActors"); + BLAST_PROFILE_SCOPE_L("TkGroup::getActors"); uint32_t actorCount = m_actorCount; if (actorCount <= indexStart) { - NVBLASTTK_LOG_WARNING("TkGroup::getActors: indexStart beyond end of actor list."); + NVBLAST_LOG_WARNING("TkGroup::getActors: indexStart beyond end of actor list."); return 0; } @@ -269,7 +266,7 @@ void TkGroupImpl::releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem) NVBLAST_ASSERT(mem != nullptr && m_sharedMemory[fam] == mem); mem->release(); m_sharedMemory.erase(fam); - NVBLASTTK_DELETE(mem, SharedMemory); + NVBLAST_DELETE(mem, SharedMemory); } @@ -279,13 +276,13 @@ bool TkGroupImpl::removeActor(TkActor& actor) if (tkActor.getGroup() != this) { - NVBLASTTK_LOG_ERROR("TkGroup::removeActor: actor does not belong to this Group."); + NVBLAST_LOG_ERROR("TkGroup::removeActor: actor does not belong to this Group."); return false; } if (isProcessing()) { - NVBLASTTK_LOG_ERROR("TkGroup::removeActor: cannot alter Group while processing."); + NVBLAST_LOG_ERROR("TkGroup::removeActor: cannot alter Group while processing."); return false; } @@ -320,65 +317,86 @@ bool TkGroupImpl::removeActor(TkActor& actor) TkGroupImpl* TkGroupImpl::create(const TkGroupDesc& desc) { - if (desc.pxTaskManager == nullptr) - { - NVBLASTTK_LOG_WARNING("TkGroup::create: attempting to create a Group with a NULL pxTaskManager."); - } - - TkGroupImpl* group = NVBLASTTK_NEW(TkGroupImpl); + TkGroupImpl* group = NVBLAST_NEW(TkGroupImpl); - group->m_pxTaskManager = desc.pxTaskManager; - group->m_initialNumThreads = getNumThreads(group->m_pxTaskManager); + group->setWorkerCount(desc.workerCount); return group; } -bool TkGroupImpl::process() +void TkGroupImpl::setWorkerCount(uint32_t workerCount) { - PERF_SCOPE_L("TkGroup::process"); - - if (!setProcessing(true)) + if (isProcessing()) { - NVBLASTTK_LOG_WARNING("TkGroup::process: Group is still processing, call TkGroup::sync first."); - return false; + NVBLAST_LOG_WARNING("TkGroup::setWorkerCount: Group is still processing, call TkGroup::endProcess first."); + return; } - if (m_jobs.size() > 0) + if (workerCount == 0) { - PERF_ZONE_BEGIN("task setup"); + NVBLAST_LOG_WARNING("TkGroup: attempting to create a Group with 0 workers. Forced to 1."); + workerCount = 1; + } - PERF_ZONE_BEGIN("task memory"); - const uint32_t numThreads = getNumThreads(m_pxTaskManager); - // one worker always exists, even if it is the main thread (when numThreads is 0) - const uint32_t numWorkers = std::max(numThreads, (uint32_t)1); + if (workerCount != m_workers.size()) + { + m_workers.resize(workerCount); - if (numThreads != m_initialNumThreads) + uint32_t workerId = 0; + for (auto& worker : m_workers) { - NVBLASTTK_LOG_WARNING("TkGroup::process: number of threads has changed, memory is being reallocated."); - m_initialNumThreads = numThreads; + worker.m_id = workerId++; + worker.m_group = this; + } - const uint32_t bondCount = m_bondTempDataBlock.numElementsPerBlock(); - if (bondCount > 0) - { - m_bondTempDataBlock.release(); - m_bondTempDataBlock.allocate(bondCount, numWorkers); - m_bondEventDataBlock.release(); - m_bondEventDataBlock.allocate(bondCount, numWorkers); - } - const uint32_t chunkCount = m_chunkTempDataBlock.numElementsPerBlock(); + const uint32_t bondCount = m_bondTempDataBlock.numElementsPerBlock(); + if (bondCount > 0) + { + m_bondTempDataBlock.release(); + m_bondTempDataBlock.allocate(bondCount, workerCount); + m_bondEventDataBlock.release(); + m_bondEventDataBlock.allocate(bondCount, workerCount); + } + const uint32_t chunkCount = m_chunkTempDataBlock.numElementsPerBlock(); + if (chunkCount > 0) + { m_chunkTempDataBlock.release(); - m_chunkTempDataBlock.allocate(chunkCount, numWorkers); + m_chunkTempDataBlock.allocate(chunkCount, workerCount); m_chunkEventDataBlock.release(); - m_chunkEventDataBlock.allocate(chunkCount, numWorkers); - const uint32_t scratchSize = m_splitScratchBlock.numElementsPerBlock(); + m_chunkEventDataBlock.allocate(chunkCount, workerCount); + } + const uint32_t scratchSize = m_splitScratchBlock.numElementsPerBlock(); + if (scratchSize > 0) + { m_splitScratchBlock.release(); - m_splitScratchBlock.allocate(scratchSize, numWorkers); + m_splitScratchBlock.allocate(scratchSize, workerCount); } - PERF_ZONE_END("task memory"); + } +} + + +NV_INLINE uint32_t TkGroupImpl::getWorkerCount() const +{ + return m_workers.size(); +} + + +uint32_t TkGroupImpl::startProcess() +{ + BLAST_PROFILE_SCOPE_L("TkGroup::startProcess"); + if (!setProcessing(true)) + { + NVBLAST_LOG_WARNING("TkGroup::process: Group is still processing, call TkGroup::endProcess first."); + return 0; + } + + if (m_jobs.size() > 0) + { + BLAST_PROFILE_ZONE_BEGIN("task setup"); - PERF_ZONE_BEGIN("setup job queue"); + BLAST_PROFILE_ZONE_BEGIN("setup job queue"); for (const auto& job : m_jobs) { const TkActorImpl* a = job.m_tkActor; @@ -400,9 +418,9 @@ bool TkGroupImpl::process() // (two TkFracture* events per damage plus one TkSplitEvent) mem->m_eventsCount += 2 * damageCount + 1; } - PERF_ZONE_END("setup job queue"); + BLAST_PROFILE_ZONE_END("setup job queue"); - PERF_ZONE_BEGIN("memory protect"); + BLAST_PROFILE_ZONE_BEGIN("memory protect"); for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it) { // preallocate the event memory for TkWorkers @@ -418,67 +436,38 @@ bool TkGroupImpl::process() // switch to parallel mode mem->m_events.protect(true); } - PERF_ZONE_END("memory protect"); - - PERF_ZONE_END("task setup"); + BLAST_PROFILE_ZONE_END("memory protect"); - // ready queue for the workers - const uint32_t numJobs = m_jobs.size(); - m_jobQueue.init(m_jobs.begin(), numJobs); + BLAST_PROFILE_ZONE_END("task setup"); - // do not start more workers than there are jobs - const uint32_t workersToRun = std::min(numWorkers, numJobs); - m_workers.resize(workersToRun); - m_sync.setCount(workersToRun); - uint32_t workerId = 0; - if (numThreads > 0) - { - for (auto& task : m_workers) - { - PERF_SCOPE_M("task release"); - task.m_id = workerId++; - task.m_group = this; - task.setContinuation(*m_pxTaskManager, nullptr); - // mind m_sync.setCount above, immediately removing reference would not work with a continuation task - task.removeReference(); - } - } - else + for (auto&worker : m_workers) { - // let this thread do the work - NVBLAST_ASSERT(m_workers.size() == 1); - for (auto& task : m_workers) - { - task.m_id = workerId++; - task.m_group = this; - task.run(); - task.release(); - } + worker.initialize(); } - } - - return true; + return m_jobs.size(); + } + else + { + bool success = setProcessing(false); + NVBLAST_ASSERT(success); + NV_UNUSED(success); + return 0; + } } -bool TkGroupImpl::sync(bool block /*= true*/) +bool TkGroupImpl::endProcess() { - if (!m_sync.isDone() && block) - { - PERF_SCOPE_L("TkGroupImpl::sync wait"); - m_sync.wait(); - } - - if (isProcessing() && m_sync.isDone()) + if (isProcessing()) { - PERF_SCOPE_L("TkGroupImpl::sync finalize"); + BLAST_PROFILE_SCOPE_L("TkGroupImpl::endProcess"); if (m_jobs.size() > 0) { #if NV_PROFILE - PERF_ZONE_BEGIN("accumulate timers"); + BLAST_PROFILE_ZONE_BEGIN("accumulate timers"); NvBlastTimers accumulated; NvBlastTimersReset(&accumulated); uint32_t jobCount = 0; @@ -492,10 +481,10 @@ bool TkGroupImpl::sync(bool block /*= true*/) m_stats.timers = accumulated; m_stats.processedActorsCount = jobCount; m_stats.workerTime = workerTime; - PERF_ZONE_END("accumulate timers"); + BLAST_PROFILE_ZONE_END("accumulate timers"); #endif - PERF_ZONE_BEGIN("job update"); + BLAST_PROFILE_ZONE_BEGIN("job update"); for (auto& j : m_jobs) { if (j.m_newActorsCount) @@ -511,21 +500,26 @@ bool TkGroupImpl::sync(bool block /*= true*/) // Update joints mem->m_events.protect(false); // allow allocations again + BLAST_PROFILE_ZONE_BEGIN("updateJoints"); fam->updateJoints(j.m_tkActor, &mem->m_events); + BLAST_PROFILE_ZONE_END("updateJoints"); } // virtually dequeue the actor // the queue itself is cleared right after this loop j.m_tkActor->m_flags.clear(TkActorFlag::PENDING); j.m_tkActor->m_groupJobIndex = invalidIndex<uint32_t>(); + BLAST_PROFILE_ZONE_BEGIN("damageBuffer.clear"); j.m_tkActor->m_damageBuffer.clear(); + BLAST_PROFILE_ZONE_END("damageBuffer.clear"); } m_jobs.clear(); - PERF_ZONE_END("job update"); + BLAST_PROFILE_ZONE_END("job update"); - PERF_ZONE_BEGIN("event dispatch"); + BLAST_PROFILE_ZONE_BEGIN("event dispatch"); for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it) { + BLAST_PROFILE_SCOPE_L("event dispatch"); TkFamilyImpl* family = it->first; SharedMemory* mem = it->second; @@ -542,15 +536,15 @@ bool TkGroupImpl::sync(bool block /*= true*/) mem->m_events.reset(); mem->reset(); } - PERF_ZONE_END("event dispatch"); + BLAST_PROFILE_ZONE_END("event dispatch"); - PERF_ZONE_BEGIN("event memory release"); + BLAST_PROFILE_ZONE_BEGIN("event memory release"); for (auto& worker : m_workers) { worker.m_bondBuffer.clear(); worker.m_chunkBuffer.clear(); } - PERF_ZONE_END("event memory release"); + BLAST_PROFILE_ZONE_END("event memory release"); } bool success = setProcessing(false); @@ -588,5 +582,31 @@ void TkGroupImpl::enqueue(TkActorImpl* tkActor) } +TkGroupWorker* TkGroupImpl::acquireWorker() +{ + BLAST_PROFILE_SCOPE_L("TkGroupImpl::acquireWorker"); + std::unique_lock<std::mutex> lk(m_workerMtx); + for (auto& worker:m_workers) + { + if (!worker.m_isBusy) + { + worker.m_isBusy = true; + return &worker; + } + } + return nullptr; +} + + +void TkGroupImpl::returnWorker(TkGroupWorker* worker) +{ + BLAST_PROFILE_SCOPE_L("TkGroupImpl::returnWorker"); + std::unique_lock<std::mutex> lk(m_workerMtx); + auto w = static_cast<TkWorker*>(worker); + NVBLAST_CHECK_WARNING(w->m_group == this, "TkGroup::returnWorker worker does not belong to this group.", return); + w->m_isBusy = false; +} + + } // namespace Blast } // namespace Nv diff --git a/sdk/toolkit/source/NvBlastTkGroupImpl.h b/sdk/toolkit/source/NvBlastTkGroupImpl.h index db7e7c1..ea5b926 100644 --- a/sdk/toolkit/source/NvBlastTkGroupImpl.h +++ b/sdk/toolkit/source/NvBlastTkGroupImpl.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 NVBLASTTKGROUPIMPL_H #define NVBLASTTKGROUPIMPL_H @@ -34,20 +52,25 @@ public: NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('G', 'R', 'P', '\0'); - static TkGroupImpl* create(const TkGroupDesc& desc); + static TkGroupImpl* create(const TkGroupDesc& desc); // Begin TkGroup - virtual bool addActor(TkActor& actor) override; + virtual bool addActor(TkActor& actor) override; + + virtual uint32_t getActorCount() const override; - virtual uint32_t getActorCount() const override; + virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const override; - virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const override; + virtual uint32_t startProcess() override; + virtual bool endProcess() override; - virtual bool process() override; + virtual void getStats(TkGroupStats& stats) const override; - virtual bool sync(bool block = true) override; + virtual void setWorkerCount(uint32_t workerCount) override; + virtual uint32_t getWorkerCount() const override; - virtual void getStats(TkGroupStats& stats) const override; + virtual TkGroupWorker* acquireWorker() override; + virtual void returnWorker(TkGroupWorker*) override; // End TkGroup // TkGroupImpl API @@ -55,54 +78,51 @@ public: /** Remove the actor from this group if the actor actually belongs to it and the group is not processing. - \param[in] actor The TkActor to remove. + \param[in] actor The TkActor to remove. - \return true if removing succeeded, false otherwise + \return true if removing succeeded, false otherwise */ - bool removeActor(TkActor& actor); + bool removeActor(TkActor& actor); /** Add the actor to this group's job queue. It is the caller's responsibility to add an actor only once. This condition is checked in debug builds. */ - void enqueue(TkActorImpl* tkActor); + void enqueue(TkActorImpl* tkActor); /** Atomically check if this group is processing actors. @see setProcessing() \return true between process() and sync() calls, false otherwise */ - bool isProcessing() const; + bool isProcessing() const; private: /** Atomically set the processing state. This function checks for the current state before changing it. @see isProcessing() - \param[in] value the value of the new state + \param[in] value the value of the new state - \return true if the new state could be set, false otherwise + \return true if the new state could be set, false otherwise */ - bool setProcessing(bool value); + bool setProcessing(bool value); /** Get the group-family shared memory for the specified family. To be used when the memory is expected to already exist. */ - SharedMemory* getSharedMemory(TkFamilyImpl* family); - void releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem); + SharedMemory* getSharedMemory(TkFamilyImpl* family); + void releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem); // functions to add/remove actors _without_ group-family memory management - void addActorInternal(TkActorImpl& tkActor); - void addActorsInternal(TkActorImpl** actors, uint32_t numActors); - void removeActorInternal(TkActorImpl& tkActor); + void addActorInternal(TkActorImpl& tkActor); + void addActorsInternal(TkActorImpl** actors, uint32_t numActors); + void removeActorInternal(TkActorImpl& tkActor); - physx::PxTaskManager* m_pxTaskManager; //!< the task manager used to dispatch workers - uint32_t m_initialNumThreads; //!< tracks the number of worker threads - uint32_t m_actorCount; //!< number of actors in this group - TkHashMap<TkFamilyImpl*, SharedMemory*>::type m_sharedMemory; //!< memory sharable by actors in the same family in this group + HashMap<TkFamilyImpl*, SharedMemory*>::type m_sharedMemory; //!< memory sharable by actors in the same family in this group // it is assumed no more than the asset's number of bond and chunks fracture commands are produced SharedBlock<NvBlastChunkFractureData> m_chunkTempDataBlock; //!< chunk data for damage/fracture @@ -112,17 +132,17 @@ private: SharedBlock<char> m_splitScratchBlock; //!< split scratch memory std::atomic<bool> m_isProcessing; //!< true while workers are processing - TaskSync m_sync; //!< keeps track of finished workers - TkArray<TkWorker>::type m_workers; //!< this group's workers - TkAtomicJobQueue m_jobQueue; //!< shared job queue for workers + Array<TkWorker>::type m_workers; //!< this group's workers - TkArray<TkWorkerJob>::type m_jobs; //!< this group's process jobs + Array<TkWorkerJob>::type m_jobs; //!< this group's process jobs //#if NV_PROFILE TkGroupStats m_stats; //!< accumulated group's worker stats //#endif + std::mutex m_workerMtx; + friend class TkWorker; }; diff --git a/sdk/toolkit/source/NvBlastTkHashMap.h b/sdk/toolkit/source/NvBlastTkHashMap.h deleted file mode 100644 index 14730c6..0000000 --- a/sdk/toolkit/source/NvBlastTkHashMap.h +++ /dev/null @@ -1,34 +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 NVBLASTTKHASHMAP_H -#define NVBLASTTKHASHMAP_H - - -#include "NvBlastTkAllocator.h" -#include "PsHashMap.h" - - -namespace Nv -{ -namespace Blast -{ - -template <class Key, class Value, class HashFn = physx::shdfnd::Hash<Key>> -struct TkHashMap -{ - typedef physx::shdfnd::HashMap<Key, Value, HashFn, TkAllocator> type; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTTKHASHMAP_H diff --git a/sdk/toolkit/source/NvBlastTkHashSet.h b/sdk/toolkit/source/NvBlastTkHashSet.h deleted file mode 100644 index 4a3a3a0..0000000 --- a/sdk/toolkit/source/NvBlastTkHashSet.h +++ /dev/null @@ -1,34 +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 NVBLASTTKHASHSET_H -#define NVBLASTTKHASHSET_H - - -#include "NvBlastTkAllocator.h" -#include "PsHashSet.h" - - -namespace Nv -{ -namespace Blast -{ - -template <class Key, class HashFn = physx::shdfnd::Hash<Key>> -struct TkHashSet -{ - typedef physx::shdfnd::HashSet<Key, HashFn, TkAllocator> type; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // #ifndef NVBLASTTKHASHSET_H diff --git a/sdk/toolkit/source/NvBlastTkJointImpl.cpp b/sdk/toolkit/source/NvBlastTkJointImpl.cpp index 46d6378..9c92b2d 100644 --- a/sdk/toolkit/source/NvBlastTkJointImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkJointImpl.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 "NvBlastTkFrameworkImpl.h" #include "NvBlastTkJointImpl.h" @@ -15,10 +33,6 @@ #include "NvBlastTkFamilyImpl.h" #include "Px.h" -#include "PxFileBuf.h" -#include "PxAllocatorCallback.h" - -using namespace physx::general_PxIOStream2; namespace Nv @@ -68,7 +82,7 @@ void TkJointImpl::release() // External joint removeReferencesInFamilies(); TkFrameworkImpl::get()->onDestroy(*this); - NVBLASTTK_DELETE(this, TkJointImpl); + NVBLAST_DELETE(this, TkJointImpl); } } diff --git a/sdk/toolkit/source/NvBlastTkJointImpl.h b/sdk/toolkit/source/NvBlastTkJointImpl.h index ec57309..09bae43 100644 --- a/sdk/toolkit/source/NvBlastTkJointImpl.h +++ b/sdk/toolkit/source/NvBlastTkJointImpl.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 NVBLASTTKJOINTIMPL_H #define NVBLASTTKJOINTIMPL_H diff --git a/sdk/toolkit/source/NvBlastTkTaskImpl.cpp b/sdk/toolkit/source/NvBlastTkTaskImpl.cpp index 3249928..e08986a 100644 --- a/sdk/toolkit/source/NvBlastTkTaskImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkTaskImpl.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 "NvBlastTime.h" @@ -26,7 +44,7 @@ void SharedMemory::allocate(TkFamilyImpl& tkFamily) // at most leafChunkCount actors can be created within a family // tasks will grab their portion out of these memory blocks - uint32_t leafChunkCount = NvBlastAssetGetLeafChunkCount(assetLL, TkFrameworkImpl::get()->log); + uint32_t leafChunkCount = NvBlastAssetGetLeafChunkCount(assetLL, logLL); m_newActorBuffers.allocate(2 * leafChunkCount); // GWD-167 workaround (2*) m_newTkActorBuffers.allocate(leafChunkCount); } @@ -107,157 +125,147 @@ NV_FORCE_INLINE void reportFractureEvents( } -void TkWorker::run() +void TkWorker::initialize() { - PERF_SCOPE_L("TkWorker Task"); - - NvBlastTimers* timers = nullptr; - -#if NV_PROFILE - NvBlastTimers myTimers; - timers = &myTimers; - NvBlastTimersReset(timers); - uint32_t jobCount = 0; - Time workTime; -#endif - // temporary memory used to generate and apply fractures // it must fit for the largest family involved in the group that owns this worker NvBlastBondFractureData* bondFractureData = m_group->m_bondTempDataBlock.getBlock(m_id); uint32_t bondFractureCount = m_group->m_bondTempDataBlock.numElementsPerBlock(); NvBlastChunkFractureData* chunkFractureData = m_group->m_chunkTempDataBlock.getBlock(m_id); uint32_t chunkFractureCount = m_group->m_chunkTempDataBlock.numElementsPerBlock(); - const NvBlastFractureBuffers tempBuffer = { bondFractureCount, chunkFractureCount, bondFractureData, chunkFractureData }; + m_tempBuffer = { bondFractureCount, chunkFractureCount, bondFractureData, chunkFractureData }; // temporary memory used to split the actor // large enough for the largest family involved - void* splitScratch = m_group->m_splitScratchBlock.getBlock(m_id); + m_splitScratch = m_group->m_splitScratchBlock.getBlock(m_id); // to avoid unnecessary allocations, preallocated memory exists to fit all chunks and bonds taking damage once // where multiple damage occurs, more memory will be allocated on demand (this may thwart other threads doing the same) m_bondBuffer.initialize(m_group->m_bondEventDataBlock.getBlock(m_id), m_group->m_bondEventDataBlock.numElementsPerBlock()); m_chunkBuffer.initialize(m_group->m_chunkEventDataBlock.getBlock(m_id), m_group->m_chunkEventDataBlock.numElementsPerBlock()); - TkAtomicJobQueue& q = m_group->m_jobQueue; - TkWorkerJob* j; +#if NV_PROFILE + NvBlastTimersReset(&m_stats.timers); + m_stats.processedActorsCount = 0; +#endif +} - while ((j = q.next()) != nullptr) - { - PERF_SCOPE_M("TkActor"); +void TkWorker::process(TkWorkerJob& j) +{ + NvBlastTimers* timers = nullptr; + + BLAST_PROFILE_SCOPE_M("TkActor"); - TkActorImpl* tkActor = j->m_tkActor; - const uint32_t tkActorIndex = tkActor->getIndex(); - NvBlastActor* actorLL = tkActor->getActorLLInternal(); - TkFamilyImpl& family = tkActor->getFamilyImpl(); - SharedMemory* mem = m_group->getSharedMemory(&family); - TkEventQueue& events = mem->m_events; + TkActorImpl* tkActor = j.m_tkActor; + const uint32_t tkActorIndex = tkActor->getIndex(); + NvBlastActor* actorLL = tkActor->getActorLLInternal(); + TkFamilyImpl& family = tkActor->getFamilyImpl(); + SharedMemory* mem = m_group->getSharedMemory(&family); + TkEventQueue& events = mem->m_events; - NVBLAST_ASSERT(tkActor->getGroupImpl() == m_group); + NVBLAST_ASSERT(tkActor->getGroupImpl() == m_group); + NVBLAST_ASSERT(tkActor->m_flags.isSet(TkActorFlag::PENDING)); #if NV_PROFILE - *timers += tkActor->m_timers; - NvBlastTimersReset(&tkActor->m_timers); - jobCount++; + timers = &m_stats.timers; + *timers += tkActor->m_timers; + NvBlastTimersReset(&tkActor->m_timers); + m_stats.processedActorsCount++; #endif - // generate and apply fracture for all damage requested on this actor - // and queue events accordingly - for (const auto& damage : tkActor->m_damageBuffer) + // generate and apply fracture for all damage requested on this actor + // and queue events accordingly + for (const auto& damage : tkActor->m_damageBuffer) + { + NvBlastFractureBuffers commandBuffer = m_tempBuffer; + + BLAST_PROFILE_ZONE_BEGIN("Material"); + damage.generateFracture(&commandBuffer, actorLL, timers); + BLAST_PROFILE_ZONE_END("Material"); + + if (commandBuffer.chunkFractureCount > 0 || commandBuffer.bondFractureCount > 0) { - NvBlastFractureBuffers commandBuffer = tempBuffer; - - PERF_ZONE_BEGIN("Material"); - damage.generateFracture(&commandBuffer, actorLL, timers); - PERF_ZONE_END("Material"); - - if (commandBuffer.chunkFractureCount > 0 || commandBuffer.bondFractureCount > 0) - { - PERF_SCOPE_M("Fill Command Events"); - reportFractureCommands(commandBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor); - } - - NvBlastFractureBuffers eventBuffer = tempBuffer; - - PERF_ZONE_BEGIN("Fracture"); - NvBlastActorApplyFracture(&eventBuffer, actorLL, &commandBuffer, TkFrameworkImpl::get()->log, timers); - PERF_ZONE_END("Fracture"); - - if (eventBuffer.chunkFractureCount > 0 || eventBuffer.bondFractureCount > 0) - { - PERF_SCOPE_M("Fill Fracture Events"); - tkActor->m_flags |= (TkActorFlag::DAMAGED); - reportFractureEvents(eventBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor); - } + BLAST_PROFILE_SCOPE_M("Fill Command Events"); + reportFractureCommands(commandBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor); } + NvBlastFractureBuffers eventBuffer = m_tempBuffer; - // split the actor, which could have been damaged directly though the TkActor's fracture functions - // i.e. it did not have damage queued for the above loop + BLAST_PROFILE_ZONE_BEGIN("Fracture"); + NvBlastActorApplyFracture(&eventBuffer, actorLL, &commandBuffer, logLL, timers); + BLAST_PROFILE_ZONE_END("Fracture"); - NvBlastActorSplitEvent splitEvent = { nullptr, nullptr }; - if (tkActor->isDamaged()) - { - PERF_ZONE_BEGIN("Split Memory"); - uint32_t maxActorCount = NvBlastActorGetMaxActorCountForSplit(actorLL, TkFrameworkImpl::get()->log); - splitEvent.newActors = mem->reserveNewActors(maxActorCount); - PERF_ZONE_END("Split Memory"); - PERF_ZONE_BEGIN("Split"); - j->m_newActorsCount = NvBlastActorSplit(&splitEvent, actorLL, maxActorCount, splitScratch, TkFrameworkImpl::get()->log, timers); - PERF_ZONE_END("Split"); - - tkActor->m_flags.clear(TkActorFlag::DAMAGED); - } - else + if (eventBuffer.chunkFractureCount > 0 || eventBuffer.bondFractureCount > 0) { - j->m_newActorsCount = 0; + BLAST_PROFILE_SCOPE_M("Fill Fracture Events"); + tkActor->m_flags |= (TkActorFlag::DAMAGED); + reportFractureEvents(eventBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor); } + } - // update the TkActor according to the LL split results and queue events accordingly - if (j->m_newActorsCount > 0) - { - NVBLAST_ASSERT(splitEvent.deletedActor == tkActor->getActorLL()); + // split the actor, which could have been damaged directly though the TkActor's fracture functions + // i.e. it did not have damage queued for the above loop - PERF_ZONE_BEGIN("memory new actors"); + NvBlastActorSplitEvent splitEvent = { nullptr, nullptr }; + if (tkActor->isDamaged()) + { + BLAST_PROFILE_ZONE_BEGIN("Split Memory"); + uint32_t maxActorCount = NvBlastActorGetMaxActorCountForSplit(actorLL, logLL); + splitEvent.newActors = mem->reserveNewActors(maxActorCount); + BLAST_PROFILE_ZONE_END("Split Memory"); + BLAST_PROFILE_ZONE_BEGIN("Split"); + j.m_newActorsCount = NvBlastActorSplit(&splitEvent, actorLL, maxActorCount, m_splitScratch, logLL, timers); + BLAST_PROFILE_ZONE_END("Split"); + + tkActor->m_flags.clear(TkActorFlag::DAMAGED); + } + else + { + j.m_newActorsCount = 0; + } - auto tkSplitEvent = events.allocData<TkSplitEvent>(); - tkSplitEvent->children = mem->reserveNewTkActors(j->m_newActorsCount); - tkSplitEvent->numChildren = j->m_newActorsCount; + // update the TkActor according to the LL split results and queue events accordingly + if (j.m_newActorsCount > 0) + { + NVBLAST_ASSERT(splitEvent.deletedActor == tkActor->getActorLL()); + + BLAST_PROFILE_ZONE_BEGIN("memory new actors"); - tkSplitEvent->parentData.family = &family; - tkSplitEvent->parentData.userData = tkActor->userData; - tkSplitEvent->parentData.index = tkActorIndex; - family.removeActor(tkActor); + auto tkSplitEvent = events.allocData<TkSplitEvent>(); - PERF_ZONE_END("memory new actors"); + tkSplitEvent->children = mem->reserveNewTkActors(j.m_newActorsCount); + tkSplitEvent->numChildren = j.m_newActorsCount; + tkSplitEvent->parentData.family = &family; + tkSplitEvent->parentData.userData = tkActor->userData; + tkSplitEvent->parentData.index = tkActorIndex; + family.removeActor(tkActor); - PERF_ZONE_BEGIN("create new actors"); - for (uint32_t i = 0; i < j->m_newActorsCount; ++i) - { - TkActorImpl* newActor = family.addActor(splitEvent.newActors[i]); - tkSplitEvent->children[i] = newActor; - } - j->m_newActors = reinterpret_cast<TkActorImpl**>(tkSplitEvent->children); - PERF_ZONE_END("create new actors"); + BLAST_PROFILE_ZONE_END("memory new actors"); - PERF_ZONE_BEGIN("split event"); - events.addEvent(tkSplitEvent); - PERF_ZONE_END("split event"); + + BLAST_PROFILE_ZONE_BEGIN("create new actors"); + for (uint32_t i = 0; i < j.m_newActorsCount; ++i) + { + TkActorImpl* newActor = family.addActor(splitEvent.newActors[i]); + tkSplitEvent->children[i] = newActor; } + j.m_newActors = reinterpret_cast<TkActorImpl**>(tkSplitEvent->children); + BLAST_PROFILE_ZONE_END("create new actors"); + + BLAST_PROFILE_ZONE_BEGIN("split event"); + events.addEvent(tkSplitEvent); + BLAST_PROFILE_ZONE_END("split event"); } -#if NV_PROFILE - PERF_ZONE_BEGIN("write timers"); - m_stats.timers = *timers; - m_stats.processedActorsCount = jobCount; - m_stats.workerTime = workTime.getElapsedTicks(); - PERF_ZONE_END("write timers"); -#endif + j.m_tkActor->m_flags.clear(TkActorFlag::PENDING); } -void TkWorker::release() + +void TkWorker::process(uint32_t jobID) { - m_group->m_sync.notify(); + TkWorkerJob& j = m_group->m_jobs[jobID]; + process(j); } diff --git a/sdk/toolkit/source/NvBlastTkTaskImpl.h b/sdk/toolkit/source/NvBlastTkTaskImpl.h index 75f92f8..4b7ef98 100644 --- a/sdk/toolkit/source/NvBlastTkTaskImpl.h +++ b/sdk/toolkit/source/NvBlastTkTaskImpl.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 NVBLASTTKTASKIMPL_H #define NVBLASTTKTASKIMPL_H @@ -15,13 +33,12 @@ #include "NvBlastTkFrameworkImpl.h" #include "NvBlastTkEventQueue.h" -#include "NvBlastTkArray.h" +#include "NvBlastArray.h" #include <atomic> #include <mutex> #include <condition_variable> -#include "task/PxTask.h" #include "NvBlastAssert.h" #include "NvBlastTkGroup.h" // TkGroupStats @@ -48,63 +65,7 @@ struct TkWorkerJob }; -/** -Counting synchronization object for waiting on TkWorkers to finish. -*/ -class TaskSync -{ -public: - /** - Initializes with an expected number of notifications. - */ - TaskSync(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); - 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; -}; /** @@ -124,7 +85,7 @@ public: { NVBLAST_ASSERT(elementsPerBlock > 0 && numBlocks > 0); - m_buffer = reinterpret_cast<T*>(NVBLASTTK_ALLOC(elementsPerBlock*numBlocks*sizeof(T), "SharedBlock")); + m_buffer = reinterpret_cast<T*>(NVBLAST_ALLOC_NAMED(elementsPerBlock*numBlocks*sizeof(T), "SharedBlock")); m_numElementsPerBlock = elementsPerBlock; m_numBlocks = numBlocks; } @@ -153,7 +114,7 @@ public: { m_numBlocks = 0; m_numElementsPerBlock = 0; - NVBLASTTK_FREE(m_buffer); + NVBLAST_FREE(m_buffer); m_buffer = nullptr; } @@ -192,7 +153,7 @@ public: void allocate(size_t capacity) { NVBLAST_ASSERT(m_buffer == nullptr); - m_buffer = reinterpret_cast<T*>(NVBLASTTK_ALLOC(capacity*sizeof(T), "SplitMemory")); + m_buffer = reinterpret_cast<T*>(NVBLAST_ALLOC_NAMED(capacity*sizeof(T), "SplitMemory")); m_capacity = capacity; } @@ -210,7 +171,7 @@ public: void release() { NVBLAST_ASSERT(m_buffer != nullptr); - NVBLASTTK_FREE(m_buffer); + NVBLAST_FREE(m_buffer); m_buffer = nullptr; m_capacity = m_used = 0; } @@ -254,7 +215,7 @@ public: { for (void* block : m_memoryBlocks) { - NVBLASTTK_FREE(block); + NVBLAST_FREE(block); } m_memoryBlocks.clear(); } @@ -276,14 +237,14 @@ private: */ void allocateNewBlock(size_t capacity) { - PERF_SCOPE_L("Local Buffer allocation"); + BLAST_PROFILE_SCOPE_L("Local Buffer allocation"); m_capacity = capacity; - m_currentBlock = static_cast<T*>(NVBLASTTK_ALLOC(capacity*sizeof(T), "Blast LocalBuffer")); + m_currentBlock = static_cast<T*>(NVBLAST_ALLOC_NAMED(capacity*sizeof(T), "Blast LocalBuffer")); m_memoryBlocks.pushBack(m_currentBlock); m_used = 0; } - TkInlineArray<void*, 4>::type m_memoryBlocks; //!< storage for memory blocks + InlineArray<void*, 4>::type m_memoryBlocks; //!< storage for memory blocks T* m_currentBlock; //!< memory block used to allocate from size_t m_used; //!< elements used in current block size_t m_capacity; //!< elements available in current block @@ -379,54 +340,18 @@ private: /** -Shared job queue from which TkWorkers atomically fetch the next job. -*/ -template <typename T> -class TkAtomicQueue -{ -public: - /** - Initialize for a new batch of jobs. - */ - void init(TkWorkerJob* jobs, uint32_t numJobs) - { - m_jobs = jobs; - m_maxCount = numJobs; - m_current = 0; - } - - /** - Fetch a pointer to the next job. Returns nullptr when exhausted. - */ - T* next() - { - size_t index = m_current.fetch_add(1, std::memory_order_relaxed); - if (index < m_maxCount) - { - return &m_jobs[index]; - } - return nullptr; - } - -private: - T* m_jobs; //!< the list of jobs - size_t m_maxCount; //!< number of jobs available in the list - std::atomic<size_t> m_current; //!< current job counter -}; - -typedef TkAtomicQueue<TkWorkerJob> TkAtomicJobQueue; - - -/** Thread worker fracturing and splitting actors sequentially. The list of actual jobs is provided by the group owning this worker. */ -class TkWorker : public physx::PxLightCpuTask +class TkWorker final : public TkGroupWorker { public: - void run(); - void release(); - const char* getName() const { return "TkWorker"; } + TkWorker() : m_id(~(uint32_t)0), m_group(nullptr), m_isBusy(false) {} + + void process(uint32_t jobID); + void initialize(); + + void process(TkWorkerJob& job); uint32_t m_id; //!< this worker's id TkGroupImpl* m_group; //!< the group owning this worker @@ -434,6 +359,10 @@ public: LocalBuffer<NvBlastChunkFractureData> m_chunkBuffer; //!< memory manager for chunk event data LocalBuffer<NvBlastBondFractureData> m_bondBuffer; //!< memory manager for bonds event data + void* m_splitScratch; + NvBlastFractureBuffers m_tempBuffer; + bool m_isBusy; + #if NV_PROFILE TkGroupStats m_stats; #endif diff --git a/sdk/toolkit/source/NvBlastTkTypeImpl.h b/sdk/toolkit/source/NvBlastTkTypeImpl.h index a29c32f..ea27619 100644 --- a/sdk/toolkit/source/NvBlastTkTypeImpl.h +++ b/sdk/toolkit/source/NvBlastTkTypeImpl.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 NVBLASTTKTYPEIMPL_H #define NVBLASTTKTYPEIMPL_H @@ -17,36 +35,18 @@ #include "NvBlastTkType.h" -// Forward declarations -namespace physx -{ -namespace general_PxIOStream2 -{ -class PxFileBuf; -} -} - - namespace Nv { namespace Blast { -// Forward declarations -class TkSerializable; - - -// Serialization function signature -typedef TkSerializable* (*TkDeserializeFn)(physx::general_PxIOStream2::PxFileBuf&, const NvBlastID& id); - - /** Implementation of TkType, storing class information for TkIdentifiable-derived classes. */ class TkTypeImpl : public TkType { public: - TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version, TkDeserializeFn deserializeFn); + TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version); // Begin TkType virtual const char* getName() const override { return getNameInternal(); } @@ -64,25 +64,20 @@ public: const char* getNameInternal() const; /** - Access to the data format version for the class (used if it TkSerializable-derived). + Access to the data format version for the class. \return the data format version. */ uint32_t getVersionInternal() const; /** - Access to a unique identifier for the class (set using the NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE or NVBLASTTK_IMPL_DEFINE_SERIALIZABLE macro). + Access to a unique identifier for the class (set using the NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE macro). \return the class's unique identifier. */ uint32_t getID() const; /** - \return the class's deserialization function. - */ - TkDeserializeFn getDeserializeFn() const; - - /** Access to a runtime-unique small index for the class. \return the index for the class. @@ -107,7 +102,6 @@ private: const char* m_name; //!< The name of the class, set by the constructor. uint32_t m_ID; //!< The unique identifier for the class, set by the constructor. uint32_t m_version; //!< The data format version for the class, set by the constructor. - TkDeserializeFn m_deserializeFn; //!< The class deserialization function, set by the constructor. uint32_t m_index; //!< The index set for this class, set using setIndex(). friend class TkFrameworkImpl; @@ -116,11 +110,10 @@ private: //////// TkTypeImpl inline methods //////// -NV_INLINE TkTypeImpl::TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version, TkDeserializeFn deserializeFn) +NV_INLINE TkTypeImpl::TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version) : m_name(typeName) , m_ID(typeID) , m_version(version) - , m_deserializeFn(deserializeFn) , m_index((uint32_t)InvalidIndex) { } @@ -144,12 +137,6 @@ NV_INLINE uint32_t TkTypeImpl::getID() const } -NV_INLINE TkDeserializeFn TkTypeImpl::getDeserializeFn() const -{ - return m_deserializeFn; -} - - NV_INLINE uint32_t TkTypeImpl::getIndex() const { return m_index; |