aboutsummaryrefslogtreecommitdiff
path: root/sdk/extensions
diff options
context:
space:
mode:
authorAnton Novoselov <[email protected]>2017-08-01 12:53:38 +0300
committerAnton Novoselov <[email protected]>2017-08-01 12:53:38 +0300
commit236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch)
treee486f2fa39dba203563895541e92c60ed3e25759 /sdk/extensions
parentAdded screens to welcome page (diff)
downloadblast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz
blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/extensions')
-rw-r--r--sdk/extensions/assetutils/include/NvBlastExtAssetUtils.h125
-rw-r--r--sdk/extensions/assetutils/source/NvBlastExtAssetUtils.cpp416
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoring.h119
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h151
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h103
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h276
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoringMesh.h179
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoringMeshCleaner.h71
-rw-r--r--sdk/extensions/authoring/include/NvBlastExtAuthoringTypes.h179
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp48
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtApexSharedParts.h43
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp262
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.cpp74
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringAccelerator.h50
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp (renamed from sdk/extensions/authoring/source/NvBlastExtAuthoringBondGenerator.cpp)391
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h104
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp384
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h60
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp (renamed from sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilder.cpp)171
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h73
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp (renamed from sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp)415
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h330
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringInternalCommon.h91
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp1626
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.h25
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.cpp (renamed from sdk/extensions/authoring/source/NvBlastExtAuthoringMesh.cpp)141
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshImpl.h212
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp975
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h193
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h36
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp946
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.h200
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringVSA.h36
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.cpp36
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h36
-rw-r--r--sdk/extensions/common/source/NvBlastExtAllocator.h127
-rw-r--r--sdk/extensions/common/source/NvBlastExtArray.h41
-rw-r--r--sdk/extensions/common/source/NvBlastExtDefs.h64
-rw-r--r--sdk/extensions/common/source/NvBlastExtHashMap.h34
-rw-r--r--sdk/extensions/common/source/NvBlastExtHashSet.h33
-rw-r--r--sdk/extensions/converter/include/NvBlastExtDataConverter.h40
-rw-r--r--sdk/extensions/converter/source/conversion/NvBlastExtAssetBlockVersionConverter_v0_v1.h88
-rw-r--r--sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.cpp152
-rw-r--r--sdk/extensions/converter/source/conversion/NvBlastExtBinaryBlockConverter.h57
-rw-r--r--sdk/extensions/converter/source/conversion/NvBlastExtDataConverter.cpp103
-rw-r--r--sdk/extensions/exporter/include/NvBlastExtExporter.h257
-rw-r--r--sdk/extensions/exporter/include/NvBlastExtExporterJsonCollision.h62
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporter.cpp58
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp505
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h144
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp192
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h67
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp1095
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h134
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp107
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp130
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h122
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp188
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h73
-rw-r--r--sdk/extensions/import/include/NvBlastExtApexImportTool.h47
-rw-r--r--sdk/extensions/import/source/NvBlastExtApexDestruction.cpp41
-rw-r--r--sdk/extensions/import/source/NvBlastExtApexDestruction.h36
-rw-r--r--sdk/extensions/import/source/NvBlastExtApexImportTool.cpp156
-rw-r--r--sdk/extensions/import/source/NvBlastExtScopedResource.cpp36
-rw-r--r--sdk/extensions/import/source/NvBlastExtScopedResource.h36
-rw-r--r--sdk/extensions/physx/include/NvBlastExtCustomProfiler.h143
-rw-r--r--sdk/extensions/physx/include/NvBlastExtImpactDamageManager.h57
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPx.h36
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxActor.h36
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxAsset.h93
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxFamily.h36
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxListener.h36
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxManager.h42
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxStressSolver.h98
-rw-r--r--sdk/extensions/physx/include/NvBlastExtPxTask.h97
-rw-r--r--sdk/extensions/physx/include/NvBlastExtStressSolver.h209
-rw-r--r--sdk/extensions/physx/include/NvBlastExtSync.h40
-rw-r--r--sdk/extensions/physx/include/NvBlastPxCallbacks.h73
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp139
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.h164
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp54
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h40
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp299
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h112
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp52
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h58
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp82
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h48
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp229
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h86
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp126
-rw-r--r--sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h212
-rw-r--r--sdk/extensions/physx/source/sync/NvBlastExtSync.cpp54
-rw-r--r--sdk/extensions/serialization/include/NvBlastExtLlSerialization.h113
-rw-r--r--sdk/extensions/serialization/include/NvBlastExtPxSerialization.h99
-rw-r--r--sdk/extensions/serialization/include/NvBlastExtSerialization.h156
-rw-r--r--sdk/extensions/serialization/include/NvBlastExtSerializationInterface.h38
-rw-r--r--sdk/extensions/serialization/include/NvBlastExtSerializationLLInterface.h43
-rw-r--r--sdk/extensions/serialization/include/NvBlastExtTkSerialization.h89
-rw-r--r--sdk/extensions/serialization/source/BlastSerialization.capn162
-rw-r--r--sdk/extensions/serialization/source/DTO/AssetDTO.cpp363
-rw-r--r--sdk/extensions/serialization/source/DTO/AssetDTO.h40
-rw-r--r--sdk/extensions/serialization/source/DTO/DTOMacros.h57
-rw-r--r--sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp202
-rw-r--r--sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp98
-rw-r--r--sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp93
-rw-r--r--sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp135
-rw-r--r--sdk/extensions/serialization/source/DTO/NvBlastBondDTO.h40
-rw-r--r--sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp129
-rw-r--r--sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.h40
-rw-r--r--sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp102
-rw-r--r--sdk/extensions/serialization/source/DTO/NvBlastIDDTO.h40
-rw-r--r--sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp223
-rw-r--r--sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp88
-rw-r--r--sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp98
-rw-r--r--sdk/extensions/serialization/source/DTO/PxQuatDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp87
-rw-r--r--sdk/extensions/serialization/source/DTO/PxTransformDTO.h38
-rw-r--r--sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp96
-rw-r--r--sdk/extensions/serialization/source/DTO/PxVec3DTO.h39
-rw-r--r--sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp135
-rw-r--r--sdk/extensions/serialization/source/DTO/TkAssetDTO.h39
-rw-r--r--sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp111
-rw-r--r--sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.h39
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtGlobals.h10
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtInputStream.cpp42
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtInputStream.h71
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.cpp71
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtKJPxInputStream.h85
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.cpp76
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtKJPxOutputStream.h73
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtLlSerialization.capn108
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtLlSerialization.cpp136
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtLlSerializerCAPN.h72
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtOutputStream.cpp37
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtOutputStream.h69
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtPxSerialization.capn99
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtPxSerialization.cpp109
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtPxSerializerCAPN.h70
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.cpp220
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtPxSerializerRAW.h61
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerialization.capn95
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerialization.cpp401
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerialization.h172
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationCAPN.h188
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationImpl.h75
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationInterface.cpp133
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationInternal.h291
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationLL.capn89
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationLLImpl.h48
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtSerializationLLInterface.cpp101
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtTkSerialization.capn55
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtTkSerialization.cpp105
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtTkSerializerCAPN.h70
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.cpp184
-rw-r--r--sdk/extensions/serialization/source/NvBlastExtTkSerializerRAW.h54
-rw-r--r--sdk/extensions/shaders/include/NvBlastExtDamageShaders.h108
-rw-r--r--sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp368
-rw-r--r--sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp205
-rw-r--r--sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp149
-rw-r--r--sdk/extensions/stress/include/NvBlastExtStressSolver.h410
-rw-r--r--sdk/extensions/stress/source/NvBlastExtStressSolver.cpp (renamed from sdk/extensions/physx/source/physics/NvBlastExtImpulseStressSolver.cpp)855
167 files changed, 17506 insertions, 6872 deletions
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, &params) == 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, &params) == 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, &center.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, &params, 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, &params, 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;
}