diff options
| author | Bryan Galdrikian <[email protected]> | 2019-05-03 00:25:46 -0700 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2019-05-03 00:25:46 -0700 |
| commit | 74b64a27f8e07b1b0b47b809b1a060518fa11a97 (patch) | |
| tree | 34cca01711be56892c149706f02ba7358d87ec54 /sdk/extensions | |
| parent | Fixing chunk reorder bug in BlastTool, when importing a prefractured mesh (diff) | |
| download | blast-1.1.5_pre1.tar.xz blast-1.1.5_pre1.zip | |
Blast SDK 1.1.5 prerelease #1v1.1.5_pre1
Diffstat (limited to 'sdk/extensions')
70 files changed, 5346 insertions, 4893 deletions
diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoring.h b/sdk/extensions/authoring/include/NvBlastExtAuthoring.h index 5b6c5d6..829e13f 100755 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoring.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoring.h @@ -31,30 +31,23 @@ #include "NvBlastExtAuthoringTypes.h"
-namespace physx
-{
- class PxCooking;
- class PxPhysicsInsertionCallback;
-}
-
namespace Nv
{
- namespace Blast
- {
- class Mesh;
- class VoronoiSitesGenerator;
- class CutoutSet;
- class FractureTool;
- class ConvexMeshBuilder;
- class BlastBondGenerator;
- class MeshCleaner;
- class PatternGenerator;
- class Grid;
- class GridWalker;
- struct CollisionParams;
- struct CollisionHull;
- }
-}
+namespace Blast
+{
+class Mesh;
+class VoronoiSitesGenerator;
+class CutoutSet;
+class RandomGeneratorBase;
+class FractureTool;
+class ConvexMeshBuilder;
+class BlastBondGenerator;
+class MeshCleaner;
+class PatternGenerator;
+class Grid;
+class GridWalker;
+} // namespace Blast
+} // namespace Nv
struct NvBlastExtAssetUtilsBondDesc;
@@ -71,8 +64,9 @@ User should call release() after usage. \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);
+NVBLAST_API Nv::Blast::Mesh*
+NvBlastExtAuthoringCreateMesh(const NvcVec3* positions, const NvcVec3* normals, const NvcVec2* uv,
+ uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount);
/**
Constructs mesh object from triangles represented as arrays of vertices, indices and per facet material.
@@ -87,8 +81,9 @@ User should call Mesh::release() after usage. \return pointer to Nv::Blast::Mesh if it was created succefully otherwise return nullptr
*/
-NVBLAST_API Nv::Blast::Mesh* NvBlastExtAuthoringCreateMeshOnlyTriangles(const void* vertices, uint32_t verticesCount,
- uint32_t* indices, uint32_t indexCount, void* materials = nullptr, uint32_t materialStride = 4);
+NVBLAST_API Nv::Blast::Mesh*
+NvBlastExtAuthoringCreateMeshOnlyTriangles(const void* vertices, uint32_t verticesCount, uint32_t* indices,
+ uint32_t indexCount, void* materials = nullptr, uint32_t materialStride = 4);
/**
Constructs mesh object from array of vertices, edges and facets.
@@ -103,8 +98,9 @@ User should call release() after usage. \return pointer to Nv::Blast::Mesh if it was created succefully otherwise return nullptr
*/
-NVBLAST_API Nv::Blast::Mesh* NvBlastExtAuthoringCreateMeshFromFacets(const void* vertices, const void* edges, const void* facets,
- uint32_t verticesCount, uint32_t edgesCount, uint32_t facetsCount);
+NVBLAST_API Nv::Blast::Mesh*
+NvBlastExtAuthoringCreateMeshFromFacets(const void* vertices, const void* edges, const void* facets,
+ uint32_t verticesCount, uint32_t edgesCount, uint32_t facetsCount);
/**
Voronoi sites should not be generated outside of the fractured mesh, so VoronoiSitesGenerator
@@ -113,8 +109,8 @@ should be supplied with 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);
+NVBLAST_API Nv::Blast::VoronoiSitesGenerator*
+NvBlastExtAuthoringCreateVoronoiSitesGenerator(Nv::Blast::Mesh* mesh, Nv::Blast::RandomGeneratorBase* rng);
/** Instantiates a blank CutoutSet */
NVBLAST_API Nv::Blast::CutoutSet* NvBlastExtAuthoringCreateCutoutSet();
@@ -128,14 +124,17 @@ by one byte in the buffer. \param pixelBuffer pointer to be beginning of the pixel buffer
\param bufferWidth the width of the buffer in pixels
\param bufferHeight the height of the buffer in pixels
-\param segmentationErrorThreshold Reduce the number of vertices on curve untill segmentation error is smaller then specified. By default set it to 0.001.
-\param snapThreshold the pixel distance at which neighboring cutout vertices and segments may be fudged into alignment. By default set it to 1.
+\param segmentationErrorThreshold Reduce the number of vertices on curve untill segmentation error is smaller then
+specified. By default set it to 0.001. \param snapThreshold the pixel distance at which neighboring cutout vertices and
+segments may be fudged into alignment. By default set it to 1.
\param periodic whether or not to use periodic boundary conditions when creating cutouts from the map
\param expandGaps expand cutout regions to gaps or keep it as is
*/
-NVBLAST_API void NvBlastExtAuthoringBuildCutoutSet(Nv::Blast::CutoutSet& cutoutSet, const uint8_t* pixelBuffer,
- uint32_t bufferWidth, uint32_t bufferHeight, float segmentationErrorThreshold, float snapThreshold, bool periodic, bool expandGaps);
+NVBLAST_API void
+NvBlastExtAuthoringBuildCutoutSet(Nv::Blast::CutoutSet& cutoutSet, const uint8_t* pixelBuffer, uint32_t bufferWidth,
+ uint32_t bufferHeight, float segmentationErrorThreshold, float snapThreshold,
+ bool periodic, bool expandGaps);
/**
Create FractureTool object.
@@ -147,15 +146,38 @@ 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);
+NVBLAST_API Nv::Blast::BlastBondGenerator* NvBlastExtAuthoringCreateBondGenerator(Nv::Blast::ConvexMeshBuilder* builder);
/**
-Create ConvexMeshBuilder
-\return Pointer to created ConvexMeshBuilder. User's code should release it after usage.
+Build convex mesh decomposition.
+\param[in] mesh Triangle mesh to decompose.
+\param[in] triangleCount Number of triangles in mesh.
+\param[in] params Parameters for convex mesh decomposition builder.
+\param[out] convexes The resulting convex hulls.
+
+\return Number of created convex hulls.
+*/
+NVBLAST_API int32_t NvBlastExtAuthoringBuildMeshConvexDecomposition(Nv::Blast::ConvexMeshBuilder* cmb,
+ const Nv::Blast::Triangle* mesh,
+ uint32_t triangleCount,
+ const Nv::Blast::ConvexDecompositionParams& params,
+ Nv::Blast::CollisionHull**& convexes);
+
+
+/**
+ Convex geometry trimming.
+ Using slicing with noised slicing surface can result in intersecting collision geometry.
+ It leads to unstable behaviour of rigid body simulation.
+ 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] 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.
+
*/
-NVBLAST_API Nv::Blast::ConvexMeshBuilder* NvBlastExtAuthoringCreateConvexMeshBuilder(physx::PxCooking* cooking,
- physx::PxPhysicsInsertionCallback* insertionCallback);
+NVBLAST_API void NvBlastExtAuthoringTrimCollisionGeometry(Nv::Blast::ConvexMeshBuilder* cmb, uint32_t chunksCount,
+ Nv::Blast::CollisionHull** in, const uint32_t* chunkDepth);
/**
@@ -165,13 +187,8 @@ Transforms collision hull in place using scale, rotation, transform. \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 NvBlastExtAuthoringTransformCollisionHullInPlace
-(
- Nv::Blast::CollisionHull* hull,
- const physx::PxVec3* scaling,
- const physx::PxQuat* rotation,
- const physx::PxVec3* translation
-);
+NVBLAST_API void NvBlastExtAuthoringTransformCollisionHullInPlace(Nv::Blast::CollisionHull* hull, const NvcVec3* scaling,
+ const NvcQuat* rotation, const NvcVec3* translation);
/**
Transforms collision hull in place using scale, rotation, transform.
@@ -180,13 +197,9 @@ Transforms collision hull in place using scale, rotation, transform. \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 Nv::Blast::CollisionHull* NvBlastExtAuthoringTransformCollisionHull
-(
- const Nv::Blast::CollisionHull* hull,
- const physx::PxVec3* scaling,
- const physx::PxQuat* rotation,
- const physx::PxVec3* translation
-);
+NVBLAST_API Nv::Blast::CollisionHull*
+NvBlastExtAuthoringTransformCollisionHull(const Nv::Blast::CollisionHull* hull, const NvcVec3* scaling,
+ const NvcQuat* rotation, const NvcVec3* translation);
/**
Performs pending fractures and generates fractured asset, render and collision geometry
@@ -194,43 +207,55 @@ Performs pending fractures and generates fractured asset, render and collision g \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.
-\param[in] collisionParam Parameters of collision hulls generation.
+\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.
+\param[in] collisionParam Parameters of collision hulls generation.
\return Authoring result
*/
-NVBLAST_API Nv::Blast::AuthoringResult* NvBlastExtAuthoringProcessFracture(Nv::Blast::FractureTool& fTool,
- Nv::Blast::BlastBondGenerator& bondGenerator, Nv::Blast::ConvexMeshBuilder& collisionBuilder, const Nv::Blast::CollisionParams& collisionParam, int32_t defaultSupportDepth = -1);
+NVBLAST_API Nv::Blast::AuthoringResult*
+NvBlastExtAuthoringProcessFracture(Nv::Blast::FractureTool& fTool, Nv::Blast::BlastBondGenerator& bondGenerator,
+ Nv::Blast::ConvexMeshBuilder& collisionBuilder,
+ const Nv::Blast::ConvexDecompositionParams& collisionParam,
+ int32_t defaultSupportDepth = -1);
+
+
+/**
+Releases collision data for AuthoringResult. AuthoringResult should be created by NvBlast.
+*/
+NVBLAST_API void NvBlastExtAuthoringReleaseAuthoringResultCollision(Nv::Blast::ConvexMeshBuilder& collisionBuilder, Nv::Blast::AuthoringResult* ar);
+
+/**
+Releases AuthoringResult data. AuthoringResult should be created by NvBlast.
+*/
+NVBLAST_API void NvBlastExtAuthoringReleaseAuthoringResult(Nv::Blast::ConvexMeshBuilder& collisionBuilder, Nv::Blast::AuthoringResult* ar);
+
/**
Updates graphics mesh only
\param[in] fTool Fracture tool created by NvBlastExtAuthoringCreateFractureTool
-\param[out] ares AuthoringResult object which contains chunks, for which rendermeshes will be updated (e.g. to tweak UVs). Initially should be created by NvBlastExtAuthoringProcessFracture.
+\param[out] ares AuthoringResult object which contains chunks, for which rendermeshes will be updated
+(e.g. to tweak UVs). Initially should be created by NvBlastExtAuthoringProcessFracture.
*/
NVBLAST_API void NvBlastExtAuthoringUpdateGraphicsMesh(Nv::Blast::FractureTool& fTool, Nv::Blast::AuthoringResult& ares);
/**
Build collision meshes
-\param[in,out] ares AuthoringResult object which contains chunks, for which collision meshes will be built.
-\param[in] collisionBuilder Reference to ConvexMeshBuilder instance.
-\param[in] collisionParam Parameters of collision hulls generation.
+\param[in,out] ares AuthoringResult object which contains chunks, for which collision meshes will be
+built. \param[in] collisionBuilder Reference to ConvexMeshBuilder instance. \param[in] collisionParam
+Parameters of collision hulls generation.
\param[in] chunksToProcessCount Number of chunk indices in chunksToProcess memory buffer.
\param[in] chunksToProcess Chunk indices for which collision mesh should be built.
*/
-NVBLAST_API void NvBlastExtAuthoringBuildCollisionMeshes
-(
- Nv::Blast::AuthoringResult& ares,
- Nv::Blast::ConvexMeshBuilder& collisionBuilder,
- const Nv::Blast::CollisionParams& collisionParam,
- uint32_t chunksToProcessCount,
- uint32_t* chunksToProcess
-);
+NVBLAST_API void NvBlastExtAuthoringBuildCollisionMeshes(Nv::Blast::AuthoringResult& ares,
+ Nv::Blast::ConvexMeshBuilder& collisionBuilder,
+ const Nv::Blast::ConvexDecompositionParams& collisionParam,
+ uint32_t chunksToProcessCount, uint32_t* chunksToProcess);
/**
- Creates MeshCleaner object
- \return pointer to Nv::Blast::Mesh if it was created succefully otherwise return nullptr
+ Creates MeshCleaner object
+ \return pointer to Nv::Blast::Mesh if it was created succefully otherwise return nullptr
*/
NVBLAST_API Nv::Blast::MeshCleaner* NvBlastExtAuthoringCreateMeshCleaner();
@@ -245,43 +270,38 @@ NOTE: This function allocates memory using the allocator in NvBlastGlobals, to c descriptor arrays returned. The user must free this memory after use with NVBLAST_FREE
\param[in] components An array of assets to merge, of size componentCount.
-\param[in] scales If not NULL, an array of size componentCount of scales to apply to the geometric data in the chunks and bonds. If NULL, no scaling is applied.
-\param[in] rotations If not NULL, an array of size componentCount of rotations to apply to the geometric data in the chunks and bonds. The quaternions MUST be normalized.
- If NULL, no rotations are applied.
-\param[in] translations If not NULL, an array of of size componentCount of translations to apply to the geometric data in the chunks and bonds. If NULL, no translations are applied.
-\param[in] convexHullOffsets For each component, an array of chunkSize+1 specifying the start of the convex hulls for that chunk inside the chunkHulls array for that component.
-\param[in] chunkHulls For each component, an array of CollisionHull* specifying the collision geometry for the chunks in that component.
-\param[in] componentCount The size of the components and relativeTransforms arrays.
+\param[in] scales If not NULL, an array of size componentCount of scales to apply to the geometric data in
+the chunks and bonds. If NULL, no scaling is applied. \param[in] rotations If not NULL, an array of size
+componentCount of rotations to apply to the geometric data in the chunks and bonds. The quaternions MUST be normalized.
+ If NULL, no rotations are applied.
+\param[in] translations If not NULL, an array of of size componentCount of translations to apply to the
+geometric data in the chunks and bonds. If NULL, no translations are applied. \param[in] convexHullOffsets For each
+component, an array of chunkSize+1 specifying the start of the convex hulls for that chunk inside the chunkHulls array
+for that component. \param[in] chunkHulls For each component, an array of CollisionHull* specifying the
+collision geometry for the chunks in that component. \param[in] componentCount The size of the components and
+relativeTransforms arrays.
\param[out] newBondDescs Descriptors of type NvBlastExtAssetUtilsBondDesc for new bonds between components.
\param[in] maxSeparation Maximal distance between chunks which can be connected by bond.
\return the number of bonds in newBondDescs
*/
-NVBLAST_API uint32_t NvBlastExtAuthoringFindAssetConnectingBonds
-(
- const NvBlastAsset** components,
- const physx::PxVec3* scales,
- const physx::PxQuat* rotations,
- const physx::PxVec3* translations,
- const uint32_t** convexHullOffsets,
- const Nv::Blast::CollisionHull*** chunkHulls,
- uint32_t componentCount,
- NvBlastExtAssetUtilsBondDesc*& newBondDescs,
- float maxSeparation = 0.0f
-);
+NVBLAST_API uint32_t NvBlastExtAuthoringFindAssetConnectingBonds(
+ const NvBlastAsset** components, const NvcVec3* scales, const NvcQuat* rotations, const NvcVec3* translations,
+ const uint32_t** convexHullOffsets, const Nv::Blast::CollisionHull*** chunkHulls, uint32_t componentCount,
+ NvBlastExtAssetUtilsBondDesc*& newBondDescs, float maxSeparation = 0.0f);
/**
-Returns pattern generator used for generating fracture patterns for Real Time (RT) fracture
+Returns pattern generator used for generating fracture patterns.
*/
NVBLAST_API Nv::Blast::PatternGenerator* NvBlastExtAuthoringCreatePatternGenerator();
/**
-TODO
+Create spatial grid for mesh.
*/
NVBLAST_API Nv::Blast::Grid* NvBlastExtAuthoringCreateGridAccelerator(uint32_t resolution, const Nv::Blast::Mesh* m);
/**
-TODO
+Create GridWalker - SpatialAccelerator which use Grid for faster mesh sampling.
*/
NVBLAST_API Nv::Blast::GridWalker* NvBlastExtAuthoringCreateGridWalker(Nv::Blast::Grid* parent);
-#endif // ifndef NVBLASTAUTHORING_H
+#endif // ifndef NVBLASTAUTHORING_H
diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h index 55e252e..6345e6d 100755 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringBondGenerator.h @@ -31,13 +31,6 @@ #include "NvBlastExtAuthoringTypes.h"
-namespace physx
-{
-class PxPlane;
-class PxCooking;
-class PxPhysicsInsertionCallback;
-}
-
struct NvBlastBondDesc;
struct NvBlastChunkDesc;
struct NvBlastBond;
@@ -68,10 +61,9 @@ struct BondGenerationConfig struct PlaneChunkIndexer
{
- PlaneChunkIndexer(int32_t chunkId, int32_t trId, physx::PxPlane pl) : chunkId(chunkId), trId(trId), plane(pl) {}
int32_t chunkId;
int32_t trId;
- physx::PxPlane plane;
+ NvcPlane plane;
};
diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h deleted file mode 100755 index d174850..0000000 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringCollisionBuilder.h +++ /dev/null @@ -1,141 +0,0 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you
-// under a form of NVIDIA software license agreement provided separately to you.
-//
-// Notice
-// NVIDIA Corporation and its licensors retain all intellectual property and
-// proprietary rights in and to this software and related documentation and
-// any modifications thereto. Any use, reproduction, disclosure, or
-// distribution of this software and related documentation without an express
-// license agreement from NVIDIA Corporation is strictly prohibited.
-//
-// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
-// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
-// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
-// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Information and code furnished is believed to be accurate and reliable.
-// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
-// information or for any infringement of patents or other rights of third parties that may
-// result from its use. No license is granted by implication or otherwise under any patent
-// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
-// This code supersedes and replaces all information previously supplied.
-// NVIDIA Corporation 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-2018 NVIDIA Corporation. All rights reserved.
-
-
-#ifndef NVBLASTEXTAUTHORINGCOLLISIONBUILDER_H
-#define NVBLASTEXTAUTHORINGCOLLISIONBUILDER_H
-
-#include "NvBlastTypes.h"
-
-namespace physx
-{
-class PxCooking;
-class PxPhysicsInsertionCallback;
-class PxVec3;
-class PxConvexMesh;
-}
-
-
-namespace Nv
-{
-namespace Blast
-{
-
-struct CollisionHull;
-struct Triangle;
-struct Vertex;
-
-struct CollisionParams
-{
- CollisionParams()
- {
- setDefault();
- }
- void setDefault()
- {
- maximumNumberOfHulls = 8;
- maximumNumberOfVerticesPerHull = 64;
- voxelGridResolution = 1000000;
- concavity = 0.0025f;
- }
- uint32_t maximumNumberOfHulls; // Maximum number of convex hull generated for one chunk. If equal to 1 convex decomposition is disabled.
- uint32_t maximumNumberOfVerticesPerHull; // Controls the maximum number of triangles per convex-hull (default=64, range=4-1024)
- uint32_t voxelGridResolution; // Voxel grid resolution used for chunk convex decomposition (default=1,000,000, range=10,000-16,000,000).
- float concavity; // Value between 0 and 1, controls how accurate hull generation is
-};
-
-/**
- ConvexMeshBuilder provides routine to build collision hulls from array of vertices.
- Collision hull is built as convex hull of provided point set.
- If due to some reason building of convex hull is failed, collision hull is built as bounding box of vertex set.
-*/
-class ConvexMeshBuilder
-{
-public:
- virtual ~ConvexMeshBuilder() {}
-
- /**
- Release ConvexMeshBuilder memory
- */
- 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
- */
- virtual CollisionHull* buildCollisionGeometry(uint32_t verticesCount, const physx::PxVec3* vertexData) = 0;
-
- /**
- Method creates PxConvexMesh 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
-
- \return pointer to the PxConvexMesh object if it was built successfully, 'nullptr' otherwise.
- */
- virtual physx::PxConvexMesh* buildConvexMesh(uint32_t verticesCount, const physx::PxVec3* vertexData) = 0;
-
-
- /**
- Method creates PxConvexMesh from provided ConvexHull geometry
- \param[in] hull ConvexHull geometry
-
- \return pointer to the PxConvexMesh object if it was built successfully, 'nullptr' otherwise.
- */
- virtual physx::PxConvexMesh* buildConvexMesh(const CollisionHull& hull) = 0;
-
- virtual physx::PxConvexMesh* buildConvexMeshRT(const Nv::Blast::Vertex* vrs, uint32_t count) = 0;
-
-
- /**
- Convex geometry trimming.
- Using slicing with noised slicing surface can result in intersecting collision geometry.
- It leads to unstable behaviour of rigid body simulation.
- 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] 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.
-
- */
- virtual void trimCollisionGeometry(uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth) = 0;
-
-
- /**
- Create mesh convex decomposition
- */
- virtual int32_t buildMeshConvexDecomposition(const Nv::Blast::Triangle* mesh, uint32_t triangleCount, const CollisionParams& params, CollisionHull** &convexes) = 0;
-
-};
-
-} // namespace Blast
-} // namespace Nv
-
-
-#endif // ifndef NVBLASTEXTAUTHORINGCOLLISIONBUILDER_H
diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringCutout.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringCutout.h index 0702afd..10ffdd0 100755 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringCutout.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringCutout.h @@ -55,7 +55,7 @@ public: Applies to the cutout indexed by cutoutIndex:
Returns the vertex indexed by vertexIndex. (Only the X and Y coordinates are used.)
*/
- virtual const physx::PxVec3& getCutoutVertex(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexIndex) const = 0;
+ virtual const NvcVec3& getCutoutVertex(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexIndex) const = 0;
/**
If smoothing group should be changed for adjacent to this vertex faces return true
@@ -70,11 +70,7 @@ public: /**
The dimensions of the fracture map used to create the cutout set.
*/
- virtual const physx::PxVec2& getDimensions() const = 0;
-
- /** Serialization */
- //virtual void serialize(physx::PxFileBuf& stream) const = 0;
- //virtual void deserialize(physx::PxFileBuf& stream) = 0;
+ virtual const NvcVec2& getDimensions() const = 0;
/** Releases all memory and deletes itself. */
virtual void release() = 0;
diff --git a/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h b/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h index fd3d985..b11851e 100755 --- a/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h +++ b/sdk/extensions/authoring/include/NvBlastExtAuthoringFractureTool.h @@ -42,26 +42,39 @@ class Mesh; class CutoutSet;
/*
- Chunk data, chunk with chunkId == 0 is always source mesh.
+ Chunk data, chunk with chunkId == 0 is always source mesh.
*/
struct ChunkInfo
{
enum ChunkFlags
{
- NO_FLAGS = 0,
+ NO_FLAGS = 0,
CREATED_BY_ISLAND_DETECTOR = 1
};
- Mesh* meshData;
- int32_t parent;
- int32_t chunkId;
+ Mesh* meshData;
+ int32_t parent;
+ int32_t chunkId;
uint32_t flags;
- bool isLeaf;
- bool isChanged;
+ bool isLeaf;
+ bool isChanged;
+};
+
+/**
+ Abstract base class for user-defined random value generator.
+*/
+class RandomGeneratorBase
+{
+ public:
+ // Generates uniformly distributed value in [0, 1] range.
+ virtual float getRandomValue() = 0;
+ // Seeds random value generator
+ virtual void seed(int32_t seed) = 0;
+ virtual ~RandomGeneratorBase(){};
};
/*
- Noise fracturing configuration for chunks's faces
+ Noise fracturing configuration for chunks's faces
*/
struct NoiseConfiguration
{
@@ -70,12 +83,12 @@ struct NoiseConfiguration Amplitude of cutting surface noise. If it is 0 - noise is disabled.
*/
- float amplitude = 0.f;
+ float amplitude = 0.f;
/**
Frequencey of cutting surface noise.
*/
- float frequency = 1.f;
+ float frequency = 1.f;
/**
Octave number in slicing surface noise.
@@ -85,65 +98,67 @@ struct NoiseConfiguration /**
Sampling interval for surface grid.
*/
- physx::PxVec3 samplingInterval = physx::PxVec3(1.f);
+ NvcVec3 samplingInterval = { 1, 1, 1 };
};
/*
- Slicing fracturing configuration
+ Slicing fracturing configuration
*/
struct SlicingConfiguration
{
/**
- Number of slices in each direction
+ Number of slices in each direction
*/
- int32_t x_slices = 1, y_slices = 1, z_slices = 1;
+ int32_t x_slices = 1, y_slices = 1, z_slices = 1;
/**
- Offset variation, value in [0, 1]
+ Offset variation, value in [0, 1]
*/
- float offset_variations = 0.f;
+ float offset_variations = 0.f;
/**
- Angle variation, value in [0, 1]
+ Angle variation, value in [0, 1]
*/
- float angle_variations = 0.f;
+ float angle_variations = 0.f;
/*
- Noise parameters for faces between sliced chunks
+ Noise parameters for faces between sliced chunks
*/
NoiseConfiguration noise;
};
/**
- Cutout fracturing configuration
+ Cutout fracturing configuration
*/
struct CutoutConfiguration
{
/**
- Set of grouped convex loop patterns for cutout in normal direction.
- Not required for PLANE_ONLY mode
+ Set of grouped convex loop patterns for cutout in normal direction.
+ Not required for PLANE_ONLY mode
*/
CutoutSet* cutoutSet = nullptr;
/**
- Transform for initial pattern position and orientation.
- By default 2d pattern lies in XY plane (Y is up) the center of pattern is (0, 0)
+ Transform for initial pattern position and orientation.
+ By default 2d pattern lies in XY plane (Y is up) the center of pattern is (0, 0)
*/
- physx::PxTransform transform = physx::PxTransform(physx::PxIdentity);
+ NvcTransform transform = {{0, 0, 0, 1}, {0, 0, 0}};
/**
- Scale for pattern. Unscaled pattern has size (1, 1).
- For negative scale pattern will be placed at the center of chunk and scaled with max distance between points of its AABB
+ Scale for pattern. Unscaled pattern has size (1, 1).
+ For negative scale pattern will be placed at the center of chunk and scaled with max distance between points of
+ its AABB
*/
- physx::PxVec2 scale = physx::PxVec2(-1, -1);
+ NvcVec2 scale = { -1, -1 };
/**
- Conic aperture in degree, for cylindric cutout set it to 0.
+ Conic aperture in degree, for cylindric cutout set it to 0.
*/
float aperture = 0.f;
/**
- If relative transform is set - position will be displacement vector from chunk's center. Otherwise from global origin.
+ If relative transform is set - position will be displacement vector from chunk's center. Otherwise from global
+ origin.
*/
bool isRelativeTransform = true;
@@ -153,347 +168,361 @@ struct CutoutConfiguration bool useSmoothing = false;
/**
- Noise parameters for cutout surface, see NoiseConfiguration.
+ Noise parameters for cutout surface, see NoiseConfiguration.
*/
NoiseConfiguration noise;
};
/**
- Class for voronoi sites generation inside supplied mesh.
+ Class for voronoi sites generation inside supplied mesh.
*/
class VoronoiSitesGenerator
{
-public:
+ public:
virtual ~VoronoiSitesGenerator() {}
/**
- Release VoronoiSitesGenerator memory
+ Release VoronoiSitesGenerator memory
*/
- virtual void release() = 0;
+ virtual void release() = 0;
/**
- Set base fracture mesh
+ Set base fracture mesh
*/
- virtual void setBaseMesh(const Mesh* mesh) = 0;
+ virtual void setBaseMesh(const Mesh* mesh) = 0;
/**
- Access to generated voronoi sites.
- \param[out] Pointer to generated voronoi sites
- \return Count of generated voronoi sites.
+ Access to generated voronoi sites.
+ \param[out] Pointer to generated voronoi sites
+ \return Count of generated voronoi sites.
*/
- virtual uint32_t getVoronoiSites(const physx::PxVec3*& sites) = 0;
-
+ virtual uint32_t getVoronoiSites(const NvcVec3*& sites) = 0;
+
/**
- Add site in particular point
- \param[in] site Site coordinates
+ Add site in particular point
+ \param[in] site Site coordinates
*/
- virtual void addSite(const physx::PxVec3& site) = 0;
+ virtual void addSite(const NvcVec3& site) = 0;
/**
- Uniformly generate sites inside the mesh
- \param[in] numberOfSites Number of generated sites
+ Uniformly generate sites inside the mesh
+ \param[in] numberOfSites Number of generated sites
*/
- virtual void uniformlyGenerateSitesInMesh(uint32_t numberOfSites) = 0;
+ virtual void uniformlyGenerateSitesInMesh(uint32_t numberOfSites) = 0;
/**
- 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
+ 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
*/
- virtual void clusteredSitesGeneration(uint32_t numberOfClusters, uint32_t sitesPerCluster, float clusterRadius) = 0;
+ virtual void clusteredSitesGeneration(uint32_t numberOfClusters, uint32_t sitesPerCluster, float clusterRadius) = 0;
/**
- 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
+ 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
*/
- 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;
+ virtual void radialPattern(const NvcVec3& center, const NvcVec3& normal, float radius, int32_t angularSteps,
+ int32_t radialSteps, float angleOffset = 0.0f, float variability = 0.0f) = 0;
/**
- Generate sites inside sphere
- \param[in] count Count of generated sites
- \param[in] radius Radius of sphere
- \param[in] center Center of sphere
+ Generate sites inside sphere
+ \param[in] count Count of generated sites
+ \param[in] radius Radius of sphere
+ \param[in] center Center of sphere
*/
- virtual void generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center) = 0;
+ virtual void generateInSphere(const uint32_t count, const float radius, const NvcVec3& center) = 0;
/**
- Set stencil mesh. With stencil mesh sites are generated only inside both of fracture and stencil meshes.
- \param[in] stencil Stencil mesh.
+ Set stencil mesh. With stencil mesh sites are generated only inside both of fracture and stencil meshes.
+ \param[in] stencil Stencil mesh.
*/
- virtual void setStencil(const Mesh* stencil) = 0;
+ virtual void setStencil(const Mesh* stencil) = 0;
/**
- Removes stencil mesh
+ Removes stencil mesh
*/
- virtual void clearStencil() = 0;
+ virtual void clearStencil() = 0;
- /**
- 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
+ /**
+ 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
*/
- virtual void deleteInSphere(const float radius, const physx::PxVec3& center, const float eraserProbability = 1) = 0;
+ virtual void deleteInSphere(const float radius, const NvcVec3& center, const float eraserProbability = 1) = 0;
};
/**
- FractureTool class provides methods to fracture provided mesh and generate Blast asset data
+ FractureTool class provides methods to fracture provided mesh and generate Blast asset data
*/
class FractureTool
{
-public:
+ public:
virtual ~FractureTool() {}
/**
- Release FractureTool memory
+ Release FractureTool memory
*/
- virtual void release() = 0;
+ virtual void release() = 0;
/**
- Reset FractureTool state.
+ Reset FractureTool state.
*/
- virtual void reset() = 0;
-
-
+ virtual void reset() = 0;
+
+
/**
- Set input mesh which will be fractured, FractureTool will be reseted.
+ Set input mesh which will be fractured, FractureTool will be reseted.
*/
- virtual void setSourceMesh(const Mesh* mesh) = 0;
+ virtual void setSourceMesh(const Mesh* mesh) = 0;
/**
- Set chunk mesh, parentId should be valid, return id of new chunk.
+ Set chunk mesh, parentId should be valid, return id of new chunk.
*/
- virtual int32_t setChunkMesh(const Mesh* mesh, int32_t parentId) = 0;
+ virtual int32_t setChunkMesh(const Mesh* mesh, int32_t parentId) = 0;
/**
- Set the material id to use for new interior faces. Defaults to MATERIAL_INTERIOR
+ Set the material id to use for new interior faces. Defaults to kMaterialInteriorId
*/
- virtual void setInteriorMaterialId(int32_t materialId) = 0;
+ virtual void setInteriorMaterialId(int32_t materialId) = 0;
/**
Gets the material id to use for new interior faces
*/
- virtual int32_t getInteriorMaterialId() const = 0;
+ virtual int32_t getInteriorMaterialId() const = 0;
/**
Replaces an material id on faces with a new one
*/
- virtual void replaceMaterialId(int32_t oldMaterialId, int32_t newMaterialId) = 0;
+ virtual void replaceMaterialId(int32_t oldMaterialId, int32_t newMaterialId) = 0;
/**
- Get chunk mesh in polygonal representation. User's code should release it after usage.
+ Get chunk mesh in polygonal representation. User's code should release it after usage.
*/
- virtual Mesh* createChunkMesh(int32_t chunkId) = 0;
+ 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;
+ Input mesh is scaled and transformed internally to fit unit cube centered in origin.
+ Method provides offset vector and scale parameter;
*/
- virtual void getTransformation(physx::PxVec3& offset, float& scale) = 0;
+ virtual void getTransformation(NvcVec3& offset, float& scale) = 0;
/**
- 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.
+ 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.
*/
- virtual int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPoints, bool replaceChunk) = 0;
+ virtual int32_t
+ voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const NvcVec3* cellPoints, bool replaceChunk) = 0;
/**
- 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] rotation Voronoi cells rotation. Has no effect without cells scale 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.
+ 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] rotation Voronoi cells rotation. Has no effect without cells scale 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.
*/
- virtual int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPoints, const physx::PxVec3& scale, const physx::PxQuat& rotation, bool replaceChunk) = 0;
+ virtual int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const NvcVec3* cellPoints,
+ const NvcVec3& scale, const NvcQuat& rotation, bool replaceChunk) = 0;
/**
- 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
+ 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.
+ \return If 0, fracturing is successful.
*/
- virtual int32_t slicing(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk, RandomGeneratorBase* rnd) = 0;
+ virtual int32_t
+ slicing(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk, RandomGeneratorBase* rnd) = 0;
/**
- Cut chunk with plane.
- \param[in] chunkId Chunk to fracture
- \param[in] normal Plane normal
- \param[in] position Point on plane
- \param[in] noise Noise configuration for plane-chunk intersection, see NoiseConfiguration.
- \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
+ Cut chunk with plane.
+ \param[in] chunkId Chunk to fracture
+ \param[in] normal Plane normal
+ \param[in] position Point on plane
+ \param[in] noise Noise configuration for plane-chunk intersection, see NoiseConfiguration.
+ \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.
+ \return If 0, fracturing is successful.
*/
- virtual int32_t cut(uint32_t chunkId, const physx::PxVec3& normal, const physx::PxVec3& position, const NoiseConfiguration& noise, bool replaceChunk, RandomGeneratorBase* rnd) = 0;
+ virtual int32_t cut(uint32_t chunkId, const NvcVec3& normal, const NvcVec3& position,
+ const NoiseConfiguration& noise, bool replaceChunk, RandomGeneratorBase* rnd) = 0;
/**
- Cutout fracture for specified chunk.
- \param[in] chunkId Chunk to fracture
- \param[in] conf Cutout parameters, see CutoutConfiguration.
- \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
+ Cutout fracture for specified chunk.
+ \param[in] chunkId Chunk to fracture
+ \param[in] conf Cutout parameters, see CutoutConfiguration.
+ \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.
+ \return If 0, fracturing is successful.
*/
- virtual int32_t cutout(uint32_t chunkId, CutoutConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) = 0;
+ virtual int32_t cutout(uint32_t chunkId, CutoutConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) = 0;
/**
- Creates resulting fractured mesh geometry from intermediate format
+ Creates resulting fractured mesh geometry from intermediate format
*/
- virtual void finalizeFracturing() = 0;
-
+ virtual void finalizeFracturing() = 0;
+
/**
- Returns overall number of chunks in fracture.
+ Returns overall number of chunks in fracture.
*/
- virtual uint32_t getChunkCount() const = 0;
+ virtual uint32_t getChunkCount() const = 0;
/**
- Get chunk information
+ Get chunk information
*/
- virtual const ChunkInfo& getChunkInfo(int32_t chunkIndex) = 0;
+ virtual const ChunkInfo& getChunkInfo(int32_t chunkIndex) = 0;
/**
- 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
+ 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
*/
- virtual float getMeshOverlap(const Mesh& meshA, const Mesh& meshB) = 0;
+ 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
+ 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
*/
- virtual uint32_t getBaseMesh(int32_t chunkIndex, Triangle*& output) = 0;
+ virtual uint32_t getBaseMesh(int32_t chunkIndex, Triangle*& output) = 0;
/**
- Update chunk base mesh
- \note Doesn't allocates output array, Triangle* output should be preallocated by user
- \param[in] chunkIndex Chunk index
- \param[out] output Array of triangles to be filled
- \return number of triangles in base mesh
+ Update chunk base mesh
+ \note Doesn't allocates output array, Triangle* output should be preallocated by user
+ \param[in] chunkIndex Chunk index
+ \param[out] output Array of triangles to be filled
+ \return number of triangles in base mesh
*/
- virtual uint32_t updateBaseMesh(int32_t chunkIndex, Triangle* output) = 0;
+ virtual uint32_t updateBaseMesh(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.
+ Return index of chunk with specified chunkId
+ \param[in] chunkId Chunk ID
+ \return Chunk index in internal buffer, if not exist -1 is returned.
*/
- virtual int32_t getChunkIndex(int32_t chunkId) = 0;
+ 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.
+ Return id of chunk with specified index.
+ \param[in] chunkIndex Chunk index
+ \return Chunk id or -1 if there is no such chunk.
*/
- virtual int32_t getChunkId(int32_t chunkIndex) = 0;
+ 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.
+ Return depth level of the given chunk
+ \param[in] chunkId Chunk ID
+ \return Chunk depth or -1 if there is no such chunk.
*/
- virtual int32_t getChunkDepth(int32_t chunkId) = 0;
+ virtual int32_t getChunkDepth(int32_t chunkId) = 0;
/**
- Return array of chunks IDs with given depth.
- \param[in] depth Chunk depth
- \param[out] Pointer to array of chunk IDs
- \return Number of chunks in array
+ Return array of chunks IDs with given depth.
+ \param[in] depth Chunk depth
+ \param[out] Pointer to array of chunk IDs
+ \return Number of chunks in array
*/
- virtual uint32_t getChunksIdAtDepth(uint32_t depth, int32_t*& chunkIds) = 0;
+ 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 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
+ 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 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
*/
- virtual uint32_t getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t*& indexBuffer, uint32_t*& indexBufferOffsets) = 0;
+ 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.
+ Set automatic islands removing. May cause instabilities.
+ \param[in] isRemoveIslands Flag whether remove or not islands.
*/
- virtual void setRemoveIslands(bool isRemoveIslands) = 0;
+ 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
+ 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
*/
- virtual int32_t islandDetectionAndRemoving(int32_t chunkId, bool createAtNewDepth = false) = 0;
+ virtual int32_t islandDetectionAndRemoving(int32_t chunkId, bool createAtNewDepth = false) = 0;
/**
- Check if input mesh contains open edges. Open edges can lead to wrong fracturing results.
- \return true if mesh contains open edges
+ Check if input mesh contains open edges. Open edges can lead to wrong fracturing results.
+ \return true if mesh contains open edges
*/
- virtual bool isMeshContainOpenEdges(const Mesh* input) = 0;
+ virtual bool isMeshContainOpenEdges(const Mesh* input) = 0;
/**
- Delete all children for specified chunk (also recursively delete chidren of children).
- \param[in] chunkId Chunk ID which children should be deleted
- \return true if one or more chunks were removed
+ Delete all children for specified chunk (also recursively delete chidren of children).
+ \param[in] chunkId Chunk ID which children should be deleted
+ \return true if one or more chunks were removed
*/
- virtual bool deleteAllChildrenOfChunk(int32_t chunkId) = 0;
+ virtual bool deleteAllChildrenOfChunk(int32_t chunkId) = 0;
/**
- Optimize chunk hierarhy for better runtime performance.
- It tries to unite chunks to groups of some size in order to transform flat hierarchy (all chunks are children of single root)
- to tree like hieracrhy with limited number of children for each chunk.
- \param[in] maxAtLevel If number of children of some chunk less then maxAtLevel then it would be considered as already optimized and skipped.
- \param[in] maxGroupSize Max number of children for processed chunks.
+ Optimize chunk hierarhy for better runtime performance.
+ It tries to unite chunks to groups of some size in order to transform flat hierarchy (all chunks are children of
+ single root) to tree like hieracrhy with limited number of children for each chunk.
+ \param[in] maxAtLevel If number of children of some chunk less then maxAtLevel then it would be considered as already
+ optimized and skipped.
+ \param[in] maxGroupSize Max number of children for processed chunks. \param[in] removeOriginalChunks.
+ \param[in] adjChunks Optional index pairs to describe chunk adjacency. May be NULL.
+ \param[in] adjChunksSize If 'adjChunks' is not NULL, the number of index pairs in the adjChunks array.
+ \param[in] removeOriginalChunks If true, original chunks that are merged are removed.
*/
- virtual void uniteChunks(uint32_t maxAtLevel, uint32_t maxGroupSize) = 0;
+ virtual void uniteChunks(uint32_t maxAtLevel, uint32_t maxGroupSize,
+ const NvcVec2i* adjChunks, uint32_t adjChunksSize,
+ bool removeOriginalChunks = false) = 0;
/**
- Rescale interior uv coordinates of given chunk to fit square of given size.
- \param[in] side Size of square side
- \param[in] chunkId Chunk ID for which UVs should be scaled.
+ Rescale interior uv coordinates of given chunk to fit square of given size.
+ \param[in] side Size of square side
+ \param[in] chunkId Chunk ID for which UVs should be scaled.
*/
- virtual void fitUvToRect(float side, uint32_t chunkId) = 0;
+ virtual void fitUvToRect(float side, uint32_t chunkId) = 0;
/**
- Rescale interior uv coordinates of all existing chunks to fit square of given size, relative sizes will be preserved.
- \param[in] side Size of square side
+ Rescale interior uv coordinates of all existing chunks to fit square of given size, relative sizes will be
+ preserved. \param[in] side Size of square side
*/
- virtual void fitAllUvToRect(float side) = 0;
-
+ virtual void fitAllUvToRect(float side) = 0;
};
-} // namespace Blast
-} // namespace Nv
+} // namespace Blast
+} // namespace Nv
-#endif // ifndef NVBLASTAUTHORINGFRACTURETOOL_H
+#endif // ifndef NVBLASTAUTHORINGFRACTURETOOL_H
diff --git a/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp b/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp index e69d039..847df77 100755 --- a/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp @@ -31,7 +31,6 @@ #include "PxMat44.h"
#include "PxBounds3.h"
#include "PxFoundation.h"
-#include "PxPhysics.h"
#include "PsVecMath.h"
#include <vector>
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp index ef012d6..a0e6fc2 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoring.cpp @@ -26,20 +26,21 @@ // Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
#include "NvBlastExtAuthoring.h"
-#include "NvBlastExtAuthoringMeshImpl.h"
-#include "NvBlastExtAuthoringMeshCleanerImpl.h"
-#include "NvBlastExtAuthoringFractureToolImpl.h"
-#include "NvBlastExtAuthoringCollisionBuilderImpl.h"
-#include "NvBlastExtAuthoringBondGeneratorImpl.h"
-#include "NvBlastExtAuthoringCutoutImpl.h"
#include "NvBlastTypes.h"
#include "NvBlastIndexFns.h"
#include "NvBlast.h"
+#include "NvBlastAssert.h"
#include "NvBlastGlobals.h"
-#include "NvBlastExtPxAsset.h"
#include "NvBlastExtAssetUtils.h"
#include "NvBlastExtAuthoringPatternGeneratorImpl.h"
#include "NvBlastExtAuthoringAccelerator.h"
+#include "NvBlastExtAuthoringMeshImpl.h"
+#include "NvBlastExtAuthoringMeshCleanerImpl.h"
+#include "NvBlastExtAuthoringFractureToolImpl.h"
+#include "NvBlastExtAuthoringBondGeneratorImpl.h"
+#include "NvBlastExtAuthoringCollisionBuilderImpl.h"
+#include "NvBlastExtAuthoringCutoutImpl.h"
+#include "NvBlastPxSharedHelpers.h"
#include <algorithm>
#include <memory>
@@ -50,7 +51,7 @@ using namespace physx; #define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? reinterpret_cast<T*>(NVBLAST_ALLOC(sizeof(T) * (x))) : nullptr;
#define SAFE_ARRAY_DELETE(x) if (x != nullptr) {NVBLAST_FREE(x); x = nullptr;}
-Mesh* NvBlastExtAuthoringCreateMesh(const PxVec3* position, const PxVec3* normals, const PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount)
+Mesh* NvBlastExtAuthoringCreateMesh(const NvcVec3* position, const NvcVec3* normals, const NvcVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount)
{
return new MeshImpl(position, normals, uv, verticesCount, indices, indicesCount);
}
@@ -91,18 +92,28 @@ FractureTool* NvBlastExtAuthoringCreateFractureTool() return new FractureToolImpl;
}
-BlastBondGenerator* NvBlastExtAuthoringCreateBondGenerator(PxCooking* cooking, PxPhysicsInsertionCallback* insertionCallback)
+BlastBondGenerator* NvBlastExtAuthoringCreateBondGenerator(Nv::Blast::ConvexMeshBuilder* builder)
{
- return new BlastBondGeneratorImpl(cooking, insertionCallback);
+ return new BlastBondGeneratorImpl(builder);
}
-ConvexMeshBuilder* NvBlastExtAuthoringCreateConvexMeshBuilder(PxCooking* cooking, PxPhysicsInsertionCallback* insertionCallback)
+int32_t NvBlastExtAuthoringBuildMeshConvexDecomposition(ConvexMeshBuilder* cmb, const Nv::Blast::Triangle* mesh,
+ uint32_t triangleCount,
+ const ConvexDecompositionParams& params,
+ CollisionHull**& convexes)
{
- return new ConvexMeshBuilderImpl(cooking, insertionCallback);
+ NVBLAST_ASSERT(cmb != nullptr);
+ return buildMeshConvexDecomposition(*cmb, mesh, triangleCount, params, convexes);
}
-void NvBlastExtAuthoringTransformCollisionHullInPlace(CollisionHull* hull, const physx::PxVec3* scaling, const physx::PxQuat* rotation, const physx::PxVec3* translation)
+void NvBlastExtAuthoringTrimCollisionGeometry(ConvexMeshBuilder* cmb, uint32_t chunksCount,
+ Nv::Blast::CollisionHull** in, const uint32_t* chunkDepth)
+{
+ return trimCollisionGeometry(*cmb, chunksCount, in, chunkDepth);
+}
+
+void NvBlastExtAuthoringTransformCollisionHullInPlace(CollisionHull* hull, const NvcVec3* scaling, const NvcQuat* rotation, const NvcVec3* translation)
{
// Local copies of scaling (S), rotation (R), and translation (T)
physx::PxVec3 S = { 1, 1, 1 };
@@ -114,12 +125,12 @@ void NvBlastExtAuthoringTransformCollisionHullInPlace(CollisionHull* hull, const {
if (rotation)
{
- R = *rotation;
+ R = *toPxShared(rotation);
}
if (scaling)
{
- S = *scaling;
+ S = *toPxShared(scaling);
cofS.x = S.y * S.z;
cofS.y = S.z * S.x;
cofS.z = S.x * S.y;
@@ -128,21 +139,21 @@ void NvBlastExtAuthoringTransformCollisionHullInPlace(CollisionHull* hull, const if (translation)
{
- T = *translation;
+ T = *toPxShared(translation);
}
}
const uint32_t pointCount = hull->pointsCount;
for (uint32_t pi = 0; pi < pointCount; pi++)
{
- physx::PxVec3& p = hull->points[pi];
+ physx::PxVec3& p = toPxShared(hull->points[pi]);
p = (R.rotate(p.multiply(S)) + T);
}
const uint32_t planeCount = hull->polygonDataCount;
for (uint32_t pi = 0; pi < planeCount; pi++)
{
- float* plane = hull->polygonData[pi].mPlane;
+ float* plane = hull->polygonData[pi].plane;
physx::PxPlane pxPlane(plane[0], plane[1], plane[2], plane[3]);
PxVec3 transformedNormal = sgnDetS*R.rotate(pxPlane.n.multiply(cofS)).getNormalized();
PxVec3 transformedPt = R.rotate(pxPlane.pointInPlane().multiply(S)) + T;
@@ -156,14 +167,20 @@ void NvBlastExtAuthoringTransformCollisionHullInPlace(CollisionHull* hull, const }
-CollisionHull* NvBlastExtAuthoringTransformCollisionHull(const CollisionHull* hull, const physx::PxVec3* scaling, const physx::PxQuat* rotation, const physx::PxVec3* translation)
+CollisionHull* NvBlastExtAuthoringTransformCollisionHull(const CollisionHull* hull, const NvcVec3* scaling, const NvcQuat* rotation, const NvcVec3* translation)
{
- CollisionHullImpl* ret = new CollisionHullImpl(*hull);
+ CollisionHull* ret = new CollisionHull(*hull);
+ ret->points = SAFE_ARRAY_NEW(NvcVec3, ret->pointsCount);
+ ret->indices = SAFE_ARRAY_NEW(uint32_t, ret->indicesCount);
+ ret->polygonData = SAFE_ARRAY_NEW(HullPolygon, ret->polygonDataCount);
+ memcpy(ret->points, hull->points, sizeof(ret->points[0]) * ret->pointsCount);
+ memcpy(ret->indices, hull->indices, sizeof(ret->indices[0]) * ret->indicesCount);
+ memcpy(ret->polygonData, hull->polygonData, sizeof(ret->polygonData[0]) * ret->polygonDataCount);
NvBlastExtAuthoringTransformCollisionHullInPlace(ret, scaling, rotation, translation);
return ret;
}
-void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& result, const CollisionParams& params, uint32_t chunksToProcessCount = 0, uint32_t* chunksToProcess = nullptr)
+void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& result, const ConvexDecompositionParams& params, uint32_t chunksToProcessCount = 0, uint32_t* chunksToProcess = nullptr)
{
uint32_t chunkCount = (uint32_t)result.chunkCount;
if (params.maximumNumberOfHulls == 1)
@@ -171,11 +188,9 @@ void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& re 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;
+ std::vector<NvcVec3> vertices;
for (uint32_t p = result.geometryOffset[i]; p < result.geometryOffset[i + 1]; ++p)
{
Nv::Blast::Triangle& tri = result.geometry[p];
@@ -185,13 +200,6 @@ void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& re }
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];
}
}
else
@@ -219,7 +227,8 @@ void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& re CollisionHull** tempHull;
- int32_t newHulls = collisionBuilder.buildMeshConvexDecomposition(result.geometry + result.geometryOffset[i],
+ int32_t newHulls =
+ buildMeshConvexDecomposition(collisionBuilder, result.geometry + result.geometryOffset[i],
result.geometryOffset[i + 1] - result.geometryOffset[i], params, tempHull);
totalHulls += newHulls;
for (int32_t h = 0; h < newHulls; ++h)
@@ -232,10 +241,7 @@ void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& re result.collisionHullOffset = SAFE_ARRAY_NEW(uint32_t, chunkCount + 1);
result.collisionHullOffset[0] = 0;
result.collisionHull = SAFE_ARRAY_NEW(CollisionHull*, totalHulls);
- result.physicsSubchunks = SAFE_ARRAY_NEW(ExtPxSubchunk, totalHulls);
- result.physicsChunks = SAFE_ARRAY_NEW(ExtPxChunk, chunkCount);
- int32_t firstSubchunk = 0;
for (uint32_t i = 0; i < chunkCount; ++i)
{
result.collisionHullOffset[i + 1] = result.collisionHullOffset[i] + hulls[i].size();
@@ -243,57 +249,42 @@ void buildPhysicsChunks(ConvexMeshBuilder& collisionBuilder, AuthoringResult& re for (uint32_t subhull = 0; subhull < hulls[i].size(); ++subhull)
{
result.collisionHull[off + subhull] = hulls[i][subhull];
- result.physicsSubchunks[firstSubchunk + subhull].transform = physx::PxTransform(physx::PxIdentity);
- result.physicsSubchunks[firstSubchunk + subhull].geometry = physx::PxConvexMeshGeometry(collisionBuilder.buildConvexMesh(*hulls[i][subhull]));
}
- result.physicsChunks[i].isStatic = false;
- result.physicsChunks[i].subchunkCount = static_cast<uint32_t>(hulls[i].size());
- result.physicsChunks[i].firstSubchunkIndex = firstSubchunk;
- firstSubchunk += result.physicsChunks[i].subchunkCount;
}
}
}
-struct AuthoringResultImpl : public AuthoringResult
+void NvBlastExtAuthoringReleaseAuthoringResultCollision(Nv::Blast::ConvexMeshBuilder& collisionBuilder, Nv::Blast::AuthoringResult* ar)
{
- AuthoringResultImpl()
- {
- collisionHullOffset = nullptr;
- collisionHull = nullptr;
- physicsChunks = nullptr;
- physicsSubchunks = nullptr;
- }
-
- void releaseCollisionHulls() override
+ if (ar->collisionHull != nullptr)
{
- if (collisionHull != nullptr)
+ for (uint32_t ch = 0; ch < ar->collisionHullOffset[ar->chunkCount]; ch++)
{
- for (uint32_t ch = 0; ch < collisionHullOffset[chunkCount]; ch++)
- {
- collisionHull[ch]->release();
- }
- SAFE_ARRAY_DELETE(collisionHullOffset);
- SAFE_ARRAY_DELETE(collisionHull);
+ collisionBuilder.releaseCollisionHull(ar->collisionHull[ch]);
}
+ SAFE_ARRAY_DELETE(ar->collisionHullOffset);
+ SAFE_ARRAY_DELETE(ar->collisionHull);
}
+}
- void release() override
+void NvBlastExtAuthoringReleaseAuthoringResult(Nv::Blast::ConvexMeshBuilder& collisionBuilder, Nv::Blast::AuthoringResult* ar)
+{
+ NvBlastExtAuthoringReleaseAuthoringResultCollision(collisionBuilder, ar);
+ if (ar->asset)
{
- 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;
+ NVBLAST_FREE(ar->asset);
+ ar->asset = nullptr;
}
-};
+ SAFE_ARRAY_DELETE(ar->assetToFractureChunkIdMap);
+ SAFE_ARRAY_DELETE(ar->geometryOffset);
+ SAFE_ARRAY_DELETE(ar->geometry);
+ SAFE_ARRAY_DELETE(ar->chunkDescs);
+ SAFE_ARRAY_DELETE(ar->bondDescs);
+ delete ar;
+}
-AuthoringResult* NvBlastExtAuthoringProcessFracture(FractureTool& fTool, BlastBondGenerator& bondGenerator, ConvexMeshBuilder& collisionBuilder, const CollisionParams& collisionParam, int32_t defaultSupportDepth)
+AuthoringResult* NvBlastExtAuthoringProcessFracture(FractureTool& fTool, BlastBondGenerator& bondGenerator, ConvexMeshBuilder& collisionBuilder, const ConvexDecompositionParams& collisionParam, int32_t defaultSupportDepth)
{
fTool.finalizeFracturing();
const uint32_t chunkCount = fTool.getChunkCount();
@@ -301,7 +292,7 @@ AuthoringResult* NvBlastExtAuthoringProcessFracture(FractureTool& fTool, BlastBo {
return nullptr;
}
- AuthoringResultImpl* ret = new AuthoringResultImpl;
+ AuthoringResult* ret = new AuthoringResult;
if (ret == nullptr)
{
return nullptr;
@@ -390,21 +381,21 @@ AuthoringResult* NvBlastExtAuthoringProcessFracture(FractureTool& fTool, BlastBo buildPhysicsChunks(collisionBuilder, aResult, collisionParam);
// 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;
- }
+ //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;
@@ -431,9 +422,9 @@ AuthoringResult* NvBlastExtAuthoringProcessFracture(FractureTool& fTool, BlastBo uint32_t NvBlastExtAuthoringFindAssetConnectingBonds
(
const NvBlastAsset** components,
- const physx::PxVec3* scales,
- const physx::PxQuat* rotations,
- const physx::PxVec3* translations,
+ const NvcVec3* scales,
+ const NvcQuat* rotations,
+ const NvcVec3* translations,
const uint32_t** convexHullOffsets,
const CollisionHull*** chunkHulls,
uint32_t componentCount,
@@ -442,7 +433,7 @@ uint32_t NvBlastExtAuthoringFindAssetConnectingBonds )
{
//We don't need to use any of the cooking related parts of this
- BlastBondGeneratorImpl bondGenerator(nullptr, nullptr);
+ BlastBondGeneratorImpl bondGenerator(nullptr);
std::vector<uint32_t> componentChunkOffsets;
componentChunkOffsets.reserve(componentCount + 1);
@@ -461,9 +452,9 @@ uint32_t NvBlastExtAuthoringFindAssetConnectingBonds for (uint32_t c = 0; c < componentCount; c++)
{
const uint32_t chunkCount = NvBlastAssetGetChunkCount(components[c], &logLL);
- const physx::PxVec3* scale = scales ? scales + c : nullptr;
- const physx::PxQuat* rotation = rotations ? rotations + c : nullptr;
- const physx::PxVec3* translation = translations ? translations + c : nullptr;
+ const NvcVec3* scale = scales ? scales + c : nullptr;
+ const NvcQuat* rotation = rotations ? rotations + c : nullptr;
+ const NvcVec3* translation = translations ? translations + c : nullptr;
componentChunkOffsets.push_back(chunkCount + componentChunkOffsets.back());
for (uint32_t chunk = 0; chunk < chunkCount; chunk++)
@@ -472,7 +463,9 @@ uint32_t NvBlastExtAuthoringFindAssetConnectingBonds const uint32_t hullsEnd = convexHullOffsets[c][chunk + 1];
for (uint32_t hull = hullsStart; hull < hullsEnd; hull++)
{
- if ((scale != nullptr && *scale != identityScale) || (rotation != nullptr && !rotation->isIdentity()) || (translation != nullptr && !translation->isZero()))
+ if ((scale != nullptr && *toPxShared(scale) != identityScale) ||
+ (rotation != nullptr && !toPxShared(rotation)->isIdentity()) ||
+ (translation != nullptr && !toPxShared(translation)->isZero()))
{
hullsToRelease.emplace_back(NvBlastExtAuthoringTransformCollisionHull(chunkHulls[c][hull], scale, rotation, translation));
combinedConvexHulls.emplace_back(hullsToRelease.back());
@@ -523,7 +516,7 @@ uint32_t NvBlastExtAuthoringFindAssetConnectingBonds for (CollisionHull* hull : hullsToRelease)
{
- hull->release();
+ delete hull;
}
return newBoundCount;
@@ -540,7 +533,7 @@ void NvBlastExtAuthoringUpdateGraphicsMesh(Nv::Blast::FractureTool& fTool, Nv::B }
void NvBlastExtAuthoringBuildCollisionMeshes(Nv::Blast::AuthoringResult& ares, Nv::Blast::ConvexMeshBuilder& collisionBuilder,
- const Nv::Blast::CollisionParams& collisionParam, uint32_t chunksToProcessCount, uint32_t* chunksToProcess)
+ const Nv::Blast::ConvexDecompositionParams& collisionParam, uint32_t chunksToProcessCount, uint32_t* chunksToProcess)
{
buildPhysicsChunks(collisionBuilder, ares, collisionParam, chunksToProcessCount, chunksToProcess);
}
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp index 1952e0f..318479f 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp @@ -36,9 +36,9 @@ #include <NvBlastExtAuthoringBondGeneratorImpl.h>
#include <NvBlast.h>
#include <NvBlastGlobals.h>
+#include <NvBlastPxSharedHelpers.h>
#include "NvBlastExtTriangleProcessor.h"
#include "NvBlastExtApexSharedParts.h"
-#include "NvBlastExtAuthoringCollisionBuilderImpl.h"
#include "NvBlastExtAuthoringInternalCommon.h"
#include "NvBlastExtAuthoringTypes.h"
#include <vector>
@@ -49,9 +49,6 @@ #include <memory>
#include <set>
-using physx::PxVec3;
-using physx::PxBounds3;
-
#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? reinterpret_cast<T*>(NVBLAST_ALLOC(sizeof(T) * (x))) : nullptr;
//#define DEBUG_OUTPUT
@@ -59,7 +56,7 @@ using physx::PxBounds3; void saveGeometryToObj(std::vector<PxVec3>& triangles, const char* filepath)
{
-
+
FILE* outStream = fopen(filepath, "w");
for (uint32_t i = 0; i < triangles.size(); ++i)
@@ -72,7 +69,8 @@ void saveGeometryToObj(std::vector<PxVec3>& triangles, const char* filepath) }
for (uint32_t i = 0; i < triangles.size() / 3; ++i)
{
- PxVec3 normal = (triangles[3 * i + 2] - triangles[3 * i]).cross((triangles[3 * i + 1] - triangles[3 * i])).getNormalized();
+ PxVec3 normal =
+ (triangles[3 * i + 2] - triangles[3 * i]).cross((triangles[3 * i + 1] - triangles[3 * i])).getNormalized();
fprintf(outStream, "vn %lf %lf %lf\n", normal.x, normal.y, normal.z);
fprintf(outStream, "vn %lf %lf %lf\n", normal.x, normal.y, normal.z);
fprintf(outStream, "vn %lf %lf %lf\n", normal.x, normal.y, normal.z);
@@ -89,1322 +87,1383 @@ void saveGeometryToObj(std::vector<PxVec3>& triangles, const char* filepath) }
fclose(outStream);
-
}
std::vector<PxVec3> intersectionBuffer;
std::vector<PxVec3> meshBuffer;
-#endif
+#endif
namespace Nv
{
- namespace Blast
- {
+namespace Blast
+{
- #define EPS_PLANE 0.0001f
-
- bool planeComparer(const PlaneChunkIndexer& as, const PlaneChunkIndexer& bs)
- {
- const PxPlane& a = as.plane;
- const PxPlane& b = bs.plane;
-
- if (a.d + EPS_PLANE < b.d) return true;
- if (a.d - EPS_PLANE > b.d) return false;
- if (a.n.x + EPS_PLANE < b.n.x) return true;
- if (a.n.x - EPS_PLANE > b.n.x) return false;
- if (a.n.y + EPS_PLANE < b.n.y) return true;
- if (a.n.y - EPS_PLANE > b.n.y) return false;
- return a.n.z + EPS_PLANE < b.n.z;
- }
+#define EPS_PLANE 0.0001f
+physx::PxVec3 getNormal(const Triangle& t)
+{
+ return toPxShared(t.b.p - t.a.p).cross(toPxShared(t.c.p - t.a.p));
+}
- struct Bond
- {
- int32_t m_chunkId;
- int32_t m_planeIndex;
- int32_t triangleIndex;
+bool planeComparer(const PlaneChunkIndexer& as, const PlaneChunkIndexer& bs)
+{
+ const NvcPlane& a = as.plane;
+ const NvcPlane& b = bs.plane;
+
+ if (a.d + EPS_PLANE < b.d)
+ return true;
+ if (a.d - EPS_PLANE > b.d)
+ return false;
+ if (a.n.x + EPS_PLANE < b.n.x)
+ return true;
+ if (a.n.x - EPS_PLANE > b.n.x)
+ return false;
+ if (a.n.y + EPS_PLANE < b.n.y)
+ return true;
+ if (a.n.y - EPS_PLANE > b.n.y)
+ return false;
+ return a.n.z + EPS_PLANE < b.n.z;
+}
- bool operator<(const Bond& inp) const
- {
- if (abs(m_planeIndex) == abs(inp.m_planeIndex))
- {
- return m_chunkId < inp.m_chunkId;
- }
- else
- {
- return abs(m_planeIndex) < abs(inp.m_planeIndex);
- }
- }
- };
+struct Bond
+{
+ int32_t m_chunkId;
+ int32_t m_planeIndex;
+ int32_t triangleIndex;
- struct BondInfo
+ bool operator<(const Bond& inp) const
+ {
+ if (abs(m_planeIndex) == abs(inp.m_planeIndex))
{
- float area;
- physx::PxBounds3 m_bb;
- physx::PxVec3 centroid;
- physx::PxVec3 normal;
- int32_t m_chunkId;
- };
-
- void AddTtAnchorPoints(const Triangle* a, const Triangle* b, std::vector<PxVec3>& points)
+ return m_chunkId < inp.m_chunkId;
+ }
+ else
{
- PxVec3 na = a->getNormal().getNormalized();
- PxVec3 nb = b->getNormal().getNormalized();
-
- PxPlane pla(a->a.p, na);
- PxPlane plb(b->a.p, nb);
-
-
- ProjectionDirections da = getProjectionDirection(na);
- ProjectionDirections db = getProjectionDirection(nb);
-
- TriangleProcessor prc;
-
- TrPrcTriangle2d ta(getProjectedPoint(a->a.p, da), getProjectedPoint(a->b.p, da), getProjectedPoint(a->c.p, da));
- TrPrcTriangle2d tb(getProjectedPoint(b->a.p, db), getProjectedPoint(b->b.p, db), getProjectedPoint(b->c.p, db));
-
- /**
- Compute
- */
- for (uint32_t i = 0; i < 3; ++i)
- {
- PxVec3 pt;
- if (getPlaneSegmentIntersection(pla, b->getVertex(i).p, b->getVertex((i + 1) % 3).p, pt))
- {
+ return abs(m_planeIndex) < abs(inp.m_planeIndex);
+ }
+ }
+};
- PxVec2 pt2 = getProjectedPoint(pt, da);
- if (prc.isPointInside(pt2, ta))
- {
- points.push_back(pt);
- }
- }
- if (getPlaneSegmentIntersection(plb, a->getVertex(i).p, a->getVertex((i + 1) % 3).p, pt))
- {
- PxVec2 pt2 = getProjectedPoint(pt, db);
- if (prc.isPointInside(pt2, tb))
- {
- points.push_back(pt);
- }
- }
- }
- }
+struct BondInfo
+{
+ float area;
+ physx::PxBounds3 m_bb;
+ physx::PxVec3 centroid;
+ physx::PxVec3 normal;
+ int32_t m_chunkId;
+};
+
+inline physx::PxVec3 getVertex(const Triangle& t, uint32_t i)
+{
+ return toPxShared((&t.a)[i].p);
+}
+void AddTtAnchorPoints(const Triangle* a, const Triangle* b, std::vector<PxVec3>& points)
+{
+ physx::PxVec3 na = getNormal(*a).getNormalized();
+ physx::PxVec3 nb = getNormal(*b).getNormalized();
- inline bool pointInsidePoly(const PxVec3& pt, const uint8_t *indices, uint16_t indexCount, const PxVec3 *verts, const PxVec3& n)
- {
- int s = 0;
- for (uint16_t i = 0; i < indexCount; ++i)
- {
- const PxVec3 r0 = verts[indices[i]] - pt;
- const PxVec3 r1 = verts[indices[(i + 1) % indexCount]] - pt;
- const float cn = r0.cross(r1).dot(n);
- const int cns = cn >= 0 ? 1 : -1;
- if (!s)
- {
- s = cns;
- }
- if (cns*s < 0)
- {
- return false;
- }
- }
- return true;
- }
+ physx::PxPlane pla(toPxShared(a->a.p), na);
+ physx::PxPlane plb(toPxShared(b->a.p), nb);
- void AddPpAnchorPoints(
- const uint8_t* indicesA, uint16_t indexCountA, const PxVec3* vertsA, const float planeA[4],
- const uint8_t* indicesB, uint16_t indexCountB, const PxVec3* vertsB, const float planeB[4],
- std::vector<PxVec3>& points)
- {
- PxPlane pla(planeA[0], planeA[1], planeA[2], planeA[3]);
- PxPlane plb(planeB[0], planeB[1], planeB[2], planeB[3]);
-
- for (uint16_t iA = 0; iA < indexCountA; ++iA)
- {
- PxVec3 pt;
- if (getPlaneSegmentIntersection(plb, vertsA[indicesA[iA]], vertsA[indicesA[(iA + 1) % indexCountA]], pt))
- {
- if (pointInsidePoly(pt, indicesB, indexCountB, vertsB, plb.n))
- {
- points.push_back(pt);
- }
- }
- }
-
- for (uint16_t iB = 0; iB < indexCountA; ++iB)
- {
- PxVec3 pt;
- if (getPlaneSegmentIntersection(pla, vertsB[indicesB[iB]], vertsB[indicesA[(iB + 1) % indexCountB]], pt))
- {
- if (pointInsidePoly(pt, indicesA, indexCountA, vertsA, pla.n))
- {
- points.push_back(pt);
- }
- }
- }
- }
-
-
- float BlastBondGeneratorImpl::processWithMidplanes(TriangleProcessor* trProcessor, const Triangle* mA, uint32_t mavc, const Triangle* mB, uint32_t mbvc,
- const CollisionHull* hull1, const CollisionHull* hull2, const std::vector<PxVec3>& hull1p, const std::vector<PxVec3>& hull2p, PxVec3& normal, PxVec3& centroid, float maxSeparation)
+
+ ProjectionDirections da = getProjectionDirection(na);
+ ProjectionDirections db = getProjectionDirection(nb);
+
+ TriangleProcessor prc;
+
+ TrPrcTriangle2d ta(getProjectedPoint(toPxShared(a->a.p), da), getProjectedPoint(toPxShared(a->b.p), da),
+ getProjectedPoint(toPxShared(a->c.p), da));
+ TrPrcTriangle2d tb(getProjectedPoint(toPxShared(b->a.p), db), getProjectedPoint(toPxShared(b->b.p), db),
+ getProjectedPoint(toPxShared(b->c.p), db));
+
+ /**
+ Compute
+ */
+ for (uint32_t i = 0; i < 3; ++i)
+ {
+ physx::PxVec3 pt;
+ if (getPlaneSegmentIntersection(pla, getVertex(*b, i), getVertex(*b, (i + 1) % 3), pt))
{
- PxBounds3 bounds;
- PxBounds3 aBounds;
- PxBounds3 bBounds;
- bounds.setEmpty();
- aBounds.setEmpty();
- bBounds.setEmpty();
-
- PxVec3 chunk1Centroid(0, 0, 0);
- PxVec3 chunk2Centroid(0, 0, 0);
-
- ///////////////////////////////////////////////////////////////////////////////////
- if (hull1p.size() < 4 || hull2p.size() < 4)
- {
- return 0.0;
- }
- for (uint32_t i = 0; i < hull1p.size(); ++i)
+ physx::PxVec2 pt2 = getProjectedPoint(pt, da);
+ if (prc.isPointInside(pt2, ta))
{
- chunk1Centroid += hull1p[i];
- bounds.include(hull1p[i]);
- aBounds.include(hull1p[i]);
+ points.push_back(pt);
}
- for (uint32_t i = 0; i < hull2p.size(); ++i)
+ }
+ if (getPlaneSegmentIntersection(plb, getVertex(*a, i), getVertex(*a, (i + 1) % 3), pt))
+ {
+ PxVec2 pt2 = getProjectedPoint(pt, db);
+ if (prc.isPointInside(pt2, tb))
{
- chunk2Centroid += hull2p[i];
- bounds.include(hull2p[i]);
- bBounds.include(hull2p[i]);
+ points.push_back(pt);
}
+ }
+ }
+}
- chunk1Centroid *= (1.0f / hull1p.size());
- chunk2Centroid *= (1.0f / hull2p.size());
+inline bool
+pointInsidePoly(const PxVec3& pt, const uint8_t* indices, uint16_t indexCount, const PxVec3* verts, const PxVec3& n)
+{
+ int s = 0;
+ for (uint16_t i = 0; i < indexCount; ++i)
+ {
+ const PxVec3 r0 = verts[indices[i]] - pt;
+ const PxVec3 r1 = verts[indices[(i + 1) % indexCount]] - pt;
+ const float cn = r0.cross(r1).dot(n);
+ const int cns = cn >= 0 ? 1 : -1;
+ if (!s)
+ {
+ s = cns;
+ }
+ if (cns * s < 0)
+ {
+ return false;
+ }
+ }
+ return true;
+}
-
+void AddPpAnchorPoints(const uint8_t* indicesA, uint16_t indexCountA, const PxVec3* vertsA, const float planeA[4],
+ const uint8_t* indicesB, uint16_t indexCountB, const PxVec3* vertsB, const float planeB[4],
+ std::vector<PxVec3>& points)
+{
+ PxPlane pla(planeA[0], planeA[1], planeA[2], planeA[3]);
+ PxPlane plb(planeB[0], planeB[1], planeB[2], planeB[3]);
- Separation 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), 2.0f * maxSeparation, &separation))
+ for (uint16_t iA = 0; iA < indexCountA; ++iA)
+ {
+ PxVec3 pt;
+ if (getPlaneSegmentIntersection(plb, vertsA[indicesA[iA]], vertsA[indicesA[(iA + 1) % indexCountA]], pt))
+ {
+ if (pointInsidePoly(pt, indicesB, indexCountB, vertsB, plb.n))
{
- return 0.0;
+ points.push_back(pt);
}
-
- const bool have_geometry = (mA != nullptr && mB != nullptr) || (hull1 != nullptr && hull2 != nullptr);
+ }
+ }
- if (separation.getDistance() > 0 || !have_geometry) // If chunks don't intersect then use midplane to produce bond, otherwise midplane can be wrong (only if we have geometry)
+ for (uint16_t iB = 0; iB < indexCountA; ++iB)
+ {
+ PxVec3 pt;
+ if (getPlaneSegmentIntersection(pla, vertsB[indicesB[iB]], vertsB[indicesA[(iB + 1) % indexCountB]], pt))
+ {
+ if (pointInsidePoly(pt, indicesA, indexCountA, vertsA, pla.n))
{
- // Build first plane interface
- PxPlane midplane = separation.plane;
- if (!midplane.n.isFinite())
- {
- return 0.0;
- }
+ points.push_back(pt);
+ }
+ }
+ }
+}
- std::vector<PxVec3> interfacePoints;
- float firstCentroidSide = (midplane.distance(chunk1Centroid) > 0) ? 1 : -1;
- float secondCentroidSide = (midplane.distance(chunk2Centroid) > 0) ? 1 : -1;
+float BlastBondGeneratorImpl::processWithMidplanes(TriangleProcessor* trProcessor, const Triangle* mA, uint32_t mavc,
+ const Triangle* mB, uint32_t mbvc, const CollisionHull* hull1,
+ const CollisionHull* hull2, const std::vector<PxVec3>& hull1p,
+ const std::vector<PxVec3>& hull2p, PxVec3& normal, PxVec3& centroid,
+ float maxSeparation)
+{
+ PxBounds3 bounds;
+ PxBounds3 aBounds;
+ PxBounds3 bBounds;
+ bounds.setEmpty();
+ aBounds.setEmpty();
+ bBounds.setEmpty();
+
+ PxVec3 chunk1Centroid(0, 0, 0);
+ PxVec3 chunk2Centroid(0, 0, 0);
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ if (hull1p.size() < 4 || hull2p.size() < 4)
+ {
+ return 0.0;
+ }
- for (uint32_t i = 0; i < hull1p.size(); ++i)
- {
- float dst = midplane.distance(hull1p[i]);
- if (dst * firstCentroidSide < maxSeparation)
- {
- interfacePoints.push_back(hull1p[i]);
- }
- }
+ for (uint32_t i = 0; i < hull1p.size(); ++i)
+ {
+ chunk1Centroid += hull1p[i];
+ bounds.include(hull1p[i]);
+ aBounds.include(hull1p[i]);
+ }
+ for (uint32_t i = 0; i < hull2p.size(); ++i)
+ {
+ chunk2Centroid += hull2p[i];
+ bounds.include(hull2p[i]);
+ bBounds.include(hull2p[i]);
+ }
- for (uint32_t i = 0; i < hull2p.size(); ++i)
- {
- float dst = midplane.distance(hull2p[i]);
- if (dst * secondCentroidSide < maxSeparation)
- {
- interfacePoints.push_back(hull2p[i]);
- }
- }
- std::vector<PxVec3> convexHull;
- trProcessor->buildConvexHull(interfacePoints, convexHull, midplane.n);
- float area = 0;
- PxVec3 centroidLocal(0, 0, 0);
- if (convexHull.size() < 3)
- {
- return 0.0;
- }
- for (uint32_t i = 0; i < convexHull.size() - 1; ++i)
- {
- centroidLocal += convexHull[i];
- area += (convexHull[i] - convexHull[0]).cross((convexHull[i + 1] - convexHull[0])).magnitude();
- }
- centroidLocal += convexHull.back();
- centroidLocal *= (1.0f / convexHull.size());
- float direction = midplane.n.dot(chunk2Centroid - chunk1Centroid);
- if (direction < 0)
- {
- normal = -1.0f * normal;
- }
- normal = midplane.n;
- centroid = centroidLocal;
- return area * 0.5f;
- }
- else
- {
- float area = 0.0f;
- std::vector<PxVec3> intersectionAnchors;
+ chunk1Centroid *= (1.0f / hull1p.size());
+ chunk2Centroid *= (1.0f / hull2p.size());
- if (mA != nullptr && mB != nullptr) // Use triangles
- {
- for (uint32_t i = 0; i < mavc; ++i)
- {
- for (uint32_t j = 0; j < mbvc; ++j)
- {
- AddTtAnchorPoints(mA + i, mB + j, intersectionAnchors);
- }
- }
- }
- else // Use hulls
- {
- for (uint32_t i1 = 0; i1 < hull1->polygonDataCount; ++i1)
- {
- CollisionHull::HullPolygon& poly1 = hull1->polygonData[i1];
- for (uint32_t i2 = 0; i2 < hull2->polygonDataCount; ++i2)
- {
- CollisionHull::HullPolygon& poly2 = hull2->polygonData[i2];
- AddPpAnchorPoints(
- reinterpret_cast<uint8_t*>(hull1->indices) + poly1.mIndexBase, poly1.mNbVerts, hull1->points, poly1.mPlane,
- reinterpret_cast<uint8_t*>(hull2->indices) + poly2.mIndexBase, poly2.mNbVerts, hull2->points, poly2.mPlane,
- intersectionAnchors);
- }
- }
- }
-
- PxVec3 lcoid(0, 0, 0);
- for (uint32_t i = 0; i < intersectionAnchors.size(); ++i)
- {
- lcoid += intersectionAnchors[i];
- }
- lcoid *= (1.0f / intersectionAnchors.size());
- centroid = lcoid;
-
- if (intersectionAnchors.size() < 2)
- {
- return 0;
- }
+ Separation 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), 2.0f * maxSeparation, &separation))
+ {
+ return 0.0;
+ }
- PxVec3 dir1 = intersectionAnchors[0] - lcoid;
- PxVec3 dir2(0, 0, 0);
- float maxMagn = 0.0f;
- float maxDist = 0.0f;
+ const bool have_geometry = (mA != nullptr && mB != nullptr) || (hull1 != nullptr && hull2 != nullptr);
+ if (separation.getDistance() > 0 || !have_geometry) // If chunks don't intersect then use midplane to produce bond,
+ // otherwise midplane can be wrong (only if we have geometry)
+ {
+ // Build first plane interface
+ PxPlane midplane = separation.plane;
+ if (!midplane.n.isFinite())
+ {
+ return 0.0;
+ }
- for (uint32_t j = 0; j < intersectionAnchors.size(); ++j)
- {
- float d = (intersectionAnchors[j] - lcoid).magnitude();
+ std::vector<PxVec3> interfacePoints;
- PxVec3 tempNormal = (intersectionAnchors[j] - lcoid).cross(dir1);
- maxDist = std::max(d, maxDist);
-
- if (tempNormal.magnitude() > maxMagn)
- {
- dir2 = tempNormal;
- }
-
- }
+ float firstCentroidSide = (midplane.distance(chunk1Centroid) > 0) ? 1 : -1;
+ float secondCentroidSide = (midplane.distance(chunk2Centroid) > 0) ? 1 : -1;
- normal = dir2.getNormalized();
-
- area = (maxDist * maxDist) * 3.14f; // Compute area like circle area;
-
- return area;
+ for (uint32_t i = 0; i < hull1p.size(); ++i)
+ {
+ float dst = midplane.distance(hull1p[i]);
+ if (dst * firstCentroidSide < maxSeparation)
+ {
+ interfacePoints.push_back(hull1p[i]);
}
}
-
- struct BondGenerationCandidate
+ for (uint32_t i = 0; i < hull2p.size(); ++i)
{
- PxVec3 point;
- bool end;
- uint32_t parentChunk;
- uint32_t parentComponent;
- BondGenerationCandidate();
- BondGenerationCandidate(const PxVec3& p, bool isEnd, uint32_t pr, uint32_t c) :point(p), end(isEnd), parentChunk(pr), parentComponent(c)
- { };
-
- bool operator<(const BondGenerationCandidate& in) const
+ float dst = midplane.distance(hull2p[i]);
+ if (dst * secondCentroidSide < maxSeparation)
{
- if (point.x < in.point.x) return true;
- if (point.x > in.point.x) return false;
-
- if (point.y < in.point.y) return true;
- if (point.y > in.point.y) return false;
-
- if (point.z < in.point.z) return true;
- if (point.z > in.point.z) return false;
-
- return end < in.end;
- };
- };
-
+ interfacePoints.push_back(hull2p[i]);
+ }
+ }
+ std::vector<PxVec3> convexHull;
+ trProcessor->buildConvexHull(interfacePoints, convexHull, midplane.n);
+ float area = 0;
+ PxVec3 centroidLocal(0, 0, 0);
+ if (convexHull.size() < 3)
+ {
+ return 0.0;
+ }
+ for (uint32_t i = 0; i < convexHull.size() - 1; ++i)
+ {
+ centroidLocal += convexHull[i];
+ area += (convexHull[i] - convexHull[0]).cross((convexHull[i + 1] - convexHull[0])).magnitude();
+ }
+ centroidLocal += convexHull.back();
+ centroidLocal *= (1.0f / convexHull.size());
+ float direction = midplane.n.dot(chunk2Centroid - chunk1Centroid);
+ if (direction < 0)
+ {
+ normal = -1.0f * normal;
+ }
+ normal = midplane.n;
+ centroid = centroidLocal;
+ return area * 0.5f;
+ }
+ else
+ {
+ float area = 0.0f;
- int32_t BlastBondGeneratorImpl::createFullBondListAveraged(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry, const CollisionHull** chunkHulls,
- const bool* supportFlags, const uint32_t* meshGroups, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf, std::set<std::pair<uint32_t, uint32_t> >* pairNotToTest)
- {
+ std::vector<PxVec3> intersectionAnchors;
- std::vector<std::vector<PxVec3> > chunksPoints(meshCount);
- std::vector<PxBounds3> bounds(meshCount);
- if (!chunkHulls)
+ if (mA != nullptr && mB != nullptr) // Use triangles
+ {
+ for (uint32_t i = 0; i < mavc; ++i)
{
- for (uint32_t i = 0; i < meshCount; ++i)
+ for (uint32_t j = 0; j < mbvc; ++j)
{
- bounds[i].setEmpty();
- if (!supportFlags[i])
- {
- continue;
- }
- uint32_t count = geometryOffset[i + 1] - geometryOffset[i];
- for (uint32_t j = 0; j < count; ++j)
- {
- 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);
- bounds[i].include(geometry[geometryOffset[i] + j].a.p);
- bounds[i].include(geometry[geometryOffset[i] + j].b.p);
- bounds[i].include(geometry[geometryOffset[i] + j].c.p);
- }
+ AddTtAnchorPoints(mA + i, mB + j, intersectionAnchors);
}
}
-
- std::unique_ptr<Nv::Blast::ConvexMeshBuilderImpl> builder;
- std::vector<std::vector<std::vector<PxVec3>>> hullPoints(meshCount);
- std::vector<BondGenerationCandidate> candidates;
-
-
- for (uint32_t chunk = 0; chunk < meshCount; ++chunk)
+ }
+ else // Use hulls
+ {
+ for (uint32_t i1 = 0; i1 < hull1->polygonDataCount; ++i1)
{
- if (!supportFlags[chunk])
+ HullPolygon& poly1 = hull1->polygonData[i1];
+ for (uint32_t i2 = 0; i2 < hull2->polygonDataCount; ++i2)
{
- continue;
+ HullPolygon& poly2 = hull2->polygonData[i2];
+ AddPpAnchorPoints(reinterpret_cast<uint8_t*>(hull1->indices) + poly1.indexBase, poly1.vertexCount,
+ toPxShared(hull1->points), poly1.plane,
+ reinterpret_cast<uint8_t*>(hull2->indices) + poly2.indexBase, poly2.vertexCount,
+ toPxShared(hull2->points), poly2.plane, intersectionAnchors);
}
- PxBounds3 bnd(PxBounds3::empty());
- CollisionHull* tempHullPtr = nullptr;
- uint32_t hullCountForMesh = 0;
- const CollisionHull** beginChunkHulls = nullptr;
- if (chunkHulls)
- {
- hullCountForMesh = geometryOffset[chunk + 1] - geometryOffset[chunk];
- beginChunkHulls = chunkHulls + geometryOffset[chunk];
- }
- else
- {
- //build a convex hull and store it in the temp slot
- if (!builder)
- {
- builder = std::unique_ptr<Nv::Blast::ConvexMeshBuilderImpl>(new Nv::Blast::ConvexMeshBuilderImpl(mPxCooking, mPxInsertionCallback));
- }
-
- tempHullPtr = builder->buildCollisionGeometry(chunksPoints[chunk].size(), chunksPoints[chunk].data());
- hullCountForMesh = 1;
- beginChunkHulls = const_cast<const CollisionHull**>(&tempHullPtr);
- }
-
- hullPoints[chunk].resize(hullCountForMesh);
- for (uint32_t hull = 0; hull < hullCountForMesh; ++hull)
- {
- auto& curHull = hullPoints[chunk][hull];
- const uint32_t pointCount = beginChunkHulls[hull]->pointsCount;
- curHull.resize(pointCount);
- for (uint32_t i = 0; i < pointCount; ++i)
- {
- curHull[i] = beginChunkHulls[hull]->points[i];
- bnd.include(curHull[i]);
- }
- }
-
- if (tempHullPtr)
- {
- tempHullPtr->release();
- }
- float minSide = bnd.getDimensions().abs().minElement();
- if (minSide > 0.f)
- {
- float scaling = std::max(1.1f, conf.maxSeparation / (minSide));
- bnd.scaleFast(scaling);
- }
- candidates.push_back(BondGenerationCandidate(bnd.minimum, false, chunk, meshGroups != nullptr ? meshGroups[chunk] : 0));
- candidates.push_back(BondGenerationCandidate(bnd.maximum, true, chunk, meshGroups != nullptr ? meshGroups[chunk] : 0));
}
+ }
- std::sort(candidates.begin(), candidates.end());
+ PxVec3 lcoid(0, 0, 0);
+ for (uint32_t i = 0; i < intersectionAnchors.size(); ++i)
+ {
+ lcoid += intersectionAnchors[i];
+ }
+ lcoid *= (1.0f / intersectionAnchors.size());
+ centroid = lcoid;
- std::set<uint32_t> listOfActiveChunks;
- std::vector<std::vector<uint32_t> > possibleBondGraph(meshCount);
+ if (intersectionAnchors.size() < 2)
+ {
+ return 0;
+ }
- for (uint32_t idx = 0; idx < candidates.size(); ++idx)
- {
- if (!candidates[idx].end) // If new candidate
- {
- for (uint32_t activeChunk : listOfActiveChunks)
- {
- if (meshGroups != nullptr && (meshGroups[activeChunk] == candidates[idx].parentComponent)) continue; // Don't connect components with itself.
- possibleBondGraph[activeChunk].push_back(candidates[idx].parentChunk);
- }
- listOfActiveChunks.insert(candidates[idx].parentChunk);
- }
- else
- {
- listOfActiveChunks.erase(candidates[idx].parentChunk);
- }
- }
- TriangleProcessor trProcessor;
- std::vector<NvBlastBondDesc> mResultBondDescs;
- for (uint32_t i = 0; i < meshCount; ++i)
- {
- const uint32_t ihullCount = hullPoints[i].size();
- for (uint32_t tj = 0; tj < possibleBondGraph[i].size(); ++tj)
- {
- uint32_t j = possibleBondGraph[i][tj];
-
- auto pr = (i < j) ? std::make_pair(i, j) : std::make_pair(j, i);
-
- if (pairNotToTest != nullptr && pairNotToTest->find(pr) != pairNotToTest->end())
- {
- continue; // This chunks should not generate bonds. This is used for mixed generation with bondFrom
- }
+ PxVec3 dir1 = intersectionAnchors[0] - lcoid;
+ PxVec3 dir2(0, 0, 0);
+ float maxMagn = 0.0f;
+ float maxDist = 0.0f;
-
- const uint32_t jhullCount = hullPoints[j].size();
- for (uint32_t ihull = 0; ihull < ihullCount; ++ihull)
- {
- for (uint32_t jhull = 0; jhull < jhullCount; ++jhull)
- {
- PxVec3 normal;
- PxVec3 centroid;
-
- float area = processWithMidplanes(&trProcessor,
- geometry ? geometry + geometryOffset[i] : nullptr, geometryOffset[i + 1] - geometryOffset[i],
- geometry ? geometry + geometryOffset[j] : nullptr, geometryOffset[j + 1] - geometryOffset[j],
- geometry ? nullptr : chunkHulls[geometryOffset[i] + ihull],
- geometry ? nullptr : chunkHulls[geometryOffset[j] + jhull],
- hullPoints[i][ihull], hullPoints[j][jhull], normal, centroid, conf.maxSeparation);
-
- if (area > 0)
- {
- NvBlastBondDesc bDesc;
- bDesc.chunkIndices[0] = i;
- bDesc.chunkIndices[1] = j;
- bDesc.bond.area = area;
- bDesc.bond.centroid[0] = centroid.x;
- bDesc.bond.centroid[1] = centroid.y;
- bDesc.bond.centroid[2] = centroid.z;
-
- uint32_t maxIndex = std::max(i, j);
- if ((bounds[maxIndex].getCenter() - centroid).dot(normal) < 0)
- {
- normal = -normal;
- }
-
- bDesc.bond.normal[0] = normal.x;
- bDesc.bond.normal[1] = normal.y;
- bDesc.bond.normal[2] = normal.z;
-
- mResultBondDescs.push_back(bDesc);
- }
- }
- }
+ for (uint32_t j = 0; j < intersectionAnchors.size(); ++j)
+ {
+ float d = (intersectionAnchors[j] - lcoid).magnitude();
- }
+ PxVec3 tempNormal = (intersectionAnchors[j] - lcoid).cross(dir1);
+ maxDist = std::max(d, maxDist);
+
+ if (tempNormal.magnitude() > maxMagn)
+ {
+ dir2 = tempNormal;
}
- 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)
- {
- if (PxAbs(a.d - b.d) > EPS_PLANE) return 0;
- if (PxAbs(a.n.x - b.n.x) > EPS_PLANE) return 0;
- if (PxAbs(a.n.y - b.n.y) > EPS_PLANE) return 0;
- if (PxAbs(a.n.z - b.n.z) > EPS_PLANE) return 0;
- return 1;
- }
+ normal = dir2.getNormalized();
- 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 < meshCount; ++i)
- {
- if (!supportFlags[i])
- {
- continue;
- }
- uint32_t count = geometryOffset[i + 1] - geometryOffset[i];
- for (uint32_t j = 0; j < count; ++j)
- {
-#ifdef DEBUG_OUTPUT
- 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
+ area = (maxDist * maxDist) * 3.14f; // Compute area like circle area;
- 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));
- }
- }
+ return area;
+ }
+}
- std::sort(planeTriangleMapping.begin(), planeTriangleMapping.end(), planeComparer);
- return createFullBondListExactInternal(meshCount, geometryOffset, geometry, planeTriangleMapping, resultBondDescs);
- }
- void BlastBondGeneratorImpl::buildGeometryCache(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry)
+struct BondGenerationCandidate
+{
+ PxVec3 point;
+ bool end;
+ uint32_t parentChunk;
+ uint32_t parentComponent;
+ BondGenerationCandidate();
+ BondGenerationCandidate(const PxVec3& p, bool isEnd, uint32_t pr, uint32_t c)
+ : point(p), end(isEnd), parentChunk(pr), parentComponent(c){};
+
+ bool operator<(const BondGenerationCandidate& in) const
+ {
+ if (point.x < in.point.x)
+ return true;
+ if (point.x > in.point.x)
+ return false;
+
+ if (point.y < in.point.y)
+ return true;
+ if (point.y > in.point.y)
+ return false;
+
+ if (point.z < in.point.z)
+ return true;
+ if (point.z > in.point.z)
+ return false;
+
+ return end < in.end;
+ };
+};
+
+
+int32_t BlastBondGeneratorImpl::createFullBondListAveraged(uint32_t meshCount, const uint32_t* geometryOffset,
+ const Triangle* geometry, const CollisionHull** chunkHulls,
+ const bool* supportFlags, const uint32_t* meshGroups,
+ NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf,
+ std::set<std::pair<uint32_t, uint32_t> >* pairNotToTest)
+{
+
+ std::vector<std::vector<NvcVec3> > chunksPoints(meshCount);
+ std::vector<PxBounds3> bounds(meshCount);
+ if (!chunkHulls)
+ {
+ for (uint32_t i = 0; i < meshCount; ++i)
{
- uint32_t geometryCount = geometryOffset[meshCount];
- for (uint32_t i = 0; i < meshCount; i++)
+ bounds[i].setEmpty();
+ if (!supportFlags[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);
+ continue;
}
- mHullsPointsCache.resize(geometryCount);
- mBoundsCache.resize(geometryCount);
- mCHullCache.resize(geometryCount);
- for (uint32_t i = 0; i < mGeometryCache.size(); ++i)
+ uint32_t count = geometryOffset[i + 1] - geometryOffset[i];
+ for (uint32_t j = 0; j < count; ++j)
{
- for (uint32_t j = 0; j < mGeometryCache[i].size(); ++j)
- {
-
- PxPlane nPlane = PxPlane(mGeometryCache[i][j].a.p, mGeometryCache[i][j].b.p, mGeometryCache[i][j].c.p);
- mPlaneCache.push_back(PlaneChunkIndexer(i, j, nPlane));
- }
+ 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);
+ bounds[i].include(toPxShared(geometry[geometryOffset[i] + j].a.p));
+ bounds[i].include(toPxShared(geometry[geometryOffset[i] + j].b.p));
+ bounds[i].include(toPxShared(geometry[geometryOffset[i] + j].c.p));
}
+ }
+ }
- for (uint32_t ch = 0; ch < mGeometryCache.size(); ++ch)
- {
- std::vector<PxVec3> chunksPoints(mGeometryCache[ch].size() * 3);
-
- int32_t sp = 0;
- for (uint32_t i = 0; i < mGeometryCache[ch].size(); ++i)
- {
- chunksPoints[sp++] = mGeometryCache[ch][i].a.p;
- chunksPoints[sp++] = mGeometryCache[ch][i].b.p;
- chunksPoints[sp++] = mGeometryCache[ch][i].c.p;
- }
-
- Nv::Blast::ConvexMeshBuilderImpl builder(mPxCooking, mPxInsertionCallback);
-
- mCHullCache[ch] = builder.buildCollisionGeometry(chunksPoints.size(), chunksPoints.data());
+ std::vector<std::vector<std::vector<PxVec3> > > hullPoints(meshCount);
+ std::vector<BondGenerationCandidate> candidates;
- mHullsPointsCache[ch].resize(mCHullCache[ch]->pointsCount);
- mBoundsCache[ch].setEmpty();
- for (uint32_t i = 0; i < mCHullCache[ch]->pointsCount; ++i)
- {
- mHullsPointsCache[ch][i] = mCHullCache[ch]->points[i];
- mBoundsCache[ch].include(mHullsPointsCache[ch][i]);
- }
- }
+ for (uint32_t chunk = 0; chunk < meshCount; ++chunk)
+ {
+ if (!supportFlags[chunk])
+ {
+ continue;
+ }
+ PxBounds3 bnd(PxBounds3::empty());
+ CollisionHull* tempHullPtr = nullptr;
+ uint32_t hullCountForMesh = 0;
+ const CollisionHull** beginChunkHulls = nullptr;
+ if (chunkHulls)
+ {
+ hullCountForMesh = geometryOffset[chunk + 1] - geometryOffset[chunk];
+ beginChunkHulls = chunkHulls + geometryOffset[chunk];
+ }
+ else
+ {
+ // build a convex hull and store it in the temp slot
+ tempHullPtr =
+ mConvexMeshBuilder->buildCollisionGeometry(chunksPoints[chunk].size(), chunksPoints[chunk].data());
+ hullCountForMesh = 1;
+ beginChunkHulls = const_cast<const CollisionHull**>(&tempHullPtr);
}
- void BlastBondGeneratorImpl::resetGeometryCache()
- {
- mGeometryCache.clear();
- mPlaneCache.clear();
- mHullsPointsCache.clear();
- for (auto h : mCHullCache)
+ hullPoints[chunk].resize(hullCountForMesh);
+ for (uint32_t hull = 0; hull < hullCountForMesh; ++hull)
+ {
+ auto& curHull = hullPoints[chunk][hull];
+ const uint32_t pointCount = beginChunkHulls[hull]->pointsCount;
+ curHull.resize(pointCount);
+ for (uint32_t i = 0; i < pointCount; ++i)
{
- h->release();
+ curHull[i] = toPxShared(beginChunkHulls[hull]->points[i]);
+ bnd.include(curHull[i]);
}
- mCHullCache.clear();
- mBoundsCache.clear();
}
- int32_t BlastBondGeneratorImpl::createFullBondListExactInternal(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry,
- std::vector<PlaneChunkIndexer>& planeTriangleMapping, NvBlastBondDesc*& resultBondDescs)
+ if (tempHullPtr)
+ {
+ mConvexMeshBuilder->releaseCollisionHull(tempHullPtr);
+ }
+ float minSide = bnd.getDimensions().abs().minElement();
+ if (minSide > 0.f)
{
- NV_UNUSED(meshCount);
+ float scaling = std::max(1.1f, conf.maxSeparation / (minSide));
+ bnd.scaleFast(scaling);
+ }
+ candidates.push_back(
+ BondGenerationCandidate(bnd.minimum, false, chunk, meshGroups != nullptr ? meshGroups[chunk] : 0));
+ candidates.push_back(
+ BondGenerationCandidate(bnd.maximum, true, chunk, meshGroups != nullptr ? meshGroups[chunk] : 0));
+ }
- std::map<std::pair<int32_t, int32_t>, std::pair<NvBlastBondDesc, int32_t> > bonds;
+ std::sort(candidates.begin(), candidates.end());
- TriangleProcessor trPrc;
- std::vector<PxVec3> intersectionBufferLocal;
+ std::set<uint32_t> listOfActiveChunks;
+ std::vector<std::vector<uint32_t> > possibleBondGraph(meshCount);
- NvBlastBondDesc cleanBond;
- memset(&cleanBond, 0, sizeof(NvBlastBondDesc));
- for (uint32_t tIndex = 0; tIndex < planeTriangleMapping.size(); ++tIndex)
+ for (uint32_t idx = 0; idx < candidates.size(); ++idx)
+ {
+ if (!candidates[idx].end) // If new candidate
+ {
+ for (uint32_t activeChunk : listOfActiveChunks)
{
-
- PlaneChunkIndexer opp = planeTriangleMapping[tIndex];
-
- opp.plane.d *= -1;
- opp.plane.n *= -1;
-
- uint32_t startIndex = (uint32_t)(std::lower_bound(planeTriangleMapping.begin(), planeTriangleMapping.end(), opp, planeComparer) - planeTriangleMapping.begin());
- uint32_t endIndex = (uint32_t)(std::upper_bound(planeTriangleMapping.begin(), planeTriangleMapping.end(), opp, planeComparer) - planeTriangleMapping.begin());
- // uint32_t startIndex = 0;
- // uint32_t endIndex = (uint32_t)planeTriangleMapping.size();
-
- PlaneChunkIndexer& mappedTr = planeTriangleMapping[tIndex];
- 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);
- trp.points[0] -= trCentroid;
- trp.points[1] -= trCentroid;
- trp.points[2] -= trCentroid;
- ProjectionDirections pDir = getProjectionDirection(pln.n);
- TrPrcTriangle2d trp2d;
- trp2d.points[0] = getProjectedPointWithWinding(trp.points[0], pDir);
- trp2d.points[1] = getProjectedPointWithWinding(trp.points[1], pDir);
- trp2d.points[2] = getProjectedPointWithWinding(trp.points[2], pDir);
-
- for (uint32_t i = startIndex; i <= endIndex && i < planeTriangleMapping.size(); ++i)
- {
- PlaneChunkIndexer& mappedTr2 = planeTriangleMapping[i];
- if (mappedTr2.trId == opp.chunkId)
- {
- continue;
- }
+ if (meshGroups != nullptr && (meshGroups[activeChunk] == candidates[idx].parentComponent))
+ continue; // Don't connect components with itself.
+ possibleBondGraph[activeChunk].push_back(candidates[idx].parentChunk);
+ }
+ listOfActiveChunks.insert(candidates[idx].parentChunk);
+ }
+ else
+ {
+ listOfActiveChunks.erase(candidates[idx].parentChunk);
+ }
+ }
- if (!isSamePlane(opp.plane, mappedTr2.plane))
- {
- continue;
- }
-
- if (mappedTr.chunkId == mappedTr2.chunkId)
- {
- continue;
- }
- std::pair<int32_t, int32_t> bondEndPoints = std::make_pair(mappedTr.chunkId, mappedTr2.chunkId);
- if (bondEndPoints.second < bondEndPoints.first) continue;
- std::pair<int32_t, int32_t> bondEndPointsSwapped = std::make_pair(mappedTr2.chunkId, mappedTr.chunkId);
- if (bonds.find(bondEndPoints) == bonds.end() && bonds.find(bondEndPointsSwapped) != bonds.end())
- {
- continue; // We do not need account interface surface twice
- }
- if (bonds.find(bondEndPoints) == bonds.end())
- {
- bonds[bondEndPoints].second = 0;
- bonds[bondEndPoints].first = cleanBond;
- bonds[bondEndPoints].first.chunkIndices[0] = bondEndPoints.first;
- bonds[bondEndPoints].first.chunkIndices[1] = bondEndPoints.second;
- bonds[bondEndPoints].first.bond.normal[0] = pln.n[0];
- bonds[bondEndPoints].first.bond.normal[1] = pln.n[1];
- bonds[bondEndPoints].first.bond.normal[2] = pln.n[2];
- }
- const Triangle& trl2 = geometry[geometryOffset[mappedTr2.chunkId] + mappedTr2.trId];
+ TriangleProcessor trProcessor;
+ std::vector<NvBlastBondDesc> mResultBondDescs;
+ for (uint32_t i = 0; i < meshCount; ++i)
+ {
+ const uint32_t ihullCount = hullPoints[i].size();
+ for (uint32_t tj = 0; tj < possibleBondGraph[i].size(); ++tj)
+ {
+ uint32_t j = possibleBondGraph[i][tj];
+
+ auto pr = (i < j) ? std::make_pair(i, j) : std::make_pair(j, i);
+
+ if (pairNotToTest != nullptr && pairNotToTest->find(pr) != pairNotToTest->end())
+ {
+ continue; // This chunks should not generate bonds. This is used for mixed generation with bondFrom
+ }
- TrPrcTriangle trp2(trl2.a.p, trl2.b.p, trl2.c.p);
- intersectionBufferLocal.clear();
- intersectionBufferLocal.reserve(32);
- trPrc.getTriangleIntersection(trp, trp2d, trp2, trCentroid, intersectionBufferLocal, pln.n);
- PxVec3 centroidPoint(0, 0, 0);
- int32_t collectedVerticesCount = 0;
- float area = 0;
- if (intersectionBufferLocal.size() >= 3)
+ const uint32_t jhullCount = hullPoints[j].size();
+ for (uint32_t ihull = 0; ihull < ihullCount; ++ihull)
+ {
+ for (uint32_t jhull = 0; jhull < jhullCount; ++jhull)
+ {
+ PxVec3 normal;
+ PxVec3 centroid;
+
+ float area = processWithMidplanes(
+ &trProcessor, geometry ? geometry + geometryOffset[i] : nullptr,
+ geometryOffset[i + 1] - geometryOffset[i], geometry ? geometry + geometryOffset[j] : nullptr,
+ geometryOffset[j + 1] - geometryOffset[j],
+ geometry ? nullptr : chunkHulls[geometryOffset[i] + ihull],
+ geometry ? nullptr : chunkHulls[geometryOffset[j] + jhull], hullPoints[i][ihull],
+ hullPoints[j][jhull], normal, centroid, conf.maxSeparation);
+
+ if (area > 0)
{
-#ifdef DEBUG_OUTPUT
- for (uint32_t p = 1; p < intersectionBufferLocal.size() - 1; ++p)
+ NvBlastBondDesc bDesc;
+ bDesc.chunkIndices[0] = i;
+ bDesc.chunkIndices[1] = j;
+ bDesc.bond.area = area;
+ bDesc.bond.centroid[0] = centroid.x;
+ bDesc.bond.centroid[1] = centroid.y;
+ bDesc.bond.centroid[2] = centroid.z;
+
+ uint32_t maxIndex = std::max(i, j);
+ if ((bounds[maxIndex].getCenter() - centroid).dot(normal) < 0)
{
- intersectionBuffer.push_back(intersectionBufferLocal[0]);
- intersectionBuffer.push_back(intersectionBufferLocal[p]);
- intersectionBuffer.push_back(intersectionBufferLocal[p + 1]);
+ normal = -normal;
}
-#endif
- centroidPoint = intersectionBufferLocal[0] + intersectionBufferLocal.back();
- collectedVerticesCount = 2;
- for (uint32_t j = 1; j < intersectionBufferLocal.size() - 1; ++j)
- {
- ++collectedVerticesCount;
- centroidPoint += intersectionBufferLocal[j];
- area += (intersectionBufferLocal[j + 1] - intersectionBufferLocal[0]).cross(intersectionBufferLocal[j] - intersectionBufferLocal[0]).magnitude();
- }
- }
- if (area > 0.00001f)
- {
- bonds[bondEndPoints].second += collectedVerticesCount;
+ bDesc.bond.normal[0] = normal.x;
+ bDesc.bond.normal[1] = normal.y;
+ bDesc.bond.normal[2] = normal.z;
- bonds[bondEndPoints].first.bond.area += area * 0.5f;
- bonds[bondEndPoints].first.bond.centroid[0] += (centroidPoint.x);
- bonds[bondEndPoints].first.bond.centroid[1] += (centroidPoint.y);
- bonds[bondEndPoints].first.bond.centroid[2] += (centroidPoint.z);
+ mResultBondDescs.push_back(bDesc);
}
}
}
+ }
+ }
+ resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size());
+ memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc) * mResultBondDescs.size());
+ return mResultBondDescs.size();
+}
- std::vector<NvBlastBondDesc> mResultBondDescs;
- for (auto it : bonds)
- {
- if (it.second.first.bond.area > 0)
- {
- float mlt = 1.0f / (it.second.second);
- it.second.first.bond.centroid[0] *= mlt;
- it.second.first.bond.centroid[1] *= mlt;
- it.second.first.bond.centroid[2] *= mlt;
-
- mResultBondDescs.push_back(it.second.first);
- }
+uint32_t isSamePlane(NvcPlane& a, NvcPlane& b)
+{
+ if (PxAbs(a.d - b.d) > EPS_PLANE)
+ return 0;
+ if (PxAbs(a.n.x - b.n.x) > EPS_PLANE)
+ return 0;
+ if (PxAbs(a.n.y - b.n.y) > EPS_PLANE)
+ return 0;
+ if (PxAbs(a.n.z - b.n.z) > EPS_PLANE)
+ return 0;
+ return 1;
+}
- }
+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 < meshCount; ++i)
+ {
+ if (!supportFlags[i])
+ {
+ continue;
+ }
+ uint32_t count = geometryOffset[i + 1] - geometryOffset[i];
+ for (uint32_t j = 0; j < count; ++j)
+ {
#ifdef DEBUG_OUTPUT
- saveGeometryToObj(meshBuffer, "Mesh.obj");
- saveGeometryToObj(intersectionBuffer, "inter.obj");
+ 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
- resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size());
- memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc)*mResultBondDescs.size());
- return mResultBondDescs.size();
+
+ NvcPlane nPlane = fromPxShared(physx::PxPlane(toPxShared(geometry[geometryOffset[i] + j].a.p),
+ toPxShared(geometry[geometryOffset[i] + j].b.p),
+ toPxShared(geometry[geometryOffset[i] + j].c.p)));
+ planeTriangleMapping.push_back({ (int32_t)i, (int32_t)j, nPlane });
}
+ }
- 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)
+ std::sort(planeTriangleMapping.begin(), planeTriangleMapping.end(), planeComparer);
+ return createFullBondListExactInternal(meshCount, geometryOffset, geometry, planeTriangleMapping, resultBondDescs);
+}
+
+void BlastBondGeneratorImpl::buildGeometryCache(uint32_t meshCount, const uint32_t* geometryOffset,
+ const Triangle* geometry)
+{
+ 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)
{
- TriangleProcessor trProcessor;
- Separation 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);
+ NvcPlane nPlane =
+ fromPxShared(physx::PxPlane(toPxShared(mGeometryCache[i][j].a.p), toPxShared(mGeometryCache[i][j].b.p),
+ toPxShared(mGeometryCache[i][j].c.p)));
+ mPlaneCache.push_back({ (int32_t)i, (int32_t)j, nPlane });
+ }
+ }
- if (std::isnan(separation.plane.d))
- {
- 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;
- }
- }
+ for (uint32_t ch = 0; ch < mGeometryCache.size(); ++ch)
+ {
+ std::vector<NvcVec3> chunksPoints(mGeometryCache[ch].size() * 3);
- PxPlane pl = separation.plane;
- std::vector<PxVec3> ifsPoints[2];
+ int32_t sp = 0;
+ for (uint32_t i = 0; i < mGeometryCache[ch].size(); ++i)
+ {
+ chunksPoints[sp++] = mGeometryCache[ch][i].a.p;
+ chunksPoints[sp++] = mGeometryCache[ch][i].b.p;
+ chunksPoints[sp++] = mGeometryCache[ch][i].c.p;
+ }
- float dst[2][2];
+ mCHullCache[ch] = mConvexMeshBuilder->buildCollisionGeometry(chunksPoints.size(), chunksPoints.data());
- dst[0][0] = 0;
- dst[0][1] = MAXIMUM_EXTENT;
- for (uint32_t p = 0; p < cHull0.pointsCount; ++p)
+ mHullsPointsCache[ch].resize(mCHullCache[ch]->pointsCount);
+
+ mBoundsCache[ch].setEmpty();
+ for (uint32_t i = 0; i < mCHullCache[ch]->pointsCount; ++i)
+ {
+ mHullsPointsCache[ch][i] = toPxShared(mCHullCache[ch]->points[i]);
+ mBoundsCache[ch].include(mHullsPointsCache[ch][i]);
+ }
+ }
+}
+
+void BlastBondGeneratorImpl::resetGeometryCache()
+{
+ mGeometryCache.clear();
+ mPlaneCache.clear();
+ mHullsPointsCache.clear();
+ for (auto h : mCHullCache)
+ {
+ mConvexMeshBuilder->releaseCollisionHull(h);
+ }
+ mCHullCache.clear();
+ mBoundsCache.clear();
+}
+
+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;
+ std::vector<PxVec3> intersectionBufferLocal;
+
+ NvBlastBondDesc cleanBond;
+ memset(&cleanBond, 0, sizeof(NvBlastBondDesc));
+ for (uint32_t tIndex = 0; tIndex < planeTriangleMapping.size(); ++tIndex)
+ {
+
+ PlaneChunkIndexer opp = planeTriangleMapping[tIndex];
+
+ opp.plane.d *= -1;
+ opp.plane.n = opp.plane.n * - 1;
+
+ uint32_t startIndex =
+ (uint32_t)(std::lower_bound(planeTriangleMapping.begin(), planeTriangleMapping.end(), opp, planeComparer) -
+ planeTriangleMapping.begin());
+ uint32_t endIndex =
+ (uint32_t)(std::upper_bound(planeTriangleMapping.begin(), planeTriangleMapping.end(), opp, planeComparer) -
+ planeTriangleMapping.begin());
+ // uint32_t startIndex = 0;
+ // uint32_t endIndex = (uint32_t)planeTriangleMapping.size();
+
+ PlaneChunkIndexer& mappedTr = planeTriangleMapping[tIndex];
+ const Triangle& trl = geometry[geometryOffset[mappedTr.chunkId] + mappedTr.trId];
+ PxPlane pln = toPxShared(mappedTr.plane);
+ TrPrcTriangle trp(toPxShared(trl.a.p), toPxShared(trl.b.p), toPxShared(trl.c.p));
+ PxVec3 trCentroid = toPxShared(trl.a.p + trl.b.p + trl.c.p) * (1.0f / 3.0f);
+ trp.points[0] -= trCentroid;
+ trp.points[1] -= trCentroid;
+ trp.points[2] -= trCentroid;
+ ProjectionDirections pDir = getProjectionDirection(pln.n);
+ TrPrcTriangle2d trp2d;
+ trp2d.points[0] = getProjectedPointWithWinding(trp.points[0], pDir);
+ trp2d.points[1] = getProjectedPointWithWinding(trp.points[1], pDir);
+ trp2d.points[2] = getProjectedPointWithWinding(trp.points[2], pDir);
+
+ for (uint32_t i = startIndex; i <= endIndex && i < planeTriangleMapping.size(); ++i)
+ {
+ PlaneChunkIndexer& mappedTr2 = planeTriangleMapping[i];
+ if (mappedTr2.trId == opp.chunkId)
{
- float d = pl.distance(cHull0.points[p]);
- if (PxAbs(d) > PxAbs(dst[0][0]))
- {
- dst[0][0] = d;
- }
- if (PxAbs(d) < PxAbs(dst[0][1]))
- {
- dst[0][1] = d;
- }
+ continue;
}
- dst[1][0] = 0;
- dst[1][1] = MAXIMUM_EXTENT;
- for (uint32_t p = 0; p < cHull1.pointsCount; ++p)
+ if (!isSamePlane(opp.plane, mappedTr2.plane))
{
- float d = pl.distance(cHull0.points[p]);
- if (PxAbs(d) > PxAbs(dst[1][0]))
- {
- dst[1][0] = d;
- }
- if (PxAbs(d) < PxAbs(dst[1][1]))
- {
- dst[1][1] = d;
- }
+ continue;
}
-
- 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.polygonDataCount; ++i)
+ if (mappedTr.chunkId == mappedTr2.chunkId)
{
- auto& pd = cHull0.polygonData[i];
- PxVec3 result;
- for (uint32_t j = 0; j < pd.mNbVerts; ++j)
- {
- 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))
- {
- ifsPoints[0].push_back(result);
- }
- }
+ continue;
}
-
- for (uint32_t i = 0; i < cHull1.polygonDataCount; ++i)
+ std::pair<int32_t, int32_t> bondEndPoints = std::make_pair(mappedTr.chunkId, mappedTr2.chunkId);
+ if (bondEndPoints.second < bondEndPoints.first)
+ continue;
+ std::pair<int32_t, int32_t> bondEndPointsSwapped = std::make_pair(mappedTr2.chunkId, mappedTr.chunkId);
+ if (bonds.find(bondEndPoints) == bonds.end() && bonds.find(bondEndPointsSwapped) != bonds.end())
{
- auto& pd = cHull1.polygonData[i];
- PxVec3 result;
- for (uint32_t j = 0; j < pd.mNbVerts; ++j)
- {
- 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))
- {
- ifsPoints[1].push_back(result);
- }
- }
+ continue; // We do not need account interface surface twice
}
+ if (bonds.find(bondEndPoints) == bonds.end())
+ {
+ bonds[bondEndPoints].second = 0;
+ bonds[bondEndPoints].first = cleanBond;
+ bonds[bondEndPoints].first.chunkIndices[0] = bondEndPoints.first;
+ bonds[bondEndPoints].first.chunkIndices[1] = bondEndPoints.second;
+ bonds[bondEndPoints].first.bond.normal[0] = pln.n[0];
+ bonds[bondEndPoints].first.bond.normal[1] = pln.n[1];
+ bonds[bondEndPoints].first.bond.normal[2] = pln.n[2];
+ }
+ const Triangle& trl2 = geometry[geometryOffset[mappedTr2.chunkId] + mappedTr2.trId];
+ TrPrcTriangle trp2(toPxShared(trl2.a.p), toPxShared(trl2.b.p), toPxShared(trl2.c.p));
- std::vector<PxVec3> convexes[2];
-
- trProcessor.buildConvexHull(ifsPoints[0], convexes[0], pl.n);
- trProcessor.buildConvexHull(ifsPoints[1], convexes[1], pl.n);
-
- float areas[2] = { 0, 0 };
- PxVec3 centroids[2] = { PxVec3(0, 0, 0), PxVec3(0, 0, 0) };
-
- for (uint32_t cv = 0; cv < 2; ++cv)
+ intersectionBufferLocal.clear();
+ intersectionBufferLocal.reserve(32);
+ trPrc.getTriangleIntersection(trp, trp2d, trp2, trCentroid, intersectionBufferLocal, pln.n);
+ PxVec3 centroidPoint(0, 0, 0);
+ int32_t collectedVerticesCount = 0;
+ float area = 0;
+ if (intersectionBufferLocal.size() >= 3)
{
- if (convexes[cv].size() == 0)
+#ifdef DEBUG_OUTPUT
+ for (uint32_t p = 1; p < intersectionBufferLocal.size() - 1; ++p)
{
- continue;
+ intersectionBuffer.push_back(intersectionBufferLocal[0]);
+ intersectionBuffer.push_back(intersectionBufferLocal[p]);
+ intersectionBuffer.push_back(intersectionBufferLocal[p + 1]);
}
- centroids[cv] = convexes[cv][0] + convexes[cv].back();
- for (uint32_t i = 1; i < convexes[cv].size() - 1; ++i)
- {
- centroids[cv] += convexes[cv][i];
- areas[cv] += (convexes[cv][i + 1] - convexes[cv][0]).cross(convexes[cv][i] - convexes[cv][0]).magnitude();
-#ifdef DEBUG_OUTPUT
- intersectionBuffer.push_back(convexes[cv][0]);
- intersectionBuffer.push_back(convexes[cv][i]);
- intersectionBuffer.push_back(convexes[cv][i + 1]);
#endif
+ centroidPoint = intersectionBufferLocal[0] + intersectionBufferLocal.back();
+ collectedVerticesCount = 2;
+ for (uint32_t j = 1; j < intersectionBufferLocal.size() - 1; ++j)
+ {
+ ++collectedVerticesCount;
+ centroidPoint += intersectionBufferLocal[j];
+ area += (intersectionBufferLocal[j + 1] - intersectionBufferLocal[0])
+ .cross(intersectionBufferLocal[j] - intersectionBufferLocal[0])
+ .magnitude();
}
- centroids[cv] *= (1.0f / convexes[cv].size());
- areas[cv] = PxAbs(areas[cv]);
}
+ if (area > 0.00001f)
+ {
+ bonds[bondEndPoints].second += collectedVerticesCount;
- resultBond.area = (areas[0] + areas[1]) * 0.5f;
- resultBond.centroid[0] = (centroids[0][0] + centroids[1][0]) * 0.5f;
- resultBond.centroid[1] = (centroids[0][1] + centroids[1][1]) * 0.5f;
- resultBond.centroid[2] = (centroids[0][2] + centroids[1][2]) * 0.5f;
- resultBond.normal[0] = pl.n[0];
- resultBond.normal[1] = pl.n[1];
- resultBond.normal[2] = pl.n[2];
+ bonds[bondEndPoints].first.bond.area += area * 0.5f;
+ bonds[bondEndPoints].first.bond.centroid[0] += (centroidPoint.x);
+ bonds[bondEndPoints].first.bond.centroid[1] += (centroidPoint.y);
+ bonds[bondEndPoints].first.bond.centroid[2] += (centroidPoint.z);
+ }
+ }
+ }
+ std::vector<NvBlastBondDesc> mResultBondDescs;
+ for (auto it : bonds)
+ {
+ if (it.second.first.bond.area > 0)
+ {
+ float mlt = 1.0f / (it.second.second);
+ it.second.first.bond.centroid[0] *= mlt;
+ it.second.first.bond.centroid[1] *= mlt;
+ it.second.first.bond.centroid[2] *= mlt;
+
+ mResultBondDescs.push_back(it.second.first);
+ }
+ }
#ifdef DEBUG_OUTPUT
- saveGeometryToObj(meshBuffer, "ArbitMeshes.obj");
- saveGeometryToObj(intersectionBuffer, "inter.obj");
+ saveGeometryToObj(meshBuffer, "Mesh.obj");
+ saveGeometryToObj(intersectionBuffer, "inter.obj");
#endif
+ resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size());
+ memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc) * mResultBondDescs.size());
+ return mResultBondDescs.size();
+}
+
+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.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.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;
+ }
+ }
+ PxPlane pl = separation.plane;
+ std::vector<PxVec3> ifsPoints[2];
- return 0;
+ float dst[2][2];
+
+ dst[0][0] = 0;
+ dst[0][1] = MAXIMUM_EXTENT;
+ for (uint32_t p = 0; p < cHull0.pointsCount; ++p)
+ {
+ float d = pl.distance(toPxShared(cHull0.points[p]));
+ if (PxAbs(d) > PxAbs(dst[0][0]))
+ {
+ dst[0][0] = d;
}
-
- int32_t BlastBondGeneratorImpl::buildDescFromInternalFracture(FractureTool* tool, const bool* chunkIsSupport,
- NvBlastBondDesc*& resultBondDescs, NvBlastChunkDesc*& resultChunkDescriptors)
+ if (PxAbs(d) < PxAbs(dst[0][1]))
{
- uint32_t chunkCount = tool->getChunkCount();
- std::vector<uint32_t> trianglesCount(chunkCount);
- std::vector<std::shared_ptr<Triangle>> trianglesBuffer;
+ dst[0][1] = d;
+ }
+ }
- for (uint32_t i = 0; i < chunkCount; ++i)
- {
- Triangle* t;
- trianglesCount[i] = tool->getBaseMesh(i, t);
- trianglesBuffer.push_back(std::shared_ptr<Triangle>(t, [](Triangle* t) {
- delete[] t;
- }));
- }
+ dst[1][0] = 0;
+ dst[1][1] = MAXIMUM_EXTENT;
+ for (uint32_t p = 0; p < cHull1.pointsCount; ++p)
+ {
+ float d = pl.distance(toPxShared(cHull0.points[p]));
+ if (PxAbs(d) > PxAbs(dst[1][0]))
+ {
+ dst[1][0] = d;
+ }
+ if (PxAbs(d) < PxAbs(dst[1][1]))
+ {
+ dst[1][1] = d;
+ }
+ }
- if (chunkCount == 0)
- {
- return 0;
- }
- resultChunkDescriptors = SAFE_ARRAY_NEW(NvBlastChunkDesc, trianglesBuffer.size());
- std::vector<Bond> bondDescriptors;
- resultChunkDescriptors[0].parentChunkIndex = UINT32_MAX;
- resultChunkDescriptors[0].userData = 0;
- resultChunkDescriptors[0].flags = NvBlastChunkDesc::NoFlags;
+ 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.polygonDataCount; ++i)
+ {
+ auto& pd = cHull0.polygonData[i];
+ PxVec3 result;
+ for (uint32_t j = 0; j < pd.vertexCount; ++j)
+ {
+ uint32_t nxj = (j + 1) % pd.vertexCount;
+ const uint32_t* ind = cHull0.indices;
+ PxVec3 a = hull0[ind[j + pd.indexBase]] - pl.n * cvOffset[0];
+ PxVec3 b = hull0[ind[nxj + pd.indexBase]] - pl.n * cvOffset[0];
+
+ if (getPlaneSegmentIntersection(pl, a, b, result))
{
- PxVec3 chunkCentroid(0, 0, 0);
- for (uint32_t tr = 0; tr < trianglesCount[0]; ++tr)
- {
- chunkCentroid += trianglesBuffer[0].get()[tr].a.p;
- chunkCentroid += trianglesBuffer[0].get()[tr].b.p;
- chunkCentroid += trianglesBuffer[0].get()[tr].c.p;
- }
- chunkCentroid *= (1.0f / (3 * trianglesCount[0]));
- resultChunkDescriptors[0].centroid[0] = chunkCentroid[0];
- resultChunkDescriptors[0].centroid[1] = chunkCentroid[1];
- resultChunkDescriptors[0].centroid[2] = chunkCentroid[2];
+ ifsPoints[0].push_back(result);
}
+ }
+ }
-
- bool hasCreatedByIslands = false;
+ for (uint32_t i = 0; i < cHull1.polygonDataCount; ++i)
+ {
+ auto& pd = cHull1.polygonData[i];
+ PxVec3 result;
+ for (uint32_t j = 0; j < pd.vertexCount; ++j)
+ {
+ uint32_t nxj = (j + 1) % pd.vertexCount;
+ const uint32_t* ind = cHull1.indices;
+ PxVec3 a = hull1[ind[j + pd.indexBase]] - pl.n * cvOffset[1];
+ PxVec3 b = hull1[ind[nxj + pd.indexBase]] - pl.n * cvOffset[1];
- for (uint32_t i = 1; i < chunkCount; ++i)
+ if (getPlaneSegmentIntersection(pl, a, b, result))
{
- NvBlastChunkDesc& desc = resultChunkDescriptors[i];
- desc.userData = i;
- desc.parentChunkIndex = tool->getChunkIndex(tool->getChunkInfo(i).parent);
- desc.flags = NvBlastChunkDesc::NoFlags;
- hasCreatedByIslands |= (tool->getChunkInfo(i).flags & ChunkInfo::CREATED_BY_ISLAND_DETECTOR);
- if (chunkIsSupport[i])
- {
- desc.flags = NvBlastChunkDesc::SupportFlag;
- }
- PxVec3 chunkCentroid(0, 0, 0);
- for (uint32_t tr = 0; tr < trianglesCount[i]; ++tr)
- {
- auto& trRef = trianglesBuffer[i].get()[tr];
- chunkCentroid += trRef.a.p;
- chunkCentroid += trRef.b.p;
- chunkCentroid += trRef.c.p;
-
- int32_t id = trRef.userData;
- if (id == 0)
- continue;
- bondDescriptors.push_back(Bond());
- Bond& bond = bondDescriptors.back();
- bond.m_chunkId = i;
- bond.m_planeIndex = id;
- bond.triangleIndex = tr;
- }
- chunkCentroid *= (1.0f / (3 * trianglesCount[i]));
- desc.centroid[0] = chunkCentroid[0];
- desc.centroid[1] = chunkCentroid[1];
- desc.centroid[2] = chunkCentroid[2];
+ ifsPoints[1].push_back(result);
}
- std::sort(bondDescriptors.begin(), bondDescriptors.end());
+ }
+ }
- std::vector<NvBlastBondDesc> mResultBondDescs;
+ std::vector<PxVec3> convexes[2];
- if (!bondDescriptors.empty())
- {
+ trProcessor.buildConvexHull(ifsPoints[0], convexes[0], pl.n);
+ trProcessor.buildConvexHull(ifsPoints[1], convexes[1], pl.n);
- int32_t chunkId, planeId;
- chunkId = bondDescriptors[0].m_chunkId;
- planeId = bondDescriptors[0].m_planeIndex;
- std::vector<BondInfo> forwardChunks;
- std::vector<BondInfo> backwardChunks;
-
- float area = 0;
- PxVec3 normal(0, 0, 0);
- PxVec3 centroid(0, 0, 0);
- int32_t collected = 0;
- PxBounds3 bb = PxBounds3::empty();
-
- chunkId = -1;
- planeId = bondDescriptors[0].m_planeIndex;
- 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)))
- {
- if (chunkId != -1)
- {
- if (bondDescriptors[i - 1].m_planeIndex > 0) {
- forwardChunks.push_back(BondInfo());
- forwardChunks.back().area = area;
- forwardChunks.back().normal = normal;
- forwardChunks.back().centroid = centroid * (1.0f / 3.0f / collected);
- forwardChunks.back().m_chunkId = chunkId;
- forwardChunks.back().m_bb = bb;
-
- }
- else
- {
- backwardChunks.push_back(BondInfo());
- backwardChunks.back().area = area;
- backwardChunks.back().normal = normal;
- backwardChunks.back().centroid = centroid * (1.0f / 3.0f / collected);
- backwardChunks.back().m_chunkId = chunkId;
- backwardChunks.back().m_bb = bb;
- }
- }
- bb.setEmpty();
- collected = 0;
- area = 0;
- normal = PxVec3(0, 0, 0);
- centroid = PxVec3(0, 0, 0);
- if (i != bondDescriptors.size())
- chunkId = bondDescriptors[i].m_chunkId;
- }
- if (i == bondDescriptors.size() || abs(planeId) != abs(bondDescriptors[i].m_planeIndex))
- {
- for (uint32_t fchunk = 0; fchunk < forwardChunks.size(); ++fchunk)
- {
- if (chunkIsSupport[forwardChunks[fchunk].m_chunkId] == false)
- {
- continue;
- }
- for (uint32_t bchunk = 0; bchunk < backwardChunks.size(); ++bchunk)
- {
- if (weakBoundingBoxIntersection(forwardChunks[fchunk].m_bb, backwardChunks[bchunk].m_bb) == 0)
- {
- continue;
- }
- if (chunkIsSupport[backwardChunks[bchunk].m_chunkId] == false)
- {
- continue;
- }
- mResultBondDescs.push_back(NvBlastBondDesc());
- mResultBondDescs.back().bond.area = std::min(forwardChunks[fchunk].area, backwardChunks[bchunk].area);
- mResultBondDescs.back().bond.normal[0] = forwardChunks[fchunk].normal.x;
- mResultBondDescs.back().bond.normal[1] = forwardChunks[fchunk].normal.y;
- mResultBondDescs.back().bond.normal[2] = forwardChunks[fchunk].normal.z;
-
- mResultBondDescs.back().bond.centroid[0] = (forwardChunks[fchunk].centroid.x + backwardChunks[bchunk].centroid.x) * 0.5;
- mResultBondDescs.back().bond.centroid[1] = (forwardChunks[fchunk].centroid.y + backwardChunks[bchunk].centroid.y) * 0.5;
- mResultBondDescs.back().bond.centroid[2] = (forwardChunks[fchunk].centroid.z + backwardChunks[bchunk].centroid.z) * 0.5;
-
-
- mResultBondDescs.back().chunkIndices[0] = forwardChunks[fchunk].m_chunkId;
- mResultBondDescs.back().chunkIndices[1] = backwardChunks[bchunk].m_chunkId;
- }
- }
- forwardChunks.clear();
- backwardChunks.clear();
- if (i != bondDescriptors.size())
- {
- planeId = bondDescriptors[i].m_planeIndex;
- }
- else
- {
- break;
- }
- }
+ float areas[2] = { 0, 0 };
+ PxVec3 centroids[2] = { PxVec3(0, 0, 0), PxVec3(0, 0, 0) };
- collected++;
- auto& trRef = trianglesBuffer[chunkId].get()[bondDescriptors[i].triangleIndex];
- PxVec3 n = trRef.getNormal();
- area += n.magnitude();
- normal = n.getNormalized();
- centroid += trRef.a.p;
- centroid += trRef.b.p;
- centroid += trRef.c.p;
-
- bb.include(trRef.a.p);
- bb.include(trRef.b.p);
- bb.include(trRef.c.p);
- }
- }
+ for (uint32_t cv = 0; cv < 2; ++cv)
+ {
+ if (convexes[cv].size() == 0)
+ {
+ continue;
+ }
+ centroids[cv] = convexes[cv][0] + convexes[cv].back();
+ for (uint32_t i = 1; i < convexes[cv].size() - 1; ++i)
+ {
+ centroids[cv] += convexes[cv][i];
+ areas[cv] += (convexes[cv][i + 1] - convexes[cv][0]).cross(convexes[cv][i] - convexes[cv][0]).magnitude();
+#ifdef DEBUG_OUTPUT
+ intersectionBuffer.push_back(convexes[cv][0]);
+ intersectionBuffer.push_back(convexes[cv][i]);
+ intersectionBuffer.push_back(convexes[cv][i + 1]);
+#endif
+ }
+ centroids[cv] *= (1.0f / convexes[cv].size());
+ areas[cv] = PxAbs(areas[cv]);
+ }
- if (hasCreatedByIslands)
- {
- std::vector<Triangle> chunkTriangles;
- std::vector<uint32_t> chunkTrianglesOffsets;
-
- std::set<std::pair<uint32_t, uint32_t> > pairsAlreadyCreated;
+ resultBond.area = (areas[0] + areas[1]) * 0.5f;
+ resultBond.centroid[0] = (centroids[0][0] + centroids[1][0]) * 0.5f;
+ resultBond.centroid[1] = (centroids[0][1] + centroids[1][1]) * 0.5f;
+ resultBond.centroid[2] = (centroids[0][2] + centroids[1][2]) * 0.5f;
+ resultBond.normal[0] = pl.n[0];
+ resultBond.normal[1] = pl.n[1];
+ resultBond.normal[2] = pl.n[2];
- for (uint32_t i = 0; i < mResultBondDescs.size(); ++i)
- {
- auto pr = (mResultBondDescs[i].chunkIndices[0] < mResultBondDescs[i].chunkIndices[1]) ?
- std::make_pair(mResultBondDescs[i].chunkIndices[0], mResultBondDescs[i].chunkIndices[1]) :
- std::make_pair(mResultBondDescs[i].chunkIndices[1], mResultBondDescs[i].chunkIndices[0]);
+#ifdef DEBUG_OUTPUT
+ saveGeometryToObj(meshBuffer, "ArbitMeshes.obj");
+ saveGeometryToObj(intersectionBuffer, "inter.obj");
+#endif
- pairsAlreadyCreated.insert(pr);
- }
+ return 0;
+}
- chunkTrianglesOffsets.push_back(0);
- for (uint32_t i = 0; i < chunkCount; ++i)
- {
- const float SCALE_FACTOR = 1.001f;
- PxVec3 centroid(resultChunkDescriptors[i].centroid[0], resultChunkDescriptors[i].centroid[1], resultChunkDescriptors[i].centroid[2]);
- for (uint32_t k = 0; k < trianglesCount[i]; ++k)
- {
- chunkTriangles.push_back(trianglesBuffer[i].get()[k]);
+int32_t BlastBondGeneratorImpl::buildDescFromInternalFracture(FractureTool* tool, const bool* chunkIsSupport,
+ NvBlastBondDesc*& resultBondDescs,
+ NvBlastChunkDesc*& resultChunkDescriptors)
+{
+ uint32_t chunkCount = tool->getChunkCount();
+ std::vector<uint32_t> trianglesCount(chunkCount);
+ std::vector<std::shared_ptr<Triangle> > trianglesBuffer;
- chunkTriangles.back().a.p = (chunkTriangles.back().a.p - centroid) * SCALE_FACTOR + centroid; // inflate mesh a bit to find
- }
- chunkTrianglesOffsets.push_back(chunkTriangles.size());
- }
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ Triangle* t;
+ trianglesCount[i] = tool->getBaseMesh(i, t);
+ trianglesBuffer.push_back(std::shared_ptr<Triangle>(t, [](Triangle* t) { delete[] t; }));
+ }
- NvBlastBondDesc* adsc;
+ if (chunkCount == 0)
+ {
+ return 0;
+ }
+ resultChunkDescriptors = SAFE_ARRAY_NEW(NvBlastChunkDesc, trianglesBuffer.size());
+ std::vector<Bond> bondDescriptors;
+ 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 < trianglesCount[0]; ++tr)
+ {
+ chunkCentroid += toPxShared(trianglesBuffer[0].get()[tr].a.p);
+ chunkCentroid += toPxShared(trianglesBuffer[0].get()[tr].b.p);
+ chunkCentroid += toPxShared(trianglesBuffer[0].get()[tr].c.p);
+ }
+ chunkCentroid *= (1.0f / (3 * trianglesCount[0]));
+ resultChunkDescriptors[0].centroid[0] = chunkCentroid[0];
+ resultChunkDescriptors[0].centroid[1] = chunkCentroid[1];
+ resultChunkDescriptors[0].centroid[2] = chunkCentroid[2];
+ }
- BondGenerationConfig cfg;
- cfg.bondMode = BondGenerationConfig::AVERAGE;
- cfg.maxSeparation = 0.0f;
- uint32_t nbListSize = createFullBondListAveraged(chunkCount, chunkTrianglesOffsets.data(), chunkTriangles.data(), nullptr, chunkIsSupport, nullptr, adsc, cfg, &pairsAlreadyCreated);
+ bool hasCreatedByIslands = false;
- for (uint32_t i = 0; i < nbListSize; ++i)
- {
- mResultBondDescs.push_back(adsc[i]);
- }
- NVBLAST_FREE(adsc);
- }
+ for (uint32_t i = 1; i < chunkCount; ++i)
+ {
+ NvBlastChunkDesc& desc = resultChunkDescriptors[i];
+ desc.userData = i;
+ desc.parentChunkIndex = tool->getChunkIndex(tool->getChunkInfo(i).parent);
+ desc.flags = NvBlastChunkDesc::NoFlags;
+ hasCreatedByIslands |= (tool->getChunkInfo(i).flags & ChunkInfo::CREATED_BY_ISLAND_DETECTOR);
+ if (chunkIsSupport[i])
+ {
+ desc.flags = NvBlastChunkDesc::SupportFlag;
+ }
+ PxVec3 chunkCentroid(0, 0, 0);
+ for (uint32_t tr = 0; tr < trianglesCount[i]; ++tr)
+ {
+ auto& trRef = trianglesBuffer[i].get()[tr];
+ chunkCentroid += toPxShared(trRef.a.p);
+ chunkCentroid += toPxShared(trRef.b.p);
+ chunkCentroid += toPxShared(trRef.c.p);
+
+ int32_t id = trRef.userData;
+ if (id == 0)
+ continue;
+ bondDescriptors.push_back(Bond());
+ Bond& bond = bondDescriptors.back();
+ bond.m_chunkId = i;
+ bond.m_planeIndex = id;
+ bond.triangleIndex = tr;
+ }
+ 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());
- resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size());
- memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc) * mResultBondDescs.size());
- return mResultBondDescs.size();
- }
+ std::vector<NvBlastBondDesc> mResultBondDescs;
+
+ if (!bondDescriptors.empty())
+ {
- 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)
+ int32_t chunkId, planeId;
+ chunkId = bondDescriptors[0].m_chunkId;
+ planeId = bondDescriptors[0].m_planeIndex;
+ std::vector<BondInfo> forwardChunks;
+ std::vector<BondInfo> backwardChunks;
+
+ float area = 0;
+ PxVec3 normal(0, 0, 0);
+ PxVec3 centroid(0, 0, 0);
+ int32_t collected = 0;
+ PxBounds3 bb = PxBounds3::empty();
+
+ chunkId = -1;
+ planeId = bondDescriptors[0].m_planeIndex;
+ for (uint32_t i = 0; i <= bondDescriptors.size(); ++i)
{
- if (cfg.bondMode == BondGenerationConfig::AVERAGE)
+ if (i == bondDescriptors.size() ||
+ (chunkId != bondDescriptors[i].m_chunkId || abs(planeId) != abs(bondDescriptors[i].m_planeIndex)))
{
- resetGeometryCache();
- buildGeometryCache(meshCount, geometryOffset, geometry);
- }
- resultBond = SAFE_ARRAY_NEW(NvBlastBondDesc, overlapsCount);
-
- if (cfg.bondMode == BondGenerationConfig::EXACT)
- {
- for (uint32_t i = 0; i < overlapsCount; ++i)
+ if (chunkId != -1)
{
- 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);
+ if (bondDescriptors[i - 1].m_planeIndex > 0)
+ {
+ forwardChunks.push_back(BondInfo());
+ forwardChunks.back().area = area;
+ forwardChunks.back().normal = normal;
+ forwardChunks.back().centroid = centroid * (1.0f / 3.0f / collected);
+ forwardChunks.back().m_chunkId = chunkId;
+ forwardChunks.back().m_bb = bb;
+ }
+ else
+ {
+ backwardChunks.push_back(BondInfo());
+ backwardChunks.back().area = area;
+ backwardChunks.back().normal = normal;
+ backwardChunks.back().centroid = centroid * (1.0f / 3.0f / collected);
+ backwardChunks.back().m_chunkId = chunkId;
+ backwardChunks.back().m_bb = bb;
+ }
}
+ bb.setEmpty();
+ collected = 0;
+ area = 0;
+ normal = PxVec3(0, 0, 0);
+ centroid = PxVec3(0, 0, 0);
+ if (i != bondDescriptors.size())
+ chunkId = bondDescriptors[i].m_chunkId;
}
- else
+ if (i == bondDescriptors.size() || abs(planeId) != abs(bondDescriptors[i].m_planeIndex))
{
- for (uint32_t i = 0; i < overlapsCount; ++i)
+ for (uint32_t fchunk = 0; fchunk < forwardChunks.size(); ++fchunk)
{
- 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);
+ if (chunkIsSupport[forwardChunks[fchunk].m_chunkId] == false)
+ {
+ continue;
+ }
+ for (uint32_t bchunk = 0; bchunk < backwardChunks.size(); ++bchunk)
+ {
+ if (weakBoundingBoxIntersection(forwardChunks[fchunk].m_bb, backwardChunks[bchunk].m_bb) == 0)
+ {
+ continue;
+ }
+ if (chunkIsSupport[backwardChunks[bchunk].m_chunkId] == false)
+ {
+ continue;
+ }
+ mResultBondDescs.push_back(NvBlastBondDesc());
+ mResultBondDescs.back().bond.area =
+ std::min(forwardChunks[fchunk].area, backwardChunks[bchunk].area);
+ mResultBondDescs.back().bond.normal[0] = forwardChunks[fchunk].normal.x;
+ mResultBondDescs.back().bond.normal[1] = forwardChunks[fchunk].normal.y;
+ mResultBondDescs.back().bond.normal[2] = forwardChunks[fchunk].normal.z;
+
+ mResultBondDescs.back().bond.centroid[0] =
+ (forwardChunks[fchunk].centroid.x + backwardChunks[bchunk].centroid.x) * 0.5;
+ mResultBondDescs.back().bond.centroid[1] =
+ (forwardChunks[fchunk].centroid.y + backwardChunks[bchunk].centroid.y) * 0.5;
+ mResultBondDescs.back().bond.centroid[2] =
+ (forwardChunks[fchunk].centroid.z + backwardChunks[bchunk].centroid.z) * 0.5;
+
+
+ mResultBondDescs.back().chunkIndices[0] = forwardChunks[fchunk].m_chunkId;
+ mResultBondDescs.back().chunkIndices[1] = backwardChunks[bchunk].m_chunkId;
+ }
}
- }
-
- return overlapsCount;
- }
-
- 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<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)
+ forwardChunks.clear();
+ backwardChunks.clear();
+ if (i != bondDescriptors.size())
{
- resultBond = desc->bond;
+ planeId = bondDescriptors[i].m_planeIndex;
}
else
{
- memset(&resultBond, 0, sizeof(NvBlastBond));
- return 1;
+ break;
}
- return 0;
}
-
- std::vector<PxVec3> chunksPoints1(meshACount * 3);
- std::vector<PxVec3> chunksPoints2(meshBCount * 3);
- int32_t sp = 0;
- for (uint32_t i = 0; i < meshACount; ++i)
- {
- chunksPoints1[sp++] = meshA[i].a.p;
- chunksPoints1[sp++] = meshA[i].b.p;
- chunksPoints1[sp++] = meshA[i].c.p;
-#ifdef DEBUG_OUTPUT
- meshBuffer.push_back(meshA[i].a.p);
- meshBuffer.push_back(meshA[i].b.p);
- meshBuffer.push_back(meshA[i].c.p);
-#endif
+ collected++;
+ auto& trRef = trianglesBuffer[chunkId].get()[bondDescriptors[i].triangleIndex];
+ PxVec3 n = getNormal(trRef);
+ area += n.magnitude();
+ normal = n.getNormalized();
+ centroid += toPxShared(trRef.a.p);
+ centroid += toPxShared(trRef.b.p);
+ centroid += toPxShared(trRef.c.p);
+
+ bb.include(toPxShared(trRef.a.p));
+ bb.include(toPxShared(trRef.b.p));
+ bb.include(toPxShared(trRef.c.p));
+ }
+ }
+
+ if (hasCreatedByIslands)
+ {
+ std::vector<Triangle> chunkTriangles;
+ std::vector<uint32_t> chunkTrianglesOffsets;
+ std::set<std::pair<uint32_t, uint32_t> > pairsAlreadyCreated;
- }
- sp = 0;
- for (uint32_t i = 0; i < meshBCount; ++i)
+ for (uint32_t i = 0; i < mResultBondDescs.size(); ++i)
+ {
+ auto pr = (mResultBondDescs[i].chunkIndices[0] < mResultBondDescs[i].chunkIndices[1]) ?
+ std::make_pair(mResultBondDescs[i].chunkIndices[0], mResultBondDescs[i].chunkIndices[1]) :
+ std::make_pair(mResultBondDescs[i].chunkIndices[1], mResultBondDescs[i].chunkIndices[0]);
+
+ pairsAlreadyCreated.insert(pr);
+ }
+
+
+ chunkTrianglesOffsets.push_back(0);
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ const float SCALE_FACTOR = 1.001f;
+ NvcVec3 centroid = {resultChunkDescriptors[i].centroid[0], resultChunkDescriptors[i].centroid[1],
+ resultChunkDescriptors[i].centroid[2]};
+ for (uint32_t k = 0; k < trianglesCount[i]; ++k)
{
- chunksPoints2[sp++] = meshB[i].a.p;
- chunksPoints2[sp++] = meshB[i].b.p;
- chunksPoints2[sp++] = meshB[i].c.p;
-#ifdef DEBUG_OUTPUT
- meshBuffer.push_back(meshB[i].a.p);
- meshBuffer.push_back(meshB[i].b.p);
- meshBuffer.push_back(meshB[i].c.p);
-#endif
- }
+ chunkTriangles.push_back(trianglesBuffer[i].get()[k]);
+ chunkTriangles.back().a.p =
+ (chunkTriangles.back().a.p - centroid) * SCALE_FACTOR + centroid; // inflate mesh a bit to find
+ }
+ chunkTrianglesOffsets.push_back(chunkTriangles.size());
+ }
- Nv::Blast::ConvexMeshBuilderImpl builder(mPxCooking, mPxInsertionCallback);
+ NvBlastBondDesc* adsc;
- CollisionHull* cHull[2];
- cHull[0] = builder.buildCollisionGeometry(chunksPoints1.size(), chunksPoints1.data());
- cHull[1] = builder.buildCollisionGeometry(chunksPoints2.size(), chunksPoints2.data());
+ BondGenerationConfig cfg;
+ cfg.bondMode = BondGenerationConfig::AVERAGE;
+ cfg.maxSeparation = 0.0f;
- std::vector<PxVec3> hullPoints[2];
- hullPoints[0].resize(cHull[0]->pointsCount);
- hullPoints[1].resize(cHull[1]->pointsCount);
+ uint32_t nbListSize =
+ createFullBondListAveraged(chunkCount, chunkTrianglesOffsets.data(), chunkTriangles.data(), nullptr,
+ chunkIsSupport, nullptr, adsc, cfg, &pairsAlreadyCreated);
+ for (uint32_t i = 0; i < nbListSize; ++i)
+ {
+ mResultBondDescs.push_back(adsc[i]);
+ }
+ NVBLAST_FREE(adsc);
+ }
- PxBounds3 bb[2];
- bb[0].setEmpty();
- bb[1].setEmpty();
+ resultBondDescs = SAFE_ARRAY_NEW(NvBlastBondDesc, mResultBondDescs.size());
+ memcpy(resultBondDescs, mResultBondDescs.data(), sizeof(NvBlastBondDesc) * mResultBondDescs.size());
- for (uint32_t cv = 0; cv < 2; ++cv)
- {
- for (uint32_t i = 0; i < cHull[cv]->pointsCount; ++i)
- {
- hullPoints[cv][i] = cHull[cv]->points[i];
- bb[cv].include(hullPoints[cv][i]);
- }
- }
- auto ret = createBondForcedInternal(hullPoints[0], hullPoints[1], *cHull[0], *cHull[1], bb[0], bb[1], resultBond, overlapping);
+ return mResultBondDescs.size();
+}
- cHull[0]->release();
- cHull[1]->release();
+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(meshCount, geometryOffset, geometry);
+ }
+ resultBond = SAFE_ARRAY_NEW(NvBlastBondDesc, overlapsCount);
- return ret;
+ if (cfg.bondMode == BondGenerationConfig::EXACT)
+ {
+ for (uint32_t i = 0; i < overlapsCount; ++i)
+ {
+ 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);
}
-
- int32_t BlastBondGeneratorImpl::bondsFromPrefractured(uint32_t meshCount, const uint32_t* geometryCount, const Triangle* geometry,
- const bool* chunkIsSupport, NvBlastBondDesc*& resultBondDescs, BondGenerationConfig conf)
+ }
+ else
+ {
+ for (uint32_t i = 0; i < overlapsCount; ++i)
{
- int32_t ret_val = 0;
- switch (conf.bondMode)
- {
- case BondGenerationConfig::AVERAGE:
- ret_val = createFullBondListAveraged(meshCount, geometryCount, geometry, nullptr, chunkIsSupport, nullptr, resultBondDescs, conf);
- break;
- case BondGenerationConfig::EXACT:
- ret_val = createFullBondListExact(meshCount, geometryCount, geometry, chunkIsSupport, resultBondDescs, conf);
- break;
- }
- return ret_val;
+ 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 overlapsCount;
+}
- int32_t BlastBondGeneratorImpl::bondsFromPrefractured(uint32_t meshCount, const uint32_t* convexHullOffset, const CollisionHull** chunkHulls, const bool* chunkIsSupport, const uint32_t* meshGroups, NvBlastBondDesc*& resultBondDescs, float maxSeparation)
+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<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)
{
- BondGenerationConfig conf;
- conf.maxSeparation = maxSeparation;
- conf.bondMode = BondGenerationConfig::AVERAGE;
- return createFullBondListAveraged(meshCount, convexHullOffset, nullptr, chunkHulls, chunkIsSupport, meshGroups, resultBondDescs, conf);
+ resultBond = desc->bond;
}
+ else
+ {
+ memset(&resultBond, 0, sizeof(NvBlastBond));
+ return 1;
+ }
+ return 0;
+ }
+
+ std::vector<NvcVec3> chunksPoints1(meshACount * 3);
+ std::vector<NvcVec3> chunksPoints2(meshBCount * 3);
+
+ int32_t sp = 0;
+ for (uint32_t i = 0; i < meshACount; ++i)
+ {
+ chunksPoints1[sp++] = meshA[i].a.p;
+ chunksPoints1[sp++] = meshA[i].b.p;
+ chunksPoints1[sp++] = meshA[i].c.p;
+#ifdef DEBUG_OUTPUT
+ meshBuffer.push_back(meshA[i].a.p);
+ meshBuffer.push_back(meshA[i].b.p);
+ meshBuffer.push_back(meshA[i].c.p);
+#endif
+ }
+ sp = 0;
+ for (uint32_t i = 0; i < meshBCount; ++i)
+ {
+ chunksPoints2[sp++] = meshB[i].a.p;
+ chunksPoints2[sp++] = meshB[i].b.p;
+ chunksPoints2[sp++] = meshB[i].c.p;
+#ifdef DEBUG_OUTPUT
+ meshBuffer.push_back(meshB[i].a.p);
+ meshBuffer.push_back(meshB[i].b.p);
+ meshBuffer.push_back(meshB[i].c.p);
+#endif
+ }
+
+ CollisionHull* cHull[2];
+
+ cHull[0] = mConvexMeshBuilder->buildCollisionGeometry(chunksPoints1.size(), chunksPoints1.data());
+ cHull[1] = mConvexMeshBuilder->buildCollisionGeometry(chunksPoints2.size(), chunksPoints2.data());
+
+ std::vector<PxVec3> hullPoints[2];
+ hullPoints[0].resize(cHull[0]->pointsCount);
+ hullPoints[1].resize(cHull[1]->pointsCount);
- void BlastBondGeneratorImpl::release()
+
+ PxBounds3 bb[2];
+ bb[0].setEmpty();
+ bb[1].setEmpty();
+
+ for (uint32_t cv = 0; cv < 2; ++cv)
+ {
+ for (uint32_t i = 0; i < cHull[cv]->pointsCount; ++i)
{
- delete this;
+ hullPoints[cv][i] = toPxShared(cHull[cv]->points[i]);
+ bb[cv].include(hullPoints[cv][i]);
}
+ }
+ auto ret = createBondForcedInternal(hullPoints[0], hullPoints[1], *cHull[0], *cHull[1], bb[0], bb[1], resultBond,
+ overlapping);
+
+ mConvexMeshBuilder->releaseCollisionHull(cHull[0]);
+ mConvexMeshBuilder->releaseCollisionHull(cHull[1]);
+ 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, nullptr, chunkIsSupport, nullptr,
+ resultBondDescs, conf);
+ break;
+ case BondGenerationConfig::EXACT:
+ ret_val = createFullBondListExact(meshCount, geometryCount, geometry, chunkIsSupport, resultBondDescs, conf);
+ break;
}
+ return ret_val;
}
+
+
+int32_t BlastBondGeneratorImpl::bondsFromPrefractured(uint32_t meshCount, const uint32_t* convexHullOffset,
+ const CollisionHull** chunkHulls, const bool* chunkIsSupport,
+ const uint32_t* meshGroups, NvBlastBondDesc*& resultBondDescs,
+ float maxSeparation)
+{
+ BondGenerationConfig conf;
+ conf.maxSeparation = maxSeparation;
+ conf.bondMode = BondGenerationConfig::AVERAGE;
+ return createFullBondListAveraged(meshCount, convexHullOffset, nullptr, chunkHulls, chunkIsSupport, meshGroups,
+ resultBondDescs, conf);
+}
+
+void BlastBondGeneratorImpl::release()
+{
+ delete this;
+}
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h index 222d22b..79c43bb 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h @@ -31,9 +31,8 @@ #include "NvBlastExtAuthoringBondGenerator.h"
#include "NvBlastExtAuthoringFractureTool.h"
-#include "../cooking/PxCooking.h"
#include <PxPlane.h>
-#include <NvBlastExtAuthoringCollisionBuilder.h>
+#include <NvBlastExtAuthoringConvexMeshBuilder.h>
#include <vector>
#include <set>
@@ -50,8 +49,8 @@ class BlastBondGeneratorImpl : public BlastBondGenerator {
public:
- BlastBondGeneratorImpl(physx::PxCooking* cooking, physx::PxPhysicsInsertionCallback* insertionCallback)
- : mPxCooking(cooking), mPxInsertionCallback(insertionCallback) {};
+ BlastBondGeneratorImpl(ConvexMeshBuilder* builder)
+ : mConvexMeshBuilder(builder) {};
virtual void release() override;
@@ -91,9 +90,7 @@ private: void buildGeometryCache(uint32_t meshCount, const uint32_t* geometryOffset, const Triangle* geometry);
void resetGeometryCache();
- physx::PxCooking* mPxCooking;
- physx::PxPhysicsInsertionCallback* mPxInsertionCallback;
-
+ ConvexMeshBuilder* mConvexMeshBuilder;
std::vector<std::vector<Triangle> > mGeometryCache;
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp index 5d85c36..89a3498 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp @@ -30,17 +30,14 @@ #include "NvBlastExtAuthoringBooleanTool.h"
#include "NvBlastExtAuthoringMeshImpl.h"
#include "NvBlastExtAuthoringAccelerator.h"
+#include <NvBlastPxSharedHelpers.h>
#include <math.h>
#include <set>
#include <algorithm>
-using physx::PxVec3;
-using physx::PxVec2;
using physx::PxBounds3;
-
-
namespace Nv
{
namespace Blast
@@ -48,14 +45,14 @@ namespace Blast /* Linear interpolation of vectors */
-NV_FORCE_INLINE void vec3Lerp(const PxVec3& a, const PxVec3& b, PxVec3& out, float t)
+NV_FORCE_INLINE void vec3Lerp(const NvcVec3& a, const NvcVec3& b, NvcVec3& out, float t)
{
out.x = (b.x - a.x) * t + a.x;
out.y = (b.y - a.y) * t + a.y;
out.z = (b.z - a.z) * t + a.z;
}
-NV_FORCE_INLINE void vec2Lerp(const PxVec2& a, const PxVec2& b, PxVec2& out, float t)
+NV_FORCE_INLINE void vec2Lerp(const NvcVec2& a, const NvcVec2& b, NvcVec2& out, float t)
{
out.x = (b.x - a.x) * t + a.x;
out.y = (b.y - a.y) * t + a.y;
@@ -75,24 +72,24 @@ NV_FORCE_INLINE void BooleanEvaluator::addEdgeIfValid(EdgeWithParent& ed) /**
Vertex level shadowing functions
*/
-NV_FORCE_INLINE int32_t vertexShadowing(const PxVec3& a, const PxVec3& b)
+NV_FORCE_INLINE int32_t vertexShadowing(const NvcVec3& a, const NvcVec3& b)
{
return (b.x >= a.x) ? 1 : 0;
}
/**
Vertex-edge status functions
*/
-NV_FORCE_INLINE int32_t veStatus01(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p)
+NV_FORCE_INLINE int32_t veStatus01(const NvcVec3& sEdge, const NvcVec3& eEdge, const NvcVec3& p)
{
return vertexShadowing(p, eEdge) - vertexShadowing(p, sEdge);
}
-NV_FORCE_INLINE int32_t veStatus10(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p)
+NV_FORCE_INLINE int32_t veStatus10(const NvcVec3& sEdge, const NvcVec3& eEdge, const NvcVec3& p)
{
return -vertexShadowing(eEdge, p) + vertexShadowing(sEdge, p);
}
-bool shouldSwap(const PxVec3& a, const PxVec3& b)
+bool shouldSwap(const NvcVec3& a, const NvcVec3& b)
{
if (a.x < b.x) return false;
if (a.x > b.x) return true;
@@ -109,7 +106,7 @@ bool shouldSwap(const PxVec3& a, const PxVec3& b) /**
Vertex-edge shadowing functions
*/
-int32_t shadowing01(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
+int32_t shadowing01(Vertex sEdge, Vertex eEdge, const NvcVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
{
int32_t winding = veStatus01(sEdge.p, eEdge.p, p);
@@ -148,7 +145,7 @@ int32_t shadowing01(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgeP }
return 0;
}
-int32_t shadowing10(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
+int32_t shadowing10(Vertex sEdge, Vertex eEdge, const NvcVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
{
int32_t winding = veStatus10(sEdge.p, eEdge.p, p);
@@ -187,7 +184,7 @@ int32_t shadowing10(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgeP return 0;
}
-int32_t shadowing01(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p)
+int32_t shadowing01(NvcVec3 sEdge, NvcVec3 eEdge, const NvcVec3& p)
{
int32_t winding = veStatus01(sEdge, eEdge, p);
@@ -198,7 +195,7 @@ int32_t shadowing01(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p) std::swap(sEdge, eEdge);
}
float t = ((p.x - sEdge.x) / (eEdge.x - sEdge.x));
- PxVec3 onEdgePoint;
+ NvcVec3 onEdgePoint;
if (t >= 1)
onEdgePoint = eEdge;
else if (t <= 0)
@@ -213,7 +210,7 @@ int32_t shadowing01(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p) return 0;
}
-int32_t shadowing10(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p)
+int32_t shadowing10(NvcVec3 sEdge, NvcVec3 eEdge, const NvcVec3& p)
{
int32_t winding = veStatus10(sEdge, eEdge, p);
if (winding != 0)
@@ -224,7 +221,7 @@ int32_t shadowing10(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p) }
float t = ((p.x - sEdge.x) / (eEdge.x - sEdge.x));
- PxVec3 onEdgePoint;
+ NvcVec3 onEdgePoint;
if (t >= 1)
onEdgePoint = eEdge;
else if (t <= 0)
@@ -243,7 +240,7 @@ int32_t shadowing10(PxVec3 sEdge, 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* out)
+int32_t vfStatus02(const NvcVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out)
{
int32_t val = 0;
Vertex pnt;
@@ -270,7 +267,7 @@ 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)
+int32_t shadowing02(const NvcVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
{
Vertex outp[2];
int32_t stat = vfStatus02(p, points, edges, edgesCount, outp);
@@ -280,10 +277,10 @@ int32_t shadowing02(const PxVec3& p, const Vertex* points, const Edge* edges, in {
Vertex& p1 = outp[0];
Vertex& p2 = outp[1];
- PxVec3 vc = p2.p - p1.p;
+ NvcVec3 vc = p2.p - p1.p;
float t = 0;
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);
+ t = physx::PxClamp(t, 0.0f, 1.0f);
z = t * vc.z + p1.p.z;
hasOnFacetPoint = true;
@@ -301,7 +298,7 @@ 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* out)
+int32_t vfStatus20(const NvcVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out)
{
int32_t val = 0;
Vertex pnt;
@@ -328,7 +325,7 @@ int32_t vfStatus20(const PxVec3& p, const Vertex* points, const Edge* edges, int return val;
}
-int32_t shadowing20(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
+int32_t shadowing20(const NvcVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
{
Vertex outp[2];
int32_t stat = vfStatus20(p, points, edges, edgesCount, outp);
@@ -337,10 +334,10 @@ int32_t shadowing20(const PxVec3& p, const Vertex* points, const Edge* edges, in {
Vertex& p1 = outp[0];
Vertex& p2 = outp[1];
- PxVec3 vc = p2.p - p1.p;
+ NvcVec3 vc = p2.p - p1.p;
float t = 0;
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);
+ t = physx::PxClamp(t, 0.0f, 1.0f);
hasOnFacetPoint = true;
onFacetPoint.p.x = p.x;
@@ -360,7 +357,7 @@ int32_t shadowing20(const PxVec3& p, const Vertex* points, const Edge* edges, in }
-NV_FORCE_INLINE int32_t edgesCrossCheck(const PxVec3& eAs, const PxVec3& eAe, const PxVec3& eBs, const PxVec3& eBe)
+NV_FORCE_INLINE int32_t edgesCrossCheck(const NvcVec3& eAs, const NvcVec3& eAe, const NvcVec3& eBs, const NvcVec3& eBe)
{
return shadowing01(eBs, eBe, eAe) - shadowing01(eBs, eBe, eAs) + shadowing10(eAs, eAe, eBe) - shadowing10(eAs, eAe, eBs);
}
@@ -634,7 +631,7 @@ int32_t edgeFacetIntersection21(const Vertex& edSt, const Vertex& edEnd, const V return status;
}
-int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, const Mesh* mesh)
+int32_t BooleanEvaluator::vertexMeshStatus03(const NvcVec3& p, const Mesh* mesh)
{
int32_t status = 0;
Vertex pnt;
@@ -656,7 +653,7 @@ int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, const Mesh* mesh) return status;
}
-int32_t BooleanEvaluator::vertexMeshStatus30(const PxVec3& p, const Mesh* mesh)
+int32_t BooleanEvaluator::vertexMeshStatus30(const NvcVec3& p, const Mesh* mesh)
{
int32_t status = 0;
bool hasPoints = false;
@@ -695,25 +692,25 @@ NV_FORCE_INLINE int32_t inclusionValue30(BooleanConf& conf, int32_t xValue) struct VertexComparator
{
- VertexComparator(PxVec3 base = PxVec3()) : basePoint(base) {};
- PxVec3 basePoint;
+ VertexComparator(NvcVec3 base = NvcVec3()) : basePoint(base) {};
+ NvcVec3 basePoint;
bool operator()(const Vertex& a, const Vertex& b)
{
- return (b.p - a.p).dot(basePoint) > 0.0;
+ return dot(b.p - a.p, basePoint) > 0.0;
}
};
struct VertexPairComparator
{
- VertexPairComparator(PxVec3 base = PxVec3()) : basePoint(base) {};
- PxVec3 basePoint;
+ VertexPairComparator(NvcVec3 base = NvcVec3()) : basePoint(base) {};
+ NvcVec3 basePoint;
bool operator()(const std::pair<Vertex, Vertex>& a, const std::pair<Vertex, Vertex>& b)
{
- return (b.first.p - a.first.p).dot(basePoint) > 0.0;
+ return dot(b.first.p - a.first.p, basePoint) > 0.0;
}
};
-int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, const PxVec3& point)
+int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, const NvcVec3& point)
{
if (msh == nullptr)
{
@@ -725,7 +722,7 @@ int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, const PxVec3& }
-int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, SpatialAccelerator* spAccel, const PxVec3& point)
+int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, SpatialAccelerator* spAccel, const NvcVec3& point)
{
if (msh == nullptr)
{
@@ -771,8 +768,8 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) const Edge* fae = facetAEdges;
retainedStarts.clear();
retainedEnds.clear();
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
+ NvcVec3 compositeEndPoint = {0, 0, 0};
+ NvcVec3 compositeStartPoint = {0, 0, 0};
uint32_t facetAEdgeCount = mMeshA->getFacet(facetA)->edgesCount;
uint32_t facetBEdgeCount = mMeshB->getFacet(facetB)->edgesCount;
int32_t ic = 0;
@@ -792,7 +789,7 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEnds.push_back(std::make_pair(newPointA, newPointB));
- compositeEndPoint += newPointA.p;
+ compositeEndPoint = compositeEndPoint + newPointA.p;
}
mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
}
@@ -801,7 +798,7 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStarts.push_back(std::make_pair(newPointA, newPointB));
- compositeStartPoint += newPointA.p;
+ compositeStartPoint = compositeStartPoint + newPointA.p;
}
mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
}
@@ -825,7 +822,7 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEnds.push_back(std::make_pair(newPointA, newPointB));
- compositeEndPoint += newPointB.p;
+ compositeEndPoint = compositeEndPoint + newPointB.p;
}
mEdgeFacetIntersectionData21[facetB].push_back(EdgeFacetIntersectionData( i, statusValue, newPointB));
}
@@ -834,7 +831,7 @@ void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStarts.push_back(std::make_pair(newPointA, newPointB));
- compositeStartPoint += newPointB.p;
+ compositeStartPoint = compositeStartPoint + newPointB.p;
}
mEdgeFacetIntersectionData21[facetB].push_back(EdgeFacetIntersectionData(i, statusValue, newPointB));
}
@@ -895,8 +892,8 @@ void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode) const Edge* fae = facetAEdges;
retainedStarts.clear();
retainedEnds.clear();
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
+ NvcVec3 compositeEndPoint = {0, 0, 0};
+ NvcVec3 compositeStartPoint = {0, 0, 0};
uint32_t facetAEdgeCount = mMeshA->getFacet(facetA)->edgesCount;
uint32_t facetBEdgeCount = mMeshB->getFacet(facetB)->edgesCount;
int32_t ic = 0;
@@ -916,7 +913,7 @@ void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEnds.push_back(std::make_pair(newPointA, newPointB));
- compositeEndPoint += newPointA.p;
+ compositeEndPoint = compositeEndPoint + newPointA.p;
}
mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
}
@@ -925,7 +922,7 @@ void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStarts.push_back(std::make_pair(newPointA, newPointB));
- compositeStartPoint += newPointA.p;
+ compositeStartPoint = compositeStartPoint + newPointA.p;
}
mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
}
@@ -967,7 +964,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) const Vertex* vertices = mMeshA->getVertices();
Vertex newPoint;
VertexComparator comp;
- const PxBounds3& bMeshBoudning = mMeshB->getBoundingBox();
+ const PxBounds3& bMeshBoudning = toPxShared(mMeshB->getBoundingBox());
const Edge* facetEdges = mMeshA->getEdges();
std::vector<Vertex> retainedStartVertices;
std::vector<Vertex> retainedEndVertices;
@@ -980,12 +977,12 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) retainedEndVertices.clear();
for (uint32_t i = 0; i < mMeshA->getFacet(facetId)->edgesCount; ++i)
{
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
+ NvcVec3 compositeEndPoint = {0, 0, 0};
+ NvcVec3 compositeStartPoint = {0, 0, 0};
int32_t lastPos = static_cast<int32_t>(retainedEndVertices.size());
/* Test start and end point of edge against mesh */
- if (bMeshBoudning.contains(vertices[facetEdges->s].p))
+ if (bMeshBoudning.contains(toPxShared(vertices[facetEdges->s].p)))
{
statusValue = vertexMeshStatus03(vertices[facetEdges->s].p, mMeshB);
}
@@ -1001,7 +998,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEndVertices.push_back(vertices[facetEdges->s]);
- compositeEndPoint += vertices[facetEdges->s].p;
+ compositeEndPoint = compositeEndPoint + vertices[facetEdges->s].p;
}
}
else
@@ -1011,12 +1008,12 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStartVertices.push_back(vertices[facetEdges->s]);
- compositeStartPoint += vertices[facetEdges->s].p;
+ compositeStartPoint = compositeStartPoint + vertices[facetEdges->s].p;
}
}
}
- if (bMeshBoudning.contains(vertices[facetEdges->e].p))
+ if (bMeshBoudning.contains(toPxShared(vertices[facetEdges->e].p)))
{
statusValue = vertexMeshStatus03(vertices[facetEdges->e].p, mMeshB);
}
@@ -1030,7 +1027,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEndVertices.push_back(vertices[facetEdges->e]);
- compositeEndPoint += vertices[facetEdges->e].p;
+ compositeEndPoint = compositeEndPoint + vertices[facetEdges->e].p;
}
}
else
@@ -1040,7 +1037,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStartVertices.push_back(vertices[facetEdges->e]);
- compositeStartPoint += vertices[facetEdges->e].p;
+ compositeStartPoint = compositeStartPoint + vertices[facetEdges->e].p;
}
}
}
@@ -1058,7 +1055,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEndVertices.push_back(newPoint);
- compositeEndPoint += newPoint.p;
+ compositeEndPoint = compositeEndPoint + newPoint.p;
}
}
else
@@ -1068,7 +1065,7 @@ void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStartVertices.push_back(newPoint);
- compositeStartPoint += newPoint.p;
+ compositeStartPoint = compositeStartPoint + newPoint.p;
}
}
}
@@ -1108,7 +1105,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) const Vertex* vertices = mMeshB->getVertices();
Vertex newPoint;
VertexComparator comp;
- const PxBounds3& aMeshBoudning = mMeshA->getBoundingBox();
+ const PxBounds3& aMeshBoudning = toPxShared(mMeshA->getBoundingBox());
const Edge* facetEdges = mMeshB->getEdges();
std::vector<Vertex> retainedStartVertices;
std::vector<Vertex> retainedEndVertices;
@@ -1121,10 +1118,10 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) retainedEndVertices.clear();
for (uint32_t i = 0; i < mMeshB->getFacet(facetId)->edgesCount; ++i)
{
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
+ NvcVec3 compositeEndPoint = {0, 0, 0};
+ NvcVec3 compositeStartPoint = {0, 0, 0};
int32_t lastPos = static_cast<int32_t>(retainedEndVertices.size());
- if (aMeshBoudning.contains(vertices[facetEdges->s].p))
+ if (aMeshBoudning.contains(toPxShared(vertices[facetEdges->s].p)))
{
statusValue = vertexMeshStatus30(vertices[facetEdges->s].p, mMeshA);
}
@@ -1140,7 +1137,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEndVertices.push_back(vertices[facetEdges->s]);
- compositeEndPoint += vertices[facetEdges->s].p;
+ compositeEndPoint = compositeEndPoint + vertices[facetEdges->s].p;
}
}
@@ -1151,13 +1148,13 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStartVertices.push_back(vertices[facetEdges->s]);
- compositeStartPoint += vertices[facetEdges->s].p;
+ compositeStartPoint = compositeStartPoint + vertices[facetEdges->s].p;
}
}
}
- if (aMeshBoudning.contains(vertices[facetEdges->e].p))
+ if (aMeshBoudning.contains(toPxShared(vertices[facetEdges->e].p)))
{
statusValue = vertexMeshStatus30(vertices[facetEdges->e].p, mMeshA);
}
@@ -1171,7 +1168,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEndVertices.push_back(vertices[facetEdges->e]);
- compositeEndPoint += vertices[facetEdges->e].p;
+ compositeEndPoint = compositeEndPoint + vertices[facetEdges->e].p;
}
}
@@ -1182,7 +1179,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStartVertices.push_back(vertices[facetEdges->e]);
- compositeStartPoint += vertices[facetEdges->e].p;
+ compositeStartPoint = compositeStartPoint + vertices[facetEdges->e].p;
}
}
@@ -1200,7 +1197,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) for (ic = 0; ic < inclusionValue; ++ic)
{
retainedEndVertices.push_back(newPoint);
- compositeEndPoint += newPoint.p;
+ compositeEndPoint = compositeEndPoint + newPoint.p;
}
}
else
@@ -1210,7 +1207,7 @@ void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode) for (ic = 0; ic < -inclusionValue; ++ic)
{
retainedStartVertices.push_back(newPoint);
- compositeStartPoint += newPoint.p;
+ compositeStartPoint = compositeStartPoint + newPoint.p;
}
}
}
@@ -1320,7 +1317,7 @@ Mesh* BooleanEvaluator::createNewMesh() std::sort(mEdgeAggregate.begin(), mEdgeAggregate.end(), EdgeWithParentSortComp);
std::vector<Facet> newFacets;
std::vector<Edge> newEdges(mEdgeAggregate.size());
- uint32_t lastPos = 0;
+ int32_t lastPos = 0;
uint32_t lastParent = mEdgeAggregate[0].parent;
uint32_t collected = 0;
int64_t userData = 0;
@@ -1344,7 +1341,7 @@ Mesh* BooleanEvaluator::createNewMesh() materialId = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->materialId;
smoothingGroup = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->smoothingGroup;
}
- newFacets.push_back(Facet(lastPos, collected, materialId, userData, smoothingGroup));
+ newFacets.push_back({ lastPos, collected, userData, materialId, smoothingGroup });
lastPos = i;
lastParent = mEdgeAggregate[i].parent;
collected = 0;
@@ -1366,7 +1363,7 @@ Mesh* BooleanEvaluator::createNewMesh() materialId = mMeshB->getFacet(pr)->materialId;
smoothingGroup = mMeshB->getFacet(pr)->smoothingGroup;
}
- newFacets.push_back(Facet(lastPos, collected, materialId, userData, smoothingGroup));
+ newFacets.push_back({ lastPos, collected, userData, materialId, smoothingGroup });
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()));
}
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h index 48875fa..71f346a 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h @@ -156,7 +156,7 @@ public: \param[in] point Point which should be tested
\return not 0 if point is inside of mesh
*/
- int32_t isPointContainedInMesh(const Mesh* mesh, const physx::PxVec3& point);
+ int32_t isPointContainedInMesh(const Mesh* mesh, const NvcVec3& point);
/**
Test whether point contained in mesh.
\param[in] mesh Mesh geometry
@@ -164,7 +164,7 @@ public: \param[in] point Point which should be tested
\return not 0 if point is inside of mesh
*/
- int32_t isPointContainedInMesh(const Mesh* mesh, SpatialAccelerator* spAccel, const physx::PxVec3& point);
+ int32_t isPointContainedInMesh(const Mesh* mesh, SpatialAccelerator* spAccel, const NvcVec3& point);
/**
@@ -189,8 +189,8 @@ private: void addEdgeIfValid(EdgeWithParent& ed);
private:
- int32_t vertexMeshStatus03(const physx::PxVec3& p, const Mesh* mesh);
- int32_t vertexMeshStatus30(const physx::PxVec3& p, const Mesh* mesh);
+ int32_t vertexMeshStatus03(const NvcVec3& p, const Mesh* mesh);
+ int32_t vertexMeshStatus30(const NvcVec3& p, const Mesh* mesh);
const Mesh* mMeshA;
const Mesh* mMeshB;
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp index 60435d0..506227e 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp @@ -27,147 +27,27 @@ #include <NvBlastGlobals.h>
#include "NvBlastExtAuthoringCollisionBuilderImpl.h"
-#include <PxConvexMesh.h>
-#include <PxVec3.h>
-#include <PxBounds3.h>
-#include "PxPhysics.h"
-#include "cooking/PxCooking.h"
-#include <NvBlastExtApexSharedParts.h>
+#include <NvBlastExtApexSharedParts.h>
#include <NvBlastExtAuthoringInternalCommon.h>
#include <NvBlastExtAuthoringBooleanTool.h>
#include <NvBlastExtAuthoringMeshImpl.h>
#include <NvBlastExtAuthoringMeshUtils.h>
+#include <NvBlastPxSharedHelpers.h>
#include <VHACD.h>
+#include <vector>
using namespace physx;
-#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? reinterpret_cast<T*>(NVBLAST_ALLOC(sizeof(T) * (x))) : nullptr;
-#define SAFE_ARRAY_DELETE(x) if (x != nullptr) {NVBLAST_FREE(x); x = nullptr;}
-
namespace Nv
{
namespace Blast
{
-CollisionHullImpl::~CollisionHullImpl()
-{
- SAFE_ARRAY_DELETE(points);
- SAFE_ARRAY_DELETE(indices);
- SAFE_ARRAY_DELETE(polygonData);
-}
-
-CollisionHullImpl::CollisionHullImpl(const CollisionHull& hullToCopy)
-{
- pointsCount = hullToCopy.pointsCount;
- indicesCount = hullToCopy.indicesCount;
- polygonDataCount = hullToCopy.polygonDataCount;
-
- points = SAFE_ARRAY_NEW(physx::PxVec3, pointsCount);
- indices = SAFE_ARRAY_NEW(uint32_t, indicesCount);
- polygonData = SAFE_ARRAY_NEW(CollisionHull::HullPolygon, polygonDataCount);
- memcpy(points, hullToCopy.points, sizeof(points[0]) * pointsCount);
- memcpy(indices, hullToCopy.indices, sizeof(indices[0]) * indicesCount);
- memcpy(polygonData, hullToCopy.polygonData, sizeof(polygonData[0]) * polygonDataCount);
-}
-
-void CollisionHullImpl::release()
-{
- delete this;
-}
-
-CollisionHull* ConvexMeshBuilderImpl::buildCollisionGeometry(uint32_t verticesCount, const physx::PxVec3* vData)
-{
- CollisionHull* output = new CollisionHullImpl();
- std::vector<physx::PxVec3> vertexData(verticesCount);
- memcpy(vertexData.data(), vData, sizeof(physx::PxVec3) * verticesCount);
-
- PxConvexMeshDesc convexMeshDescr;
- PxConvexMesh* resultConvexMesh;
- PxBounds3 bounds;
- // Scale chunk to unit cube size, to avoid numerical errors
- bounds.setEmpty();
- for (uint32_t i = 0; i < vertexData.size(); ++i)
- {
- bounds.include(vertexData[i]);
- }
- PxVec3 bbCenter = bounds.getCenter();
- float scale = PxMax(PxAbs(bounds.getExtents(0)), PxMax(PxAbs(bounds.getExtents(1)), PxAbs(bounds.getExtents(2))));
- for (uint32_t i = 0; i < vertexData.size(); ++i)
- {
- vertexData[i] = vertexData[i] - bbCenter;
- vertexData[i] *= (1.0f / scale);
- }
- bounds.setEmpty();
- for (uint32_t i = 0; i < vertexData.size(); ++i)
- {
- bounds.include(vertexData[i]);
- }
- convexMeshDescr.points.data = vertexData.data();
- convexMeshDescr.points.stride = sizeof(PxVec3);
- convexMeshDescr.points.count = (uint32_t)vertexData.size();
- convexMeshDescr.flags = PxConvexFlag::eCOMPUTE_CONVEX;
- resultConvexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback);
- if (!resultConvexMesh)
- {
- vertexData.clear();
- vertexData.push_back(bounds.minimum);
- vertexData.push_back(PxVec3(bounds.minimum.x, bounds.maximum.y, bounds.minimum.z));
- vertexData.push_back(PxVec3(bounds.maximum.x, bounds.maximum.y, bounds.minimum.z));
- vertexData.push_back(PxVec3(bounds.maximum.x, bounds.minimum.y, bounds.minimum.z));
- vertexData.push_back(PxVec3(bounds.minimum.x, bounds.minimum.y, bounds.maximum.z));
- vertexData.push_back(PxVec3(bounds.minimum.x, bounds.maximum.y, bounds.maximum.z));
- vertexData.push_back(PxVec3(bounds.maximum.x, bounds.maximum.y, bounds.maximum.z));
- vertexData.push_back(PxVec3(bounds.maximum.x, bounds.minimum.y, bounds.maximum.z));
- convexMeshDescr.points.data = vertexData.data();
- convexMeshDescr.points.count = (uint32_t)vertexData.size();
- resultConvexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback);
- }
- 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];
- resultConvexMesh->getPolygonData(i, hPoly);
- pd.mIndexBase = hPoly.mIndexBase;
- pd.mNbVerts = hPoly.mNbVerts;
- pd.mPlane[0] = hPoly.mPlane[0];
- pd.mPlane[1] = hPoly.mPlane[1];
- pd.mPlane[2] = hPoly.mPlane[2];
- pd.mPlane[3] = hPoly.mPlane[3];
-
- pd.mPlane[0] /= scale;
- pd.mPlane[1] /= scale;
- pd.mPlane[2] /= scale;
- pd.mPlane[3] -= (pd.mPlane[0] * bbCenter.x + pd.mPlane[1] * bbCenter.y + pd.mPlane[2] * bbCenter.z);
- float length = sqrt(pd.mPlane[0] * pd.mPlane[0] + pd.mPlane[1] * pd.mPlane[1] + pd.mPlane[2] * pd.mPlane[2]);
- pd.mPlane[0] /= length;
- pd.mPlane[1] /= length;
- pd.mPlane[2] /= length;
- pd.mPlane[3] /= length;
- indicesCount = PxMax(indicesCount, pd.mIndexBase + pd.mNbVerts);
- }
- 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;
- }
- for (int32_t i = 0; i < indicesCount; ++i)
- {
- output->indices[i] = resultConvexMesh->getIndexBuffer()[i];
- }
- resultConvexMesh->release();
- return output;
-}
+#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? reinterpret_cast<T*>(NVBLAST_ALLOC(sizeof(T) * (x))) : nullptr;
+#define SAFE_ARRAY_DELETE(x) if (x != nullptr) {NVBLAST_FREE(x); x = nullptr;}
-void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth)
+void trimCollisionGeometry(ConvexMeshBuilder& cmb, uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth)
{
std::vector<std::vector<PxPlane> > chunkMidplanes(chunksCount);
std::vector<PxVec3> centers(chunksCount);
@@ -178,8 +58,8 @@ void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, Collisio centers[i] = PxVec3(0, 0, 0);
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] += toPxShared(in[i]->points[p]);
+ hullsBounds[i].include(toPxShared(in[i]->points[p]));
}
centers[i] = hullsBounds[i].getCenter();
}
@@ -193,8 +73,10 @@ void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, Collisio {
continue;
}
- if (importerHullsInProximityApexFree(in[hull]->pointsCount, in[hull]->points, hullsBounds[hull], PxTransform(PxIdentity), PxVec3(1, 1, 1),
- in[hull2]->pointsCount, in[hull2]->points, hullsBounds[hull2], PxTransform(PxIdentity), PxVec3(1, 1, 1), 0.0, ¶ms) == false)
+ if (importerHullsInProximityApexFree(in[hull]->pointsCount, toPxShared(in[hull]->points), hullsBounds[hull],
+ PxTransform(PxIdentity), PxVec3(1, 1, 1), in[hull2]->pointsCount,
+ toPxShared(in[hull2]->points), hullsBounds[hull2], PxTransform(PxIdentity),
+ PxVec3(1, 1, 1), 0.0, ¶ms) == false)
{
continue;
}
@@ -205,20 +87,20 @@ void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, Collisio PxVec3 n2;
for (uint32_t p = 0; p < in[hull]->pointsCount; ++p)
{
- float ld = (in[hull]->points[p] - c2).magnitude();
+ float ld = (toPxShared(in[hull]->points[p]) - c2).magnitude();
if (ld < d)
{
- n1 = in[hull]->points[p];
+ n1 = toPxShared(in[hull]->points[p]);
d = ld;
}
}
d = FLT_MAX;
for (uint32_t p = 0; p < in[hull2]->pointsCount; ++p)
{
- float ld = (in[hull2]->points[p] - c1).magnitude();
+ float ld = (toPxShared(in[hull2]->points[p]) - c1).magnitude();
if (ld < d)
{
- n2 = in[hull2]->points[p];
+ n2 = toPxShared(in[hull2]->points[p]);
d = ld;
}
}
@@ -242,12 +124,12 @@ void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, Collisio Facet nFc;
nFc.firstEdgeNumber = edges.size();
auto& pd = in[i]->polygonData[fc];
- uint32_t n = pd.mNbVerts;
+ uint32_t n = pd.vertexCount;
for (uint32_t ed = 0; ed < n; ++ed)
{
- 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));
+ uint32_t vr1 = in[i]->indices[(ed) + pd.indexBase];
+ uint32_t vr2 = in[i]->indices[(ed + 1) % n + pd.indexBase];
+ edges.push_back({vr1, vr2});
}
nFc.edgesCount = n;
facets.push_back(nFc);
@@ -260,7 +142,7 @@ void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, Collisio Mesh* hullMesh = new MeshImpl(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size());
BooleanEvaluator evl;
//I think the material ID is unused for collision meshes so harcoding MATERIAL_INTERIOR is ok
- Mesh* cuttingMesh = getCuttingBox(PxVec3(0, 0, 0), PxVec3(0, 0, 1), 40, 0, MATERIAL_INTERIOR);
+ Mesh* cuttingMesh = getCuttingBox(PxVec3(0, 0, 0), PxVec3(0, 0, 1), 40, 0, kMaterialInteriorId);
for (uint32_t p = 0; p < chunkMidplanes[i].size(); ++p)
{
PxPlane& pl = chunkMidplanes[i][p];
@@ -283,72 +165,19 @@ void ConvexMeshBuilderImpl::trimCollisionGeometry(uint32_t chunksCount, Collisio hPoints.resize(hullMesh->getVerticesCount());
for (uint32_t v = 0; v < hullMesh->getVerticesCount(); ++v)
{
- hPoints[v] = hullMesh->getVertices()[v].p;
+ hPoints[v] = toPxShared(hullMesh->getVertices()[v].p);
}
delete hullMesh;
if (in[i] != nullptr)
{
- in[i]->release();
+ delete in[i];
}
- in[i] = buildCollisionGeometry(hPoints.size(), hPoints.data());
+ in[i] = cmb.buildCollisionGeometry(hPoints.size(), fromPxShared(hPoints.data()));
}
}
-
-PxConvexMesh* ConvexMeshBuilderImpl::buildConvexMesh(uint32_t verticesCount, const physx::PxVec3* vertexData)
-{
- CollisionHull* hull = buildCollisionGeometry(verticesCount, vertexData);
- PxConvexMesh* convexMesh = buildConvexMesh(*hull);
- hull->release();
- return convexMesh;
-}
-
-PxConvexMesh* ConvexMeshBuilderImpl::buildConvexMesh(const CollisionHull& hull)
-{
- /* PxCooking::createConvexMesh expects PxHullPolygon input, which matches CollisionHull::HullPolygon */
- static_assert(sizeof(PxHullPolygon) == sizeof(CollisionHull::HullPolygon), "CollisionHull::HullPolygon size mismatch");
- static_assert(offsetof(PxHullPolygon, mPlane) == offsetof(CollisionHull::HullPolygon, mPlane), "CollisionHull::HullPolygon layout mismatch");
- static_assert(offsetof(PxHullPolygon, mNbVerts) == offsetof(CollisionHull::HullPolygon, mNbVerts), "CollisionHull::HullPolygon layout mismatch");
- static_assert(offsetof(PxHullPolygon, mIndexBase) == offsetof(CollisionHull::HullPolygon, mIndexBase), "CollisionHull::HullPolygon layout mismatch");
-
- PxConvexMeshDesc convexMeshDescr;
- convexMeshDescr.indices.data = hull.indices;
- convexMeshDescr.indices.count = (uint32_t)hull.indicesCount;
- convexMeshDescr.indices.stride = sizeof(uint32_t);
-
- convexMeshDescr.points.data = hull.points;
- convexMeshDescr.points.count = (uint32_t)hull.pointsCount;
- convexMeshDescr.points.stride = sizeof(PxVec3);
-
- 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;
-}
-
-
-PxConvexMesh* ConvexMeshBuilderImpl::buildConvexMeshRT(const Nv::Blast::Vertex* vrs, uint32_t count)
-{
- PxConvexMeshDesc convexMeshDescr;
-
- convexMeshDescr.points.data = vrs;
- convexMeshDescr.points.count = (uint32_t)count;
- convexMeshDescr.points.stride = sizeof(Nv::Blast::Vertex);
-
- convexMeshDescr.flags = PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eGPU_COMPATIBLE;
-
- PxConvexMesh* convexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback);
- return convexMesh;
-}
-
-void ConvexMeshBuilderImpl::release()
-{
- delete this;
-}
-
-int32_t ConvexMeshBuilderImpl::buildMeshConvexDecomposition(const Triangle* mesh, uint32_t triangleCount, const CollisionParams& iparams, CollisionHull**& convexes)
+int32_t buildMeshConvexDecomposition(ConvexMeshBuilder& cmb, const Triangle* mesh, uint32_t triangleCount,
+ const ConvexDecompositionParams& iparams, CollisionHull**& convexes)
{
std::vector<float> coords(triangleCount * 9);
std::vector<uint32_t> indices(triangleCount * 3);
@@ -362,7 +191,7 @@ int32_t ConvexMeshBuilderImpl::buildMeshConvexDecomposition(const Triangle* mesh for (auto& t : { mesh[i].a.p , mesh[i].b.p , mesh[i].c.p })
{
- chunkBound.include(t);
+ chunkBound.include(toPxShared(t));
coords[indxCoord] = t.x;
coords[indxCoord + 1] = t.y;
coords[indxCoord + 2] = t.z;
@@ -411,7 +240,7 @@ int32_t ConvexMeshBuilderImpl::buildMeshConvexDecomposition(const Triangle* mesh vertices.back().z = vertices.back().z * rsc.z + chunkBound.minimum.z;
}
- convexes[i] = buildCollisionGeometry(vertices.size(), vertices.data());
+ convexes[i] = cmb.buildCollisionGeometry(vertices.size(), fromPxShared(vertices.data()));
}
//VHACD::~VHACD called from release does nothign and does not call Clean()
decomposer->Clean();
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h index afdbcde..8d136e4 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h @@ -29,7 +29,7 @@ #ifndef NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H
#define NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H
-#include "NvBlastExtAuthoringCollisionBuilder.h"
+#include "NvBlastExtAuthoringConvexMeshBuilder.h"
#include "NvBlastExtAuthoringTypes.h"
namespace Nv
@@ -37,54 +37,14 @@ namespace Nv namespace Blast
{
-struct CollisionHullImpl : public CollisionHull
-{
- ~CollisionHullImpl();
- CollisionHullImpl()
- {
- pointsCount = 0;
- indicesCount = 0;
- polygonDataCount = 0;
- points = nullptr;
- indices = nullptr;
- polygonData = nullptr;
- }
-
- CollisionHullImpl(const CollisionHull& hullToCopy);
-
- 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 physx::PxConvexMesh* buildConvexMeshRT(const Vertex* vrs, uint32_t count) override;
-
- virtual void trimCollisionGeometry(uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth) override;
- virtual int32_t buildMeshConvexDecomposition(const Triangle* mesh, uint32_t triangleCount, const CollisionParams& params, CollisionHull**& convexes) override;
+void trimCollisionGeometry(ConvexMeshBuilder& cmb, uint32_t chunksCount, CollisionHull** in, const uint32_t* chunkDepth);
-private:
- physx::PxPhysicsInsertionCallback* mInsertionCallback;
- physx::PxCooking* mCooking;
-};
+int32_t buildMeshConvexDecomposition(ConvexMeshBuilder& cmb, const Triangle* mesh, uint32_t triangleCount,
+ const ConvexDecompositionParams& params, CollisionHull**& convexes);
-} // namespace Blast
-} // namespace Nv
+} // namespace Blast
+} // namespace Nv
-#endif // ifndef NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H
+#endif // ifndef NVBLASTEXTAUTHORINGCOLLISIONBUILDERIIMPL_H
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.cpp index 0cb270d..cef97f7 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.cpp @@ -26,14 +26,16 @@ // Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
-#include "NvBlastExtAuthoringCutoutImpl.h"
#include "NvBlastGlobals.h"
#include <NvBlastAssert.h>
+#include <PxBounds3.h>
+#include <PxMath.h>
+#include <NvBlastPxSharedHelpers.h>
+#include "NvBlastExtAuthoringCutoutImpl.h"
#include <algorithm>
#include <set>
#include <map>
#include <stack>
-#include "PxMath.h"
#define CUTOUT_DISTANCE_THRESHOLD (0.7f)
@@ -2420,9 +2422,9 @@ PX_INLINE bool calculateUVMapping(const Nv::Blast::Triangle& triangle, physx::Px physx::PxMat33 uvMat;
for (unsigned col = 0; col < 3; ++col)
{
- auto v = triangle.getVertex(col);
- rMat[col] = v.p;
- uvMat[col] = physx::PxVec3(v.uv[0][0], v.uv[0][1], 1.0f);
+ auto v = (&triangle.a)[col];
+ rMat[col] = toPxShared(v.p);
+ uvMat[col] = physx::PxVec3(v.uv[0].x, v.uv[0].y, 1.0f);
}
if (uvMat.getDeterminant() == 0.0f)
@@ -2503,4 +2505,12 @@ PX_INLINE bool calculateUVMapping(const Nv::Blast::Triangle& triangle, physx::Px // return ::calculateUVMapping(targetDirection, theMapping);
//}
+const NvcVec3& CutoutSetImpl::getCutoutVertex(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexIndex) const
+{
+ return fromPxShared(cutoutLoops[cutouts[cutoutIndex] + loopIndex].vertices[vertexIndex]);
+}
+const NvcVec2& CutoutSetImpl::getDimensions() const
+{
+ return fromPxShared(dimensions);
+}
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.h index 0d3ef50..ea3c1ff 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.h @@ -31,7 +31,9 @@ #include "NvBlastExtAuthoringCutout.h"
#include <vector>
-#include "PxMat44.h" // TODO Should replace?
+#include <PxVec2.h>
+#include <PxVec3.h>
+#include <PxMat44.h>
namespace Nv
{
@@ -95,10 +97,7 @@ struct CutoutSetImpl : public CutoutSet return (uint32_t)cutouts[cutoutIndex + 1] - cutouts[cutoutIndex];
}
- const physx::PxVec3& getCutoutVertex(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexIndex) const
- {
- return cutoutLoops[cutouts[cutoutIndex] + loopIndex].vertices[vertexIndex];
- }
+ const NvcVec3& getCutoutVertex(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexIndex) const;
bool isCutoutVertexToggleSmoothingGroup(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexIndex) const
{
@@ -117,10 +116,7 @@ struct CutoutSetImpl : public CutoutSet {
return periodic;
}
- const physx::PxVec2& getDimensions() const
- {
- return dimensions;
- }
+ const NvcVec2& getDimensions() const;
//void serialize(physx::PxFileBuf& stream) const;
//void deserialize(physx::PxFileBuf& stream);
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp index e7bc39d..f8d9a2d 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp @@ -49,12 +49,12 @@ #include "NvBlastGlobals.h"
#include "NvBlastExtAuthoringPerlinNoise.h"
#include <NvBlastAssert.h>
-using namespace physx;
+#include <NvBlastPxSharedHelpers.h>
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) \
{ \
- if(p) \
+ if (p) \
{ \
delete (p); \
(p) = NULL; \
@@ -72,20 +72,21 @@ namespace Blast struct Halfspace_partitioning : public VSA::VS3D_Halfspace_Set
{
- std::vector<physx::PxPlane> planes;
+ std::vector<NvcPlane> planes;
VSA::real farthest_halfspace(VSA::real plane[4], const VSA::real point[4])
{
float biggest_d = -FLT_MAX;
for (uint32_t i = 0; i < planes.size(); ++i)
{
- float d = planes[i].n.x * point[0] + planes[i].n.y * point[1] + planes[i].n.z * point[2] + planes[i].d * point[3];
+ float d =
+ planes[i].n.x * point[0] + planes[i].n.y * point[1] + planes[i].n.z * point[2] + planes[i].d * point[3];
if (d > biggest_d)
{
biggest_d = d;
- plane[0] = planes[i].n.x;
- plane[1] = planes[i].n.y;
- plane[2] = planes[i].n.z;
- plane[3] = planes[i].d;
+ plane[0] = planes[i].n.x;
+ plane[1] = planes[i].n.y;
+ plane[2] = planes[i].n.z;
+ plane[3] = planes[i].d;
}
}
return biggest_d;
@@ -93,30 +94,30 @@ struct Halfspace_partitioning : public VSA::VS3D_Halfspace_Set };
-void findCellBasePlanes(const std::vector<PxVec3>& sites, std::vector<std::vector<int32_t> >& neighboors)
+void findCellBasePlanes(const std::vector<NvcVec3>& sites, std::vector<std::vector<int32_t> >& neighboors)
{
Halfspace_partitioning prt;
- std::vector<physx::PxPlane>& planes = prt.planes;
+ std::vector<NvcPlane>& planes = prt.planes;
neighboors.resize(sites.size());
for (uint32_t cellId = 0; cellId + 1 < sites.size(); ++cellId)
{
planes.clear();
planes.resize(sites.size() - 1 - cellId);
- std::vector<PxVec3> midpoints(sites.size() - 1);
+ std::vector<NvcVec3> midpoints(sites.size() - 1);
int32_t collected = 0;
for (uint32_t i = cellId + 1; i < sites.size(); ++i)
{
- PxVec3 midpoint = 0.5 * (sites[i] + sites[cellId]);
- PxVec3 direction = (sites[i] - sites[cellId]).getNormalized();
- planes[collected].n = direction;
- planes[collected].d = -direction.dot(midpoint);
+ NvcVec3 midpoint = 0.5 * (sites[i] + sites[cellId]);
+ NvcVec3 direction = fromPxShared(toPxShared(sites[i] - sites[cellId]).getNormalized());
+ planes[collected].n = direction;
+ planes[collected].d = -dot(direction, midpoint);
midpoints[collected] = midpoint;
++collected;
}
for (uint32_t i = 0; i < planes.size(); ++i)
{
- planes[i].n = -planes[i].n;
+ planes[i].n = neg(planes[i].n);
planes[i].d = -planes[i].d;
if (VSA::vs3d_test(prt))
@@ -124,7 +125,7 @@ void findCellBasePlanes(const std::vector<PxVec3>& sites, std::vector<std::vecto neighboors[cellId].push_back(i + cellId + 1);
neighboors[i + cellId + 1].push_back(cellId);
};
- planes[i].n = -planes[i].n;
+ planes[i].n = neg(planes[i].n);
planes[i].d = -planes[i].d;
}
}
@@ -134,17 +135,19 @@ void findCellBasePlanes(const std::vector<PxVec3>& sites, std::vector<std::vecto #define SITE_BOX_SIZE 4
#define CUTTING_BOX_SIZE 40
-Mesh* getCellMesh(BooleanEvaluator& eval, int32_t planeIndexerOffset, int32_t cellId, const std::vector<PxVec3>& sites, std::vector < std::vector<int32_t> >& neighboors, int32_t interiorMaterialId, physx::PxVec3 origin)
+Mesh* getCellMesh(BooleanEvaluator& eval, int32_t planeIndexerOffset, int32_t cellId, const std::vector<NvcVec3>& sites,
+ std::vector<std::vector<int32_t> >& neighboors, int32_t interiorMaterialId, NvcVec3 origin)
{
- Mesh* cell = getBigBox(origin, SITE_BOX_SIZE, interiorMaterialId);
+ Mesh* cell = getBigBox(toPxShared(origin), SITE_BOX_SIZE, interiorMaterialId);
Mesh* cuttingMesh = getCuttingBox(PxVec3(0, 0, 0), PxVec3(1, 1, 1), CUTTING_BOX_SIZE, 0, interiorMaterialId);
for (uint32_t i = 0; i < neighboors[cellId].size(); ++i)
{
- int32_t nCell = neighboors[cellId][i];
- PxVec3 midpoint = 0.5 * (sites[nCell] + sites[cellId]);
- PxVec3 direction = (sites[nCell] - sites[cellId]).getNormalized();
- int32_t planeIndex = static_cast<int32_t>(sites.size()) * std::min(cellId, nCell) + std::max(cellId, nCell) + planeIndexerOffset;
+ int32_t nCell = neighboors[cellId][i];
+ PxVec3 midpoint = 0.5 * toPxShared(sites[nCell] + sites[cellId]);
+ PxVec3 direction = toPxShared(sites[nCell] - sites[cellId]).getNormalized();
+ int32_t planeIndex =
+ static_cast<int32_t>(sites.size()) * std::min(cellId, nCell) + std::max(cellId, nCell) + planeIndexerOffset;
if (nCell < cellId)
planeIndex = -planeIndex;
setCuttingBox(midpoint, -direction, cuttingMesh, CUTTING_BOX_SIZE, planeIndex);
@@ -173,17 +176,17 @@ bool blastBondComparator(const NvBlastBondDesc& a, const NvBlastBondDesc& b) VoronoiSitesGeneratorImpl::VoronoiSitesGeneratorImpl(const Mesh* mesh, RandomGeneratorBase* rnd)
{
- mMesh = mesh;
- mRnd = rnd;
+ mMesh = mesh;
+ mRnd = rnd;
mAccelerator = new BBoxBasedAccelerator(mMesh, DEFAULT_BB_ACCELARATOR_RES);
- mStencil = nullptr;
+ mStencil = nullptr;
}
void VoronoiSitesGeneratorImpl::setBaseMesh(const Mesh* m)
{
mGeneratedSites.clear();
delete mAccelerator;
- mMesh = m;
+ mMesh = m;
mAccelerator = new BBoxBasedAccelerator(mMesh, DEFAULT_BB_ACCELARATOR_RES);
}
@@ -213,21 +216,21 @@ void VoronoiSitesGeneratorImpl::clearStencil() void VoronoiSitesGeneratorImpl::uniformlyGenerateSitesInMesh(const uint32_t sitesCount)
{
BooleanEvaluator voronoiMeshEval;
- PxVec3 mn = mMesh->getBoundingBox().minimum;
- PxVec3 mx = mMesh->getBoundingBox().maximum;
- PxVec3 vc = mx - mn;
- uint32_t attemptNumber = 0;
+ NvcVec3 mn = mMesh->getBoundingBox().minimum;
+ NvcVec3 mx = mMesh->getBoundingBox().maximum;
+ NvcVec3 vc = mx - mn;
+ uint32_t attemptNumber = 0;
uint32_t generatedSites = 0;
while (generatedSites < sitesCount && attemptNumber < MAX_VORONOI_ATTEMPT_NUMBER)
{
float rn1 = mRnd->getRandomValue() * vc.x;
float rn2 = mRnd->getRandomValue() * vc.y;
float rn3 = mRnd->getRandomValue() * vc.z;
- if (voronoiMeshEval.isPointContainedInMesh(mMesh, PxVec3(rn1, rn2, rn3) + mn) && (mStencil == nullptr
- || voronoiMeshEval.isPointContainedInMesh(mStencil, PxVec3(rn1, rn2, rn3) + mn)))
+ if (voronoiMeshEval.isPointContainedInMesh(mMesh, NvcVec3{ rn1, rn2, rn3 } + mn) &&
+ (mStencil == nullptr || voronoiMeshEval.isPointContainedInMesh(mStencil, NvcVec3{ rn1, rn2, rn3 } + mn)))
{
generatedSites++;
- mGeneratedSites.push_back(PxVec3(rn1, rn2, rn3) + mn);
+ mGeneratedSites.push_back(NvcVec3{ rn1, rn2, rn3 } + mn);
attemptNumber = 0;
}
else
@@ -240,25 +243,26 @@ void VoronoiSitesGeneratorImpl::uniformlyGenerateSitesInMesh(const uint32_t site }
-void VoronoiSitesGeneratorImpl::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;
- PxVec3 mn = mMesh->getBoundingBox().minimum;
- PxVec3 mx = mMesh->getBoundingBox().maximum;
- PxVec3 middle = (mx + mn) * 0.5;
- PxVec3 vc = (mx - mn) * 0.5;
- uint32_t attemptNumber = 0;
+ NvcVec3 mn = mMesh->getBoundingBox().minimum;
+ NvcVec3 mx = mMesh->getBoundingBox().maximum;
+ NvcVec3 middle = (mx + mn) * 0.5;
+ NvcVec3 vc = (mx - mn) * 0.5;
+ uint32_t attemptNumber = 0;
uint32_t generatedSites = 0;
- std::vector<PxVec3> tempPoints;
+ std::vector<NvcVec3> tempPoints;
while (generatedSites < numberOfClusters)
{
float rn1 = mRnd->getRandomValue() * 2 - 1;
float rn2 = mRnd->getRandomValue() * 2 - 1;
float rn3 = mRnd->getRandomValue() * 2 - 1;
- PxVec3 p = PxVec3(middle.x + rn1 * vc.x, middle.y + rn2 * vc.y, middle.z + rn3 * vc.z);
+ NvcVec3 p = { middle.x + rn1 * vc.x, middle.y + rn2 * vc.y, middle.z + rn3 * vc.z };
- if (voronoiMeshEval.isPointContainedInMesh(mMesh, p) && (mStencil == nullptr
- || voronoiMeshEval.isPointContainedInMesh(mStencil, p)))
+ if (voronoiMeshEval.isPointContainedInMesh(mMesh, p) &&
+ (mStencil == nullptr || voronoiMeshEval.isPointContainedInMesh(mStencil, p)))
{
generatedSites++;
tempPoints.push_back(p);
@@ -274,13 +278,17 @@ void VoronoiSitesGeneratorImpl::clusteredSitesGeneration(const uint32_t numberOf int32_t totalCount = 0;
for (; tempPoints.size() > 0; tempPoints.pop_back())
{
- uint32_t unif = sitesPerCluster;
+ uint32_t unif = sitesPerCluster;
generatedSites = 0;
while (generatedSites < unif)
{
- PxVec3 p = tempPoints.back() + PxVec3(mRnd->getRandomValue() * 2 - 1, mRnd->getRandomValue() * 2 - 1, mRnd->getRandomValue() * 2 - 1).getNormalized() * (mRnd->getRandomValue() + 0.001f) * clusterRadius;
- if (voronoiMeshEval.isPointContainedInMesh(mMesh, p) && (mStencil == nullptr
- || voronoiMeshEval.isPointContainedInMesh(mStencil, p)))
+ NvcVec3 p =
+ tempPoints.back() + fromPxShared(PxVec3(mRnd->getRandomValue() * 2 - 1, mRnd->getRandomValue() * 2 - 1,
+ mRnd->getRandomValue() * 2 - 1)
+ .getNormalized()) *
+ (mRnd->getRandomValue() + 0.001f) * clusterRadius;
+ if (voronoiMeshEval.isPointContainedInMesh(mMesh, p) &&
+ (mStencil == nullptr || voronoiMeshEval.isPointContainedInMesh(mStencil, p)))
{
totalCount++;
generatedSites++;
@@ -294,36 +302,35 @@ void VoronoiSitesGeneratorImpl::clusteredSitesGeneration(const uint32_t numberOf break;
}
}
-
}
-
}
#define IN_SPHERE_ATTEMPT_NUMBER 20
-void VoronoiSitesGeneratorImpl::addSite(const physx::PxVec3& site)
+void VoronoiSitesGeneratorImpl::addSite(const NvcVec3& site)
{
mGeneratedSites.push_back(site);
}
-void VoronoiSitesGeneratorImpl::generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center)
+void VoronoiSitesGeneratorImpl::generateInSphere(const uint32_t count, const float radius, const NvcVec3& center)
{
BooleanEvaluator voronoiMeshEval;
- uint32_t attemptNumber = 0;
+ uint32_t attemptNumber = 0;
uint32_t generatedSites = 0;
- std::vector<PxVec3> tempPoints;
+ std::vector<NvcVec3> tempPoints;
float radiusSquared = radius * radius;
while (generatedSites < count && attemptNumber < MAX_VORONOI_ATTEMPT_NUMBER)
{
- float rn1 = (mRnd->getRandomValue() - 0.5f) * 2.f * radius;
- float rn2 = (mRnd->getRandomValue() - 0.5f) * 2.f * radius;
- float rn3 = (mRnd->getRandomValue() - 0.5f) * 2.f * radius;
- PxVec3 point(rn1, rn2, rn3);
- if (point.magnitudeSquared() < radiusSquared && voronoiMeshEval.isPointContainedInMesh(mMesh, point + center) && (mStencil == nullptr
- || voronoiMeshEval.isPointContainedInMesh(mStencil, point + center)))
+ float rn1 = (mRnd->getRandomValue() - 0.5f) * 2.f * radius;
+ float rn2 = (mRnd->getRandomValue() - 0.5f) * 2.f * radius;
+ float rn3 = (mRnd->getRandomValue() - 0.5f) * 2.f * radius;
+ NvcVec3 point = { rn1, rn2, rn3 };
+ if (toPxShared(point).magnitudeSquared() < radiusSquared &&
+ voronoiMeshEval.isPointContainedInMesh(mMesh, point + center) &&
+ (mStencil == nullptr || voronoiMeshEval.isPointContainedInMesh(mStencil, point + center)))
{
generatedSites++;
mGeneratedSites.push_back(point + center);
@@ -339,12 +346,12 @@ void VoronoiSitesGeneratorImpl::generateInSphere(const uint32_t count, const flo }
-void VoronoiSitesGeneratorImpl::deleteInSphere(const float radius, const physx::PxVec3& center, float deleteProbability)
+void VoronoiSitesGeneratorImpl::deleteInSphere(const float radius, const NvcVec3& center, float deleteProbability)
{
float r2 = radius * radius;
for (uint32_t i = 0; i < mGeneratedSites.size(); ++i)
{
- if ((mGeneratedSites[i] - center).magnitudeSquared() < r2 && mRnd->getRandomValue() <= deleteProbability)
+ if (toPxShared(mGeneratedSites[i] - center).magnitudeSquared() < r2 && mRnd->getRandomValue() <= deleteProbability)
{
std::swap(mGeneratedSites[i], mGeneratedSites.back());
mGeneratedSites.pop_back();
@@ -354,26 +361,28 @@ void VoronoiSitesGeneratorImpl::deleteInSphere(const float radius, const physx:: }
-void VoronoiSitesGeneratorImpl::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 NvcVec3& center, const NvcVec3& normal, float radius,
+ int32_t angularSteps, int32_t radialSteps, float angleOffset,
+ float variability)
{
-// mGeneratedSites.push_back(center);
- physx::PxVec3 t1, t2;
+ // mGeneratedSites.push_back(center);
+ PxVec3 t1, t2;
if (std::abs(normal.z) < 0.9)
{
- t1 = normal.cross(PxVec3(0, 0, 1));
+ t1 = toPxShared(normal).cross(PxVec3(0, 0, 1));
}
else
{
- t1 = normal.cross(PxVec3(1, 0, 0));
+ t1 = toPxShared(normal).cross(PxVec3(1, 0, 0));
}
- t2 = t1.cross(normal);
+ t2 = t1.cross(toPxShared(normal));
t1.normalize();
t2.normalize();
float radStep = radius / radialSteps;
- int32_t cCr = 0;
+ int32_t cCr = 0;
- float angleStep = PxPi * 2 / angularSteps;
+ float angleStep = physx::PxPi * 2 / angularSteps;
for (float cRadius = radStep; cRadius < radius; cRadius += radStep)
{
float cAngle = angleOffset * cCr;
@@ -382,7 +391,7 @@ void VoronoiSitesGeneratorImpl::radialPattern(const physx::PxVec3& center, const float angVars = mRnd->getRandomValue() * variability + (1.0f - 0.5f * variability);
float radVars = mRnd->getRandomValue() * variability + (1.0f - 0.5f * variability);
- PxVec3 nPos = (PxCos(cAngle * angVars) * t1 + PxSin(cAngle * angVars) * t2) * cRadius * radVars + center;
+ NvcVec3 nPos = fromPxShared(std::cos(cAngle * angVars) * t1 + std::sin(cAngle * angVars) * t2) * cRadius * radVars + center;
mGeneratedSites.push_back(nPos);
cAngle += angleStep;
}
@@ -390,7 +399,7 @@ void VoronoiSitesGeneratorImpl::radialPattern(const physx::PxVec3& center, const }
}
-uint32_t VoronoiSitesGeneratorImpl::getVoronoiSites(const physx::PxVec3*& sites)
+uint32_t VoronoiSitesGeneratorImpl::getVoronoiSites(const NvcVec3*& sites)
{
if (mGeneratedSites.size())
{
@@ -399,7 +408,8 @@ uint32_t VoronoiSitesGeneratorImpl::getVoronoiSites(const physx::PxVec3*& sites) return (uint32_t)mGeneratedSites.size();
}
-int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPointsIn, bool replaceChunk)
+int32_t
+FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const NvcVec3* cellPointsIn, bool replaceChunk)
{
if (chunkId == 0 && replaceChunk)
{
@@ -419,7 +429,7 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount Mesh* mesh = mChunkData[chunkIndex].meshData;
- std::vector<PxVec3> cellPoints(cellCount);
+ std::vector<NvcVec3> cellPoints(cellCount);
for (uint32_t i = 0; i < cellCount; ++i)
{
cellPoints[i] = (cellPointsIn[i] - mOffset) * (1.0f / mScaleFactor);
@@ -443,7 +453,8 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount std::vector<uint32_t> newlyCreatedChunksIds;
for (uint32_t i = 0; i < cellPoints.size(); ++i)
{
- Mesh* cell = getCellMesh(eval, mPlaneIndexerOffset, i, cellPoints, neighboors, mInteriorMaterialId, cellPoints[i]);
+ Mesh* cell =
+ getCellMesh(eval, mPlaneIndexerOffset, i, cellPoints, neighboors, mInteriorMaterialId, cellPoints[i]);
if (cell == nullptr)
{
@@ -454,8 +465,8 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount Mesh* resultMesh = voronoiMeshEval.createNewMesh();
if (resultMesh)
{
- uint32_t ncidx = createNewChunk(parentChunk);
- mChunkData[ncidx].isLeaf = true;
+ uint32_t ncidx = createNewChunk(parentChunk);
+ mChunkData[ncidx].isLeaf = true;
mChunkData[ncidx].meshData = resultMesh;
newlyCreatedChunksIds.push_back(mChunkData[ncidx].chunkId);
}
@@ -476,7 +487,7 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount islandDetectionAndRemoving(chunkToCheck);
}
}
-
+
return 0;
}
@@ -500,11 +511,11 @@ Mesh* FractureToolImpl::createChunkMesh(int32_t chunkId) bool FractureToolImpl::isMeshContainOpenEdges(const Mesh* input)
{
- std::map<PxVec3, int32_t, VrtPositionComparator> vertexMapping;
+ std::map<NvcVec3, int32_t, VrtPositionComparator> vertexMapping;
std::vector<int32_t> vertexRemappingArray(input->getVerticesCount());
std::vector<Edge> remappedEdges(input->getEdgesCount());
/**
- Remap vertices
+ Remap vertices
*/
const Vertex* vrx = input->getVertices();
@@ -513,7 +524,7 @@ bool FractureToolImpl::isMeshContainOpenEdges(const Mesh* input) auto it = vertexMapping.find(vrx->p);
if (it == vertexMapping.end())
{
- vertexMapping[vrx->p] = i;
+ vertexMapping[vrx->p] = i;
vertexRemappingArray[i] = i;
}
else
@@ -522,7 +533,7 @@ bool FractureToolImpl::isMeshContainOpenEdges(const Mesh* input) }
++vrx;
}
-
+
const Edge* ed = input->getEdges();
for (uint32_t i = 0; i < input->getEdgesCount(); ++i)
{
@@ -559,7 +570,8 @@ bool FractureToolImpl::isMeshContainOpenEdges(const Mesh* input) return collected & 1;
}
-int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const physx::PxVec3* cellPointsIn, const physx::PxVec3& scale, const physx::PxQuat& rotation, bool replaceChunk)
+int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const NvcVec3* cellPointsIn,
+ const NvcVec3& scale, const NvcQuat& rotation, bool replaceChunk)
{
if (chunkId == 0 && replaceChunk)
{
@@ -579,17 +591,16 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount Mesh* mesh = mChunkData[chunkIndex].meshData;
- std::vector<PxVec3> cellPoints(cellCount);
+ std::vector<NvcVec3> cellPoints(cellCount);
for (uint32_t i = 0; i < cellCount; ++i)
{
cellPoints[i] = (cellPointsIn[i] - mOffset) * (1.0f / mScaleFactor);
-
- cellPoints[i] = rotation.rotateInv(cellPoints[i]);
+
+ toPxShared(cellPoints[i]) = toPxShared(rotation).rotateInv(toPxShared(cellPoints[i]));
cellPoints[i].x *= (1.0f / scale.x);
cellPoints[i].y *= (1.0f / scale.y);
cellPoints[i].z *= (1.0f / scale.z);
-
}
/**
@@ -611,8 +622,9 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount for (uint32_t i = 0; i < cellPoints.size(); ++i)
{
- Mesh* cell = getCellMesh(eval, mPlaneIndexerOffset, i, cellPoints, neighboors, mInteriorMaterialId, cellPoints[i]);
-
+ Mesh* cell =
+ getCellMesh(eval, mPlaneIndexerOffset, i, cellPoints, neighboors, mInteriorMaterialId, cellPoints[i]);
+
if (cell == nullptr)
{
continue;
@@ -623,7 +635,7 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount cell->getVerticesWritable()[v].p.x *= scale.x;
cell->getVerticesWritable()[v].p.y *= scale.y;
cell->getVerticesWritable()[v].p.z *= scale.z;
- cell->getVerticesWritable()[v].p = rotation.rotate(cell->getVerticesWritable()[v].p);
+ toPxShared(cell->getVerticesWritable()[v].p) = toPxShared(rotation).rotate(toPxShared(cell->getVerticesWritable()[v].p));
}
cell->recalculateBoundingBox();
DummyAccelerator dmAccel(cell->getFacetCount());
@@ -631,8 +643,8 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount Mesh* resultMesh = voronoiMeshEval.createNewMesh();
if (resultMesh)
{
- uint32_t ncidx = createNewChunk(parentChunk);
- mChunkData[ncidx].isLeaf = true;
+ uint32_t ncidx = createNewChunk(parentChunk);
+ mChunkData[ncidx].isLeaf = true;
mChunkData[ncidx].meshData = resultMesh;
newlyCreatedChunksIds.push_back(mChunkData[ncidx].chunkId);
}
@@ -657,7 +669,8 @@ int32_t FractureToolImpl::voronoiFracturing(uint32_t chunkId, uint32_t cellCount return 0;
}
-int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk, RandomGeneratorBase* rnd)
+int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk,
+ RandomGeneratorBase* rnd)
{
if (conf.noise.amplitude != 0)
{
@@ -679,19 +692,19 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& deleteAllChildrenOfChunk(chunkId);
}
chunkIndex = getChunkIndex(chunkId);
-
- Mesh* mesh = new MeshImpl(*reinterpret_cast <MeshImpl*>(mChunkData[chunkIndex].meshData));
-
+
+ Mesh* mesh = new MeshImpl(*reinterpret_cast<MeshImpl*>(mChunkData[chunkIndex].meshData));
+
BooleanEvaluator bTool;
int32_t x_slices = conf.x_slices;
int32_t y_slices = conf.y_slices;
int32_t z_slices = conf.z_slices;
- const PxBounds3 sourceBBox = mesh->getBoundingBox();
+ const physx::PxBounds3 sourceBBox = toPxShared(mesh->getBoundingBox());
- PxVec3 center = PxVec3(mesh->getBoundingBox().minimum.x, 0, 0);
+ PxVec3 center = {mesh->getBoundingBox().minimum.x, 0, 0};
float x_offset = (sourceBBox.maximum.x - sourceBBox.minimum.x) * (1.0f / (x_slices + 1));
@@ -700,15 +713,15 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& center.x += x_offset;
- PxVec3 dir(1, 0, 0);
+ PxVec3 dir = {1, 0, 0};
Mesh* slBox = getCuttingBox(center, dir, 20, 0, mInteriorMaterialId);
ChunkInfo ch;
- ch.isLeaf = true;
+ ch.isLeaf = true;
ch.isChanged = true;
- ch.flags = ChunkInfo::NO_FLAGS;
- ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
+ ch.flags = ChunkInfo::NO_FLAGS;
+ ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
std::vector<ChunkInfo> xSlicedChunks;
std::vector<ChunkInfo> ySlicedChunks;
std::vector<uint32_t> newlyCreatedChunksIds;
@@ -717,7 +730,8 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& */
for (int32_t slice = 0; slice < x_slices; ++slice)
{
- PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
+ 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 + SLICING_INDEXER_OFFSET);
@@ -751,15 +765,16 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& {
center = PxVec3(0, sourceBBox.minimum.y, 0);
center.y += y_offset;
- dir = PxVec3(0, 1, 0);
+ dir = PxVec3(0, 1, 0);
mesh = xSlicedChunks[chunk].meshData;
for (int32_t slice = 0; slice < y_slices; ++slice)
{
- PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
+ 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 + SLICING_INDEXER_OFFSET);
bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION());
ch.meshData = bTool.createNewMesh();
@@ -791,12 +806,13 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& {
center = PxVec3(0, 0, sourceBBox.minimum.z);
center.z += z_offset;
- dir = PxVec3(0, 0, 1);
+ dir = PxVec3(0, 0, 1);
mesh = ySlicedChunks[chunk].meshData;
for (int32_t slice = 0; slice < z_slices; ++slice)
{
- PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
+ 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 + SLICING_INDEXER_OFFSET);
bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION());
@@ -821,7 +837,7 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& }
if (mesh != 0)
{
- ch.chunkId = mChunkIdCounter++;
+ ch.chunkId = mChunkIdCounter++;
ch.meshData = mesh;
mChunkData.push_back(ch);
newlyCreatedChunksIds.push_back(ch.chunkId);
@@ -848,7 +864,8 @@ int32_t FractureToolImpl::slicing(uint32_t chunkId, const SlicingConfiguration& return 0;
}
-int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk, RandomGeneratorBase* rnd)
+int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk,
+ RandomGeneratorBase* rnd)
{
if (replaceChunk && chunkId == 0)
{
@@ -867,7 +884,7 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat chunkIndex = getChunkIndex(chunkId);
- Mesh* mesh = new MeshImpl(*reinterpret_cast <MeshImpl*>(mChunkData[chunkIndex].meshData));
+ Mesh* mesh = new MeshImpl(*reinterpret_cast<MeshImpl*>(mChunkData[chunkIndex].meshData));
BooleanEvaluator bTool;
@@ -875,7 +892,7 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat int32_t y_slices = conf.y_slices;
int32_t z_slices = conf.z_slices;
- const PxBounds3 sourceBBox = mesh->getBoundingBox();
+ const physx::PxBounds3 sourceBBox = toPxShared(mesh->getBoundingBox());
PxVec3 center = PxVec3(mesh->getBoundingBox().minimum.x, 0, 0);
@@ -884,7 +901,8 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat float y_offset = (sourceBBox.maximum.y - sourceBBox.minimum.y) * (1.0f / (y_slices + 1));
float z_offset = (sourceBBox.maximum.z - sourceBBox.minimum.z) * (1.0f / (z_slices + 1));
- physx::PxVec3 resolution(mScaleFactor / conf.noise.samplingInterval.x, mScaleFactor / conf.noise.samplingInterval.y, mScaleFactor / conf.noise.samplingInterval.z);
+ PxVec3 resolution(mScaleFactor / conf.noise.samplingInterval.x, mScaleFactor / conf.noise.samplingInterval.y,
+ mScaleFactor / conf.noise.samplingInterval.z);
center.x += x_offset;
@@ -893,24 +911,28 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat Mesh* slBox = nullptr;
ChunkInfo ch;
- ch.isLeaf = true;
+ ch.isLeaf = true;
ch.isChanged = true;
- ch.flags = ChunkInfo::NO_FLAGS;
- ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
+ ch.flags = ChunkInfo::NO_FLAGS;
+ ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
std::vector<ChunkInfo> xSlicedChunks;
std::vector<ChunkInfo> ySlicedChunks;
std::vector<uint32_t> newlyCreatedChunksIds;
float noisyPartSize = 1.2f;
-// int32_t acceleratorRes = 8;
+ // int32_t acceleratorRes = 8;
/**
- Slice along x direction
+ Slice along x direction
*/
for (int32_t slice = 0; slice < x_slices; ++slice)
{
- PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
+ PxVec3 randVect =
+ PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
PxVec3 lDir = dir + randVect * conf.angle_variations;
- slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, resolution, mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, conf.noise.amplitude, conf.noise.frequency, conf.noise.octaveNumber, rnd->getRandomValue(), mInteriorMaterialId);
- // DummyAccelerator accel(mesh->getFacetCount());
+ slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, resolution,
+ mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, conf.noise.amplitude,
+ conf.noise.frequency, conf.noise.octaveNumber, rnd->getRandomValue(),
+ mInteriorMaterialId);
+ // DummyAccelerator accel(mesh->getFacetCount());
SweepingAccelerator accel(mesh);
SweepingAccelerator dummy(slBox);
bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE());
@@ -937,22 +959,26 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat ch.meshData = mesh;
xSlicedChunks.push_back(ch);
}
- slBox = getCuttingBox(center, dir, 20, 0, mInteriorMaterialId);
+ slBox = getCuttingBox(center, dir, 20, 0, mInteriorMaterialId);
uint32_t slicedChunkSize = xSlicedChunks.size();
for (uint32_t chunk = 0; chunk < slicedChunkSize; ++chunk)
{
center = PxVec3(0, sourceBBox.minimum.y, 0);
center.y += y_offset;
- dir = PxVec3(0, 1, 0);
+ dir = PxVec3(0, 1, 0);
mesh = xSlicedChunks[chunk].meshData;
for (int32_t slice = 0; slice < y_slices; ++slice)
{
- PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
+ PxVec3 randVect =
+ PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
PxVec3 lDir = dir + randVect * conf.angle_variations;
- slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, resolution, mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, conf.noise.amplitude, conf.noise.frequency, conf.noise.octaveNumber, rnd->getRandomValue(), mInteriorMaterialId);
- // DummyAccelerator accel(mesh->getFacetCount());
+ slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, resolution,
+ mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, conf.noise.amplitude,
+ conf.noise.frequency, conf.noise.octaveNumber, rnd->getRandomValue(),
+ mInteriorMaterialId);
+ // DummyAccelerator accel(mesh->getFacetCount());
SweepingAccelerator accel(mesh);
SweepingAccelerator dummy(slBox);
bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE());
@@ -985,15 +1011,19 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat {
center = PxVec3(0, 0, sourceBBox.minimum.z);
center.z += z_offset;
- dir = PxVec3(0, 0, 1);
+ dir = PxVec3(0, 0, 1);
mesh = ySlicedChunks[chunk].meshData;
for (int32_t slice = 0; slice < z_slices; ++slice)
{
- PxVec3 randVect = PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
+ PxVec3 randVect =
+ PxVec3(2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1, 2 * rnd->getRandomValue() - 1);
PxVec3 lDir = dir + randVect * conf.angle_variations;
- slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, resolution, mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, conf.noise.amplitude, conf.noise.frequency, conf.noise.octaveNumber, rnd->getRandomValue(), mInteriorMaterialId);
- // DummyAccelerator accel(mesh->getFacetCount());
+ slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, resolution,
+ mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, conf.noise.amplitude,
+ conf.noise.frequency, conf.noise.octaveNumber, rnd->getRandomValue(),
+ mInteriorMaterialId);
+ // DummyAccelerator accel(mesh->getFacetCount());
SweepingAccelerator accel(mesh);
SweepingAccelerator dummy(slBox);
bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE());
@@ -1019,14 +1049,14 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat }
if (mesh != 0)
{
- ch.chunkId = mChunkIdCounter++;
+ ch.chunkId = mChunkIdCounter++;
ch.meshData = mesh;
mChunkData.push_back(ch);
newlyCreatedChunksIds.push_back(ch.chunkId);
}
}
-// delete slBox;
+ // delete slBox;
mChunkData[chunkIndex].isLeaf = false;
if (replaceChunk)
@@ -1044,7 +1074,8 @@ int32_t FractureToolImpl::slicingNoisy(uint32_t chunkId, const SlicingConfigurat return 0;
}
-int32_t FractureToolImpl::cut(uint32_t chunkId, const physx::PxVec3& normal, const physx::PxVec3& point, const NoiseConfiguration& noise, bool replaceChunk, RandomGeneratorBase* rnd)
+int32_t FractureToolImpl::cut(uint32_t chunkId, const NvcVec3& normal, const NvcVec3& point,
+ const NoiseConfiguration& noise, bool replaceChunk, RandomGeneratorBase* rnd)
{
if (replaceChunk && chunkId == 0)
{
@@ -1062,21 +1093,24 @@ int32_t FractureToolImpl::cut(uint32_t chunkId, const physx::PxVec3& normal, con }
chunkIndex = getChunkIndex(chunkId);
- Mesh* mesh = new MeshImpl(*reinterpret_cast <MeshImpl*>(mChunkData[chunkIndex].meshData));
+ Mesh* mesh = new MeshImpl(*reinterpret_cast<MeshImpl*>(mChunkData[chunkIndex].meshData));
BooleanEvaluator bTool;
ChunkInfo ch;
- ch.chunkId = -1;
- ch.isLeaf = true;
- ch.isChanged = true;
- ch.flags = ChunkInfo::NO_FLAGS;
- ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
+ ch.chunkId = -1;
+ ch.isLeaf = true;
+ ch.isChanged = true;
+ ch.flags = ChunkInfo::NO_FLAGS;
+ ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
float noisyPartSize = 1.2f;
-
- physx::PxVec3 resolution(mScaleFactor / noise.samplingInterval.x, mScaleFactor / noise.samplingInterval.y, mScaleFactor / noise.samplingInterval.z);
+
+ PxVec3 resolution(mScaleFactor / noise.samplingInterval.x, mScaleFactor / noise.samplingInterval.y,
+ mScaleFactor / noise.samplingInterval.z);
// Perform cut
- Mesh* slBox = getNoisyCuttingBoxPair((point - mOffset) / mScaleFactor, normal, 40, noisyPartSize, resolution, mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, noise.amplitude, noise.frequency, noise.octaveNumber, rnd->getRandomValue(), mInteriorMaterialId);
+ Mesh* slBox = getNoisyCuttingBoxPair(toPxShared(point - mOffset) / mScaleFactor, toPxShared(normal), 40, noisyPartSize, resolution,
+ mPlaneIndexerOffset + SLICING_INDEXER_OFFSET, noise.amplitude, noise.frequency,
+ noise.octaveNumber, rnd->getRandomValue(), mInteriorMaterialId);
SweepingAccelerator accel(mesh);
SweepingAccelerator dummy(slBox);
bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE());
@@ -1088,8 +1122,8 @@ int32_t FractureToolImpl::cut(uint32_t chunkId, const physx::PxVec3& normal, con delete slBox;
delete mesh;
mesh = result;
-
- if (mesh == 0) //Return if it doesn't cut specified chunk
+
+ if (mesh == 0) // Return if it doesn't cut specified chunk
{
return 1;
}
@@ -1109,11 +1143,11 @@ int32_t FractureToolImpl::cut(uint32_t chunkId, const physx::PxVec3& normal, con }
if (mesh != 0)
{
- ch.chunkId = mChunkIdCounter++;
+ ch.chunkId = mChunkIdCounter++;
ch.meshData = mesh;
mChunkData.push_back(ch);
}
-
+
mChunkData[chunkIndex].isLeaf = false;
if (replaceChunk)
{
@@ -1133,7 +1167,7 @@ int32_t FractureToolImpl::cut(uint32_t chunkId, const physx::PxVec3& normal, con }
-bool CmpVec::operator()(const physx::PxVec3& v1, const physx::PxVec3& v2) const
+bool CmpVec::operator()(const PxVec3& v1, const PxVec3& v2) const
{
auto v = (v2 - v1).abs();
if (v.x < 1e-5)
@@ -1164,42 +1198,42 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo {
deleteAllChildrenOfChunk(chunkId);
}
- chunkIndex = getChunkIndex(chunkId);
+ chunkIndex = getChunkIndex(chunkId);
Nv::Blast::CutoutSet& cutoutSet = *conf.cutoutSet;
- Mesh* mesh = new MeshImpl(*reinterpret_cast <MeshImpl*>(mChunkData[chunkIndex].meshData));
- float extrusionLength = mesh->getBoundingBox().getDimensions().magnitude();
- auto scale = conf.scale / mScaleFactor;
- conf.transform.p = (conf.transform.p - mOffset) / mScaleFactor;
+ Mesh* mesh = new MeshImpl(*reinterpret_cast<MeshImpl*>(mChunkData[chunkIndex].meshData));
+ float extrusionLength = toPxShared(mesh->getBoundingBox()).getDimensions().magnitude();
+ auto scale = toPxShared(conf.scale) / mScaleFactor;
+ conf.transform.p = (conf.transform.p - mOffset) / mScaleFactor;
if (scale.x < 0.f || scale.y < 0.f)
{
- scale = physx::PxVec2(extrusionLength);
+ scale = { extrusionLength, extrusionLength };
}
if (conf.isRelativeTransform)
{
- conf.transform.p += mesh->getBoundingBox().getCenter() / mScaleFactor;
+ toPxShared(conf.transform.p) += toPxShared(mesh->getBoundingBox()).getCenter() / mScaleFactor;
}
- conf.noise.samplingInterval /= mScaleFactor;
+ toPxShared(conf.noise.samplingInterval) /= mScaleFactor;
float xDim = cutoutSet.getDimensions().x;
float yDim = cutoutSet.getDimensions().y;
- if (conf.cutoutSet->isPeriodic()) //cutout with periodic boundary do not support noise and conicity
+ if (conf.cutoutSet->isPeriodic()) // cutout with periodic boundary do not support noise and conicity
{
- conf.aperture = 0.f;
+ conf.aperture = 0.f;
conf.noise.amplitude = 0.f;
}
BooleanEvaluator bTool;
ChunkInfo ch;
- ch.isLeaf = true;
+ ch.isLeaf = true;
ch.isChanged = true;
- ch.flags = ChunkInfo::NO_FLAGS;
- ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
+ ch.flags = ChunkInfo::NO_FLAGS;
+ ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId;
std::vector<uint32_t> newlyCreatedChunksIds;
SharedFacesMap sharedFacesMap;
- std::vector<std::vector<physx::PxVec3>> verts;
- std::vector<std::set<int32_t>> smoothingGroups;
+ std::vector<std::vector<PxVec3> > verts;
+ std::vector<std::set<int32_t> > smoothingGroups;
std::vector<uint32_t> cutoutStarts;
for (uint32_t c = 0; c < cutoutSet.getCutoutCount(); c++)
@@ -1208,14 +1242,14 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo for (uint32_t l = 0; l < cutoutSet.getCutoutLoopCount(c); l++)
{
uint32_t vertCount = cutoutSet.getCutoutVertexCount(c, l);
- verts.push_back(std::vector<physx::PxVec3>(vertCount));
+ verts.push_back(std::vector<PxVec3>(vertCount));
smoothingGroups.push_back(std::set<int32_t>());
for (uint32_t v = 0; v < vertCount; v++)
{
- auto vert = cutoutSet.getCutoutVertex(c, l, v);
- vert.x = (vert.x / xDim - 0.5f) * scale.x;
- vert.y = (vert.y / yDim - 0.5f) * scale.y;
- verts.back()[v] = vert;
+ auto vert = cutoutSet.getCutoutVertex(c, l, v);
+ vert.x = (vert.x / xDim - 0.5f) * scale.x;
+ vert.y = (vert.y / yDim - 0.5f) * scale.y;
+ verts.back()[v] = toPxShared(vert);
if (cutoutSet.isCutoutVertexToggleSmoothingGroup(c, l, v))
{
@@ -1226,25 +1260,27 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo }
float dimension = scale.magnitude();
- float conicityMultiplierBot = 1.f + 2.f * extrusionLength / dimension * physx::PxTan(physx::PxClamp(conf.aperture, -179.f, 179.f) * physx::PxPi / 360.f);
+ float conicityMultiplierBot =
+ 1.f + 2.f * extrusionLength / dimension *
+ physx::PxTan(physx::PxClamp(conf.aperture, -179.f, 179.f) * physx::PxPi / 360.f);
float conicityMultiplierTop = 2.f - conicityMultiplierBot;
float heightBot = extrusionLength, heightTop = extrusionLength;
if (conicityMultiplierBot < 0.f)
{
conicityMultiplierBot = 0.f;
- heightBot = 0.5f * dimension / std::abs(physx::PxTan(conf.aperture * physx::PxPi / 360.f));
+ heightBot = 0.5f * dimension / std::abs(physx::PxTan(conf.aperture * physx::PxPi / 360.f));
}
if (conicityMultiplierTop < 0.f)
{
conicityMultiplierTop = 0.f;
- heightTop = 0.5f * dimension / std::abs(physx::PxTan(conf.aperture * physx::PxPi / 360.f));
+ heightTop = 0.5f * dimension / std::abs(physx::PxTan(conf.aperture * physx::PxPi / 360.f));
}
uint32_t seed = rnd->getRandomValue();
- buildCuttingConeFaces(conf, verts, heightBot, heightTop, conicityMultiplierBot, conicityMultiplierTop,
- mPlaneIndexerOffset, seed, mInteriorMaterialId, sharedFacesMap);
+ buildCuttingConeFaces(conf, verts, heightBot, heightTop, conicityMultiplierBot, conicityMultiplierTop,
+ mPlaneIndexerOffset, seed, mInteriorMaterialId, sharedFacesMap);
- std::vector<std::vector<Mesh*>> cutoutMeshes;
+ std::vector<std::vector<Mesh*> > cutoutMeshes;
for (uint32_t c = 0; c < cutoutSet.getCutoutCount(); c++)
{
cutoutMeshes.push_back(std::vector<Mesh*>());
@@ -1254,19 +1290,21 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo {
continue;
}
- cutoutMeshes.back().push_back(getCuttingCone(conf, verts[cutoutStarts[c] + l], smoothingGroups[cutoutStarts[c] + l], heightBot, heightTop, conicityMultiplierBot, conicityMultiplierTop,
- mPlaneIndexerOffset, seed, mInteriorMaterialId, sharedFacesMap, l != 0));
+ cutoutMeshes.back().push_back(
+ getCuttingCone(conf, verts[cutoutStarts[c] + l], smoothingGroups[cutoutStarts[c] + l], heightBot,
+ heightTop, conicityMultiplierBot, conicityMultiplierTop, mPlaneIndexerOffset, seed,
+ mInteriorMaterialId, sharedFacesMap, l != 0));
}
}
- std::stack<std::pair<int32_t, int32_t>> cellsStack;
- std::set<std::pair<int32_t, int32_t>> visited;
+ std::stack<std::pair<int32_t, int32_t> > cellsStack;
+ std::set<std::pair<int32_t, int32_t> > visited;
cellsStack.push(std::make_pair(0, 0));
while (!cellsStack.empty())
{
- auto cell = cellsStack.top();
- auto transformedCell = conf.transform.rotate(physx::PxVec3(cell.first * scale.x, cell.second * scale.y, 0));
+ auto cell = cellsStack.top();
+ auto transformedCell = toPxShared(conf.transform).rotate(PxVec3(cell.first * scale.x, cell.second * scale.y, 0));
cellsStack.pop();
if (visited.find(cell) != visited.end())
{
@@ -1289,10 +1327,10 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo auto vertices = cutoutMesh->getVerticesWritable();
for (uint32_t v = 0; v < cutoutMesh->getVerticesCount(); v++)
{
- vertices[v].p += transformedCell;
+ toPxShared(vertices[v].p) += transformedCell;
}
- cutoutMesh->getBoundingBoxWritable().minimum += transformedCell;
- cutoutMesh->getBoundingBoxWritable().maximum += transformedCell;
+ toPxShared(cutoutMesh->getBoundingBoxWritable().minimum) += transformedCell;
+ toPxShared(cutoutMesh->getBoundingBoxWritable().maximum) += transformedCell;
if (l == 0)
{
SweepingAccelerator accel(mesh);
@@ -1305,16 +1343,17 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo {
SweepingAccelerator accel(ch.meshData);
SweepingAccelerator dummy(cutoutMesh);
- bTool.performBoolean(ch.meshData, cutoutMesh, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE());
+ bTool.performBoolean(ch.meshData, cutoutMesh, &accel, &dummy,
+ BooleanConfigurations::BOOLEAN_DIFFERENCE());
ch.meshData = bTool.createNewMesh();
}
for (uint32_t v = 0; v < cutoutMesh->getVerticesCount(); v++)
{
- vertices[v].p -= transformedCell;
+ toPxShared(vertices[v].p) -= transformedCell;
}
- cutoutMesh->getBoundingBoxWritable().minimum -= transformedCell;
- cutoutMesh->getBoundingBoxWritable().maximum -= transformedCell;
+ toPxShared(cutoutMesh->getBoundingBoxWritable().minimum )-= transformedCell;
+ toPxShared(cutoutMesh->getBoundingBoxWritable().maximum) -= transformedCell;
}
if (ch.meshData != 0)
{
@@ -1331,7 +1370,7 @@ int32_t FractureToolImpl::cutout(uint32_t chunkId, CutoutConfiguration conf, boo {
const int32_t i0 = i & 1;
const int32_t i1 = (i >> 1) & 1;
- auto newCell = std::make_pair(cell.first + i0 - i1, cell.second + i0 + i1 - 1);
+ auto newCell = std::make_pair(cell.first + i0 - i1, cell.second + i0 + i1 - 1);
if (visited.find(newCell) == visited.end())
{
cellsStack.push(newCell);
@@ -1393,7 +1432,7 @@ int32_t FractureToolImpl::getChunkDepth(int32_t chunkId) ++depth;
chunkIndex = getChunkIndex(mChunkData[chunkIndex].parent);
}
- return depth;
+ return depth;
}
uint32_t FractureToolImpl::getChunksIdAtDepth(uint32_t depth, int32_t*& chunkIds)
@@ -1414,10 +1453,10 @@ uint32_t FractureToolImpl::getChunksIdAtDepth(uint32_t depth, int32_t*& chunkIds }
-void FractureToolImpl::getTransformation(PxVec3& offset, float& scale)
+void FractureToolImpl::getTransformation(NvcVec3& offset, float& scale)
{
offset = mOffset;
- scale = mScaleFactor;
+ scale = mScaleFactor;
}
void FractureToolImpl::setSourceMesh(const Mesh* meshInput)
@@ -1434,41 +1473,41 @@ void FractureToolImpl::setSourceMesh(const Mesh* meshInput) }
- //mChunkData.resize(1);
- //mChunkData[0].meshData = new MeshImpl(*reinterpret_cast <const MeshImpl*>(meshInput));
- //mChunkData[0].parent = -1;
- //mChunkData[0].isLeaf = true;
- //mChunkData[0].chunkId = mChunkIdCounter++;
- //Mesh* mesh = mChunkData[0].meshData;
+ // mChunkData.resize(1);
+ // mChunkData[0].meshData = new MeshImpl(*reinterpret_cast <const MeshImpl*>(meshInput));
+ // mChunkData[0].parent = -1;
+ // mChunkData[0].isLeaf = true;
+ // mChunkData[0].chunkId = mChunkIdCounter++;
+ // Mesh* mesh = mChunkData[0].meshData;
/**
Move to origin and scale to unit cube
*/
- mOffset = (meshInput->getBoundingBox().maximum + meshInput->getBoundingBox().minimum) * 0.5f;
- PxVec3 bbSizes = (meshInput->getBoundingBox().maximum - meshInput->getBoundingBox().minimum);
+ mOffset = (meshInput->getBoundingBox().maximum + meshInput->getBoundingBox().minimum) * 0.5f;
+ NvcVec3 bbSizes = (meshInput->getBoundingBox().maximum - meshInput->getBoundingBox().minimum);
mScaleFactor = std::max(bbSizes.x, std::max(bbSizes.y, bbSizes.z));
setChunkMesh(meshInput, -1);
- //Vertex* verticesBuffer = mesh->getVerticesWritable();
- //for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i)
+ // Vertex* verticesBuffer = mesh->getVerticesWritable();
+ // for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i)
//{
// verticesBuffer[i].p = (verticesBuffer[i].p - mOffset) * (1.0f / mScaleFactor);
//}
- //mesh->getBoundingBoxWritable().minimum = (mesh->getBoundingBox().minimum - mOffset) * (1.0f / mScaleFactor);
- //mesh->getBoundingBoxWritable().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)
+ // for (uint32_t i = 0; i < mesh->getFacetCount(); ++i)
//{
// mesh->getFacetWritable(i)->userData = 0; // Mark facet as initial boundary facet
//}
}
-int32_t FractureToolImpl::setChunkMesh(const Mesh* meshInput, int32_t parentId)
+int32_t FractureToolImpl::setChunkMesh(const Mesh* meshInput, int32_t parentId)
{
ChunkInfo* parent = nullptr;
for (size_t i = 0; i < mChunkData.size(); i++)
@@ -1484,18 +1523,18 @@ int32_t FractureToolImpl::setChunkMesh(const Mesh* meshInput, int32_t parentId) }
mChunkData.push_back(ChunkInfo());
- auto& chunk = mChunkData.back();
- chunk.meshData = new MeshImpl(*reinterpret_cast <const MeshImpl*>(meshInput));
- chunk.parent = parentId;
- chunk.isLeaf = true;
+ auto& chunk = mChunkData.back();
+ chunk.meshData = new MeshImpl(*reinterpret_cast<const MeshImpl*>(meshInput));
+ chunk.parent = parentId;
+ chunk.isLeaf = true;
chunk.isChanged = true;
- chunk.flags = ChunkInfo::NO_FLAGS;
+ chunk.flags = ChunkInfo::NO_FLAGS;
if ((size_t)parentId < mChunkData.size())
{
mChunkData[parentId].isLeaf = false;
}
chunk.chunkId = mChunkIdCounter++;
- Mesh* mesh = chunk.meshData;
+ Mesh* mesh = chunk.meshData;
/**
Move to origin and scale to unit cube
@@ -1510,11 +1549,11 @@ int32_t FractureToolImpl::setChunkMesh(const Mesh* meshInput, int32_t parentId) mesh->getBoundingBoxWritable().minimum = (mesh->getBoundingBox().minimum - mOffset) * (1.0f / mScaleFactor);
mesh->getBoundingBoxWritable().maximum = (mesh->getBoundingBox().maximum - mOffset) * (1.0f / mScaleFactor);
- if (parentId == -1) // We are setting root mesh. Set all facets as boundary.
+ if (parentId == -1) // We are setting root mesh. Set all facets as boundary.
{
for (uint32_t i = 0; i < mesh->getFacetCount(); ++i)
{
- mesh->getFacetWritable(i)->userData = 0; // Mark facet as initial boundary facet
+ mesh->getFacetWritable(i)->userData = 0; // Mark facet as initial boundary facet
}
}
@@ -1540,8 +1579,8 @@ void FractureToolImpl::reset() }
mChunkData.clear();
mPlaneIndexerOffset = 1;
- mChunkIdCounter = 0;
- mInteriorMaterialId = MATERIAL_INTERIOR;
+ mChunkIdCounter = 0;
+ mInteriorMaterialId = kMaterialInteriorId;
}
@@ -1607,7 +1646,7 @@ bool FractureToolImpl::deleteAllChildrenOfChunk(int32_t chunkId) void FractureToolImpl::finalizeFracturing()
{
- std::vector<Triangulator* > oldTriangulators = mChunkPostprocessors;
+ std::vector<Triangulator*> oldTriangulators = mChunkPostprocessors;
std::map<int32_t, int32_t> chunkIdToTriangulator;
std::set<uint32_t> newChunkMask;
for (uint32_t i = 0; i < oldTriangulators.size(); ++i)
@@ -1616,7 +1655,8 @@ void FractureToolImpl::finalizeFracturing() }
mChunkPostprocessors.clear();
mChunkPostprocessors.resize(mChunkData.size());
- newChunkMask.insert(0xffffffff); // To trigger masking mode, if newChunkMask will happen to be empty, all UVs will be updated.
+ newChunkMask.insert(0xffffffff); // To trigger masking mode, if newChunkMask will happen to be empty, all UVs will
+ // be updated.
for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i)
{
@@ -1639,7 +1679,7 @@ void FractureToolImpl::finalizeFracturing() mChunkPostprocessors[i] = oldTriangulators[it->second];
}
}
-
+
std::vector<int32_t> badOnes;
for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i)
{
@@ -1678,11 +1718,11 @@ uint32_t FractureToolImpl::getBaseMesh(int32_t chunkIndex, Triangle*& output) {
NVBLAST_ASSERT(mChunkPostprocessors.size() > 0);
if (mChunkPostprocessors.size() == 0)
- {
- return 0; // finalizeFracturing() should be called before getting mesh!
+ {
+ return 0; // finalizeFracturing() should be called before getting mesh!
}
auto& baseMesh = mChunkPostprocessors[chunkIndex]->getBaseMesh();
- output = new Triangle[baseMesh.size()];
+ output = new Triangle[baseMesh.size()];
memcpy(output, baseMesh.data(), baseMesh.size() * sizeof(Triangle));
/* Scale mesh back */
@@ -1690,9 +1730,9 @@ uint32_t FractureToolImpl::getBaseMesh(int32_t chunkIndex, Triangle*& output) for (uint32_t i = 0; i < baseMesh.size(); ++i)
{
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;
+ triangle.a.p = triangle.a.p * mScaleFactor + mOffset;
+ triangle.b.p = triangle.b.p * mScaleFactor + mOffset;
+ triangle.c.p = triangle.c.p * mScaleFactor + mOffset;
}
return baseMesh.size();
@@ -1703,7 +1743,7 @@ uint32_t FractureToolImpl::updateBaseMesh(int32_t chunkIndex, Triangle* output) NVBLAST_ASSERT(mChunkPostprocessors.size() > 0);
if (mChunkPostprocessors.size() == 0)
{
- return 0; // finalizeFracturing() should be called before getting mesh!
+ return 0; // finalizeFracturing() should be called before getting mesh!
}
auto& baseMesh = mChunkPostprocessors[chunkIndex]->getBaseMesh();
memcpy(output, baseMesh.data(), baseMesh.size() * sizeof(Triangle));
@@ -1713,9 +1753,9 @@ uint32_t FractureToolImpl::updateBaseMesh(int32_t chunkIndex, Triangle* output) for (uint32_t i = 0; i < baseMesh.size(); ++i)
{
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;
+ triangle.a.p = triangle.a.p * mScaleFactor + mOffset;
+ triangle.b.p = triangle.b.p * mScaleFactor + mOffset;
+ triangle.c.p = triangle.c.p * mScaleFactor + mOffset;
}
return baseMesh.size();
}
@@ -1727,12 +1767,13 @@ float getVolume(std::vector<Triangle>& triangles) for (uint32_t i = 0; i < triangles.size(); ++i)
{
- PxVec3& a = triangles[i].a.p;
- PxVec3& b = triangles[i].b.p;
- PxVec3& c = triangles[i].c.p;
- 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);
+ NvcVec3& a = triangles[i].a.p;
+ NvcVec3& b = triangles[i].b.p;
+ NvcVec3& c = triangles[i].c.p;
+ 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) * PxAbs(volume);
+ return (1.0f / 6.0f) * std::abs(volume);
}
float FractureToolImpl::getMeshOverlap(const Mesh& meshA, const Mesh& meshB)
@@ -1761,7 +1802,8 @@ float FractureToolImpl::getMeshOverlap(const Mesh& meshA, const Mesh& meshB) return intrsVolume / baseVolume;
}
-void weldVertices(std::map<Vertex, uint32_t, VrtComp>& vertexMapping, std::vector<Vertex>& vertexBuffer, std::vector<uint32_t>& indexBuffer, std::vector<Triangle>& trb)
+void weldVertices(std::map<Vertex, uint32_t, VrtComp>& vertexMapping, std::vector<Vertex>& vertexBuffer,
+ std::vector<uint32_t>& indexBuffer, std::vector<Triangle>& trb)
{
for (uint32_t i = 0; i < trb.size(); ++i)
{
@@ -1799,7 +1841,6 @@ void weldVertices(std::map<Vertex, uint32_t, VrtComp>& vertexMapping, std::vecto indexBuffer.push_back(it->second);
}
}
-
}
void FractureToolImpl::setRemoveIslands(bool isRemoveIslands)
@@ -1819,7 +1860,7 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat Mesh* chunk = mChunkData[chunkIndex].meshData;
- std::vector<uint32_t>& mapping = prc.getBaseMapping();
+ std::vector<uint32_t>& mapping = prc.getBaseMapping();
std::vector<TriangleIndexed>& trs = prc.getBaseMeshIndexed();
std::vector<std::vector<uint32_t> > graph(prc.getWeldedVerticesCount());
@@ -1830,7 +1871,7 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat }
/**
- Chunk graph
+ Chunk graph
*/
for (uint32_t i = 0; i < trs.size(); ++i)
{
@@ -1853,22 +1894,22 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat graph[v1].push_back(v2);
graph[v2].push_back(v1);
-
}
/**
- Walk graph, mark components
+ Walk graph, mark components
*/
std::vector<int32_t> comps(prc.getWeldedVerticesCount(), -1);
std::queue<uint32_t> que;
int32_t cComp = 0;
-
+
for (uint32_t i = 0; i < prc.getWeldedVerticesCount(); ++i)
{
int32_t to = pm[i];
- if (comps[to] != -1) continue;
+ if (comps[to] != -1)
+ continue;
que.push(to);
comps[to] = cComp;
@@ -1876,7 +1917,7 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat {
int32_t c = que.front();
que.pop();
-
+
for (uint32_t j = 0; j < graph[c].size(); ++j)
{
if (comps[graph[c][j]] == -1)
@@ -1891,33 +1932,33 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat for (uint32_t i = 0; i < prc.getWeldedVerticesCount(); ++i)
{
int32_t to = pm[i];
- comps[i] = comps[to];
+ comps[i] = comps[to];
}
std::vector<uint32_t> longComps(chunk->getVerticesCount());
for (uint32_t i = 0; i < chunk->getVerticesCount(); ++i)
{
- int32_t to = mapping[i];
+ int32_t to = mapping[i];
longComps[i] = comps[to];
}
-
+
if (cComp > 1)
{
- std::vector<std::vector<Vertex> > compVertices(cComp);
- std::vector<std::vector<Facet> > compFacets(cComp);
- std::vector<std::vector<Edge> > compEdges(cComp);
+ std::vector<std::vector<Vertex> > compVertices(cComp);
+ std::vector<std::vector<Facet> > compFacets(cComp);
+ std::vector<std::vector<Edge> > compEdges(cComp);
- std::vector<uint32_t> compVertexMapping(chunk->getVerticesCount(), 0);
+ std::vector<uint32_t> compVertexMapping(chunk->getVerticesCount(), 0);
const Vertex* vrts = chunk->getVertices();
for (uint32_t v = 0; v < chunk->getVerticesCount(); ++v)
{
- int32_t vComp = comps[mapping[v]];
+ int32_t vComp = comps[mapping[v]];
compVertexMapping[v] = static_cast<uint32_t>(compVertices[vComp].size());
compVertices[vComp].push_back(vrts[v]);
}
-
+
const Facet* fcb = chunk->getFacetsBuffer();
- const Edge* edb = chunk->getEdges();
+ const Edge* edb = chunk->getEdges();
for (uint32_t fc = 0; fc < chunk->getFacetCount(); ++fc)
{
@@ -1926,7 +1967,7 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat {
int32_t vComp = comps[mapping[edb[ep].s]];
edgesPerComp[vComp]++;
- compEdges[vComp].push_back(Edge(compVertexMapping[edb[ep].s], compVertexMapping[edb[ep].e]));
+ compEdges[vComp].push_back({compVertexMapping[edb[ep].s], compVertexMapping[edb[ep].e]});
}
for (int32_t c = 0; c < cComp; ++c)
{
@@ -1935,7 +1976,7 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat continue;
}
compFacets[c].push_back(*chunk->getFacet(fc));
- compFacets[c].back().edgesCount = edgesPerComp[c];
+ compFacets[c].back().edgesCount = edgesPerComp[c];
compFacets[c].back().firstEdgeNumber = static_cast<int32_t>(compEdges[c].size()) - edgesPerComp[c];
}
}
@@ -1943,50 +1984,57 @@ int32_t FractureToolImpl::islandDetectionAndRemoving(int32_t chunkId, bool creat if (createAtNewDepth == false || chunkId != 0)
{
delete mChunkData[chunkIndex].meshData;
- 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()));;
+ 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 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()));
+ 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()));
}
}
else
- {
+ {
mChunkData[chunkIndex].isLeaf = false;
deleteAllChildrenOfChunk(chunkId);
for (int32_t i = 0; i < cComp; ++i)
{
- uint32_t nc = createNewChunk(chunkId);
- mChunkData[nc].isLeaf = true;
- mChunkData[nc].flags = ChunkInfo::CREATED_BY_ISLAND_DETECTOR;
- mChunkData[nc].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()));
+ uint32_t nc = createNewChunk(chunkId);
+ mChunkData[nc].isLeaf = true;
+ mChunkData[nc].flags = ChunkInfo::CREATED_BY_ISLAND_DETECTOR;
+ mChunkData[nc].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()));
}
- }
+ }
return cComp;
}
return 0;
}
-uint32_t FractureToolImpl::getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t*& indexBuffer,
- uint32_t*& indexBufferOffsets)
+uint32_t
+FractureToolImpl::getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t*& indexBuffer, uint32_t*& indexBufferOffsets)
{
std::map<Vertex, uint32_t, VrtComp> vertexMapping;
std::vector<Vertex> _vertexBuffer;
- std::vector<std::vector<uint32_t>> _indexBuffer(mChunkPostprocessors.size());
-
+ 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);
-
+
indexBufferOffsets[ch] = totalIndices;
totalIndices += _indexBuffer[ch].size();
}
@@ -1998,8 +2046,8 @@ uint32_t FractureToolImpl::getBufferedBaseMeshes(Vertex*& vertexBuffer, uint32_t }
vertexBuffer = new Vertex[_vertexBuffer.size()];
- indexBuffer = new uint32_t[totalIndices];
-
+ indexBuffer = new uint32_t[totalIndices];
+
memcpy(vertexBuffer, _vertexBuffer.data(), _vertexBuffer.size() * sizeof(Vertex));
for (uint32_t ch = 0; ch < _indexBuffer.size(); ++ch)
{
@@ -2035,25 +2083,24 @@ void FractureToolImpl::replaceMaterialId(int32_t oldMaterialId, int32_t newMater }
}
-uint32_t FractureToolImpl::stretchGroup(const std::vector<uint32_t>& grp, std::vector<std::vector<uint32_t>>& graph)
+uint32_t FractureToolImpl::stretchGroup(const std::vector<uint32_t>& grp, std::vector<std::vector<uint32_t> >& graph)
{
- uint32_t parent = mChunkData[grp[0]].parent;
+ uint32_t parent = mChunkData[grp[0]].parent;
uint32_t newChunkIndex = createNewChunk(parent);
graph.push_back(std::vector<uint32_t>());
-
std::vector<Vertex> nVertices;
std::vector<Edge> nEdges;
std::vector<Facet> nFacets;
uint32_t offsetVertices = 0;
- uint32_t offsetEdges = 0;
+ uint32_t offsetEdges = 0;
for (uint32_t i = 0; i < grp.size(); ++i)
{
- mChunkData[grp[i]].parent = mChunkData[newChunkIndex].chunkId;
-
+ mChunkData[grp[i]].parent = mChunkData[newChunkIndex].chunkId;
+
auto vr = mChunkData[grp[i]].meshData->getVertices();
auto ed = mChunkData[grp[i]].meshData->getEdges();
auto fc = mChunkData[grp[i]].meshData->getFacetsBuffer();
@@ -2068,13 +2115,13 @@ uint32_t FractureToolImpl::stretchGroup(const std::vector<uint32_t>& grp, std::v nEdges.push_back(ed[v]);
nEdges.back().s += offsetVertices;
nEdges.back().e += offsetVertices;
- }
+ }
for (uint32_t v = 0; v < mChunkData[grp[i]].meshData->getFacetCount(); ++v)
{
nFacets.push_back(fc[v]);
nFacets.back().firstEdgeNumber += offsetEdges;
}
- offsetEdges = nEdges.size();
+ offsetEdges = nEdges.size();
offsetVertices = nVertices.size();
}
std::vector<Facet> finalFacets;
@@ -2086,24 +2133,27 @@ uint32_t FractureToolImpl::stretchGroup(const std::vector<uint32_t>& grp, std::v }
for (uint32_t i = 0; i < nFacets.size(); ++i)
{
- if (nFacets[i].userData == 0 || (hasCutting.find(-nFacets[i].userData) == hasCutting.end()) || std::abs(nFacets[i].userData) >= SLICING_INDEXER_OFFSET)
+ if (nFacets[i].userData == 0 || (hasCutting.find(-nFacets[i].userData) == hasCutting.end()) ||
+ std::abs(nFacets[i].userData) >= SLICING_INDEXER_OFFSET)
{
finalFacets.push_back(nFacets[i]);
}
}
- mChunkData[newChunkIndex].meshData = new MeshImpl(nVertices.data(), nEdges.data(), finalFacets.data(), static_cast<uint32_t>(nVertices.size()), static_cast<uint32_t>(nEdges.size()), static_cast<uint32_t>(finalFacets.size()));
+ mChunkData[newChunkIndex].meshData =
+ new MeshImpl(nVertices.data(), nEdges.data(), finalFacets.data(), static_cast<uint32_t>(nVertices.size()),
+ static_cast<uint32_t>(nEdges.size()), static_cast<uint32_t>(finalFacets.size()));
return newChunkIndex;
}
uint32_t FractureToolImpl::createNewChunk(uint32_t parent)
{
mChunkData.push_back(ChunkInfo());
- mChunkData.back().parent = parent;
- mChunkData.back().chunkId = mChunkIdCounter++;
- mChunkData.back().meshData = nullptr;
- mChunkData.back().isLeaf = false;
+ mChunkData.back().parent = parent;
+ mChunkData.back().chunkId = mChunkIdCounter++;
+ mChunkData.back().meshData = nullptr;
+ mChunkData.back().isLeaf = false;
mChunkData.back().isChanged = true;
- mChunkData.back().flags = ChunkInfo::NO_FLAGS;
+ mChunkData.back().flags = ChunkInfo::NO_FLAGS;
return mChunkData.size() - 1;
}
@@ -2112,23 +2162,24 @@ uint32_t FractureToolImpl::createNewChunk(uint32_t parent) void FractureToolImpl::fitUvToRect(float side, uint32_t chunk)
{
int32_t index = getChunkIndex(chunk);
- if (mChunkPostprocessors.empty()) // It seems finalize have not been called, call it here.
+ if (mChunkPostprocessors.empty()) // It seems finalize have not been called, call it here.
{
finalizeFracturing();
}
- if (index == -1 || (int32_t)mChunkPostprocessors.size() <= index)
+ if (index == -1 || (int32_t)mChunkPostprocessors.size() <= index)
{
- return; // We dont have such chunk tringulated;
+ return; // We dont have such chunk tringulated;
}
- PxBounds3 bnd;
+ physx::PxBounds3 bnd;
bnd.setEmpty();
-
- std::vector<Triangle>& ctrs = mChunkPostprocessors[index]->getBaseMesh();
+
+ std::vector<Triangle>& ctrs = mChunkPostprocessors[index]->getBaseMesh();
std::vector<Triangle>& output = mChunkPostprocessors[index]->getBaseMesh();
for (uint32_t trn = 0; trn < ctrs.size(); ++trn)
{
- if (ctrs[trn].userData == 0) continue;
+ if (ctrs[trn].userData == 0)
+ continue;
bnd.include(PxVec3(ctrs[trn].a.uv[0].x, ctrs[trn].a.uv[0].y, 0.0f));
bnd.include(PxVec3(ctrs[trn].b.uv[0].x, ctrs[trn].b.uv[0].y, 0.0f));
bnd.include(PxVec3(ctrs[trn].c.uv[0].x, ctrs[trn].c.uv[0].y, 0.0f));
@@ -2136,11 +2187,12 @@ void FractureToolImpl::fitUvToRect(float side, uint32_t chunk) float xscale = side / (bnd.maximum.x - bnd.minimum.x);
float yscale = side / (bnd.maximum.y - bnd.minimum.y);
- xscale = std::min(xscale, yscale); // To have uniform scaling
+ xscale = std::min(xscale, yscale); // To have uniform scaling
for (uint32_t trn = 0; trn < ctrs.size(); ++trn)
{
- if (ctrs[trn].userData == 0) continue;
+ if (ctrs[trn].userData == 0)
+ continue;
output[trn].a.uv[0].x = (ctrs[trn].a.uv[0].x - bnd.minimum.x) * xscale;
output[trn].b.uv[0].x = (ctrs[trn].b.uv[0].x - bnd.minimum.x) * xscale;
output[trn].c.uv[0].x = (ctrs[trn].c.uv[0].x - bnd.minimum.x) * xscale;
@@ -2159,26 +2211,27 @@ void FractureToolImpl::fitAllUvToRect(float side) void FractureToolImpl::fitAllUvToRect(float side, std::set<uint32_t>& mask)
{
- if (mChunkPostprocessors.empty()) // It seems finalize have not been called, call it here.
+ if (mChunkPostprocessors.empty()) // It seems finalize have not been called, call it here.
{
finalizeFracturing();
}
if (mChunkPostprocessors.empty())
{
- return; // We dont have triangulated chunks.
+ return; // We dont have triangulated chunks.
}
- PxBounds3 bnd;
+ physx::PxBounds3 bnd;
bnd.setEmpty();
for (uint32_t chunk = 0; chunk < mChunkData.size(); ++chunk)
{
- Mesh* m = mChunkData[chunk].meshData;
- const Edge* edges = m->getEdges();
+ Mesh* m = mChunkData[chunk].meshData;
+ const Edge* edges = m->getEdges();
const Vertex* vertices = m->getVertices();
for (uint32_t trn = 0; trn < m->getFacetCount(); ++trn)
{
- if (m->getFacet(trn)->userData == 0) continue;
+ if (m->getFacet(trn)->userData == 0)
+ continue;
for (uint32_t ei = 0; ei < m->getFacet(trn)->edgesCount; ++ei)
{
int32_t v1 = edges[m->getFacet(trn)->firstEdgeNumber + ei].s;
@@ -2190,17 +2243,19 @@ void FractureToolImpl::fitAllUvToRect(float side, std::set<uint32_t>& mask) }
float xscale = side / (bnd.maximum.x - bnd.minimum.x);
float yscale = side / (bnd.maximum.y - bnd.minimum.y);
- xscale = std::min(xscale, yscale); // To have uniform scaling
+ xscale = std::min(xscale, yscale); // To have uniform scaling
for (uint32_t chunk = 0; chunk < mChunkPostprocessors.size(); ++chunk)
{
- if (!mask.empty() && mask.find(mChunkPostprocessors[chunk]->getParentChunkId()) == mask.end()) continue;
- std::vector<Triangle>& ctrs = mChunkPostprocessors[chunk]->getBaseMeshNotFitted();
+ if (!mask.empty() && mask.find(mChunkPostprocessors[chunk]->getParentChunkId()) == mask.end())
+ continue;
+ std::vector<Triangle>& ctrs = mChunkPostprocessors[chunk]->getBaseMeshNotFitted();
std::vector<Triangle>& output = mChunkPostprocessors[chunk]->getBaseMesh();
for (uint32_t trn = 0; trn < ctrs.size(); ++trn)
{
- if (ctrs[trn].userData == 0) continue;
+ if (ctrs[trn].userData == 0)
+ continue;
output[trn].a.uv[0].x = (ctrs[trn].a.uv[0].x - bnd.minimum.x) * xscale;
output[trn].b.uv[0].x = (ctrs[trn].b.uv[0].x - bnd.minimum.x) * xscale;
output[trn].c.uv[0].x = (ctrs[trn].c.uv[0].x - bnd.minimum.x) * xscale;
@@ -2213,10 +2268,10 @@ void FractureToolImpl::fitAllUvToRect(float side, std::set<uint32_t>& mask) }
-
-void FractureToolImpl::rebuildAdjGraph(const std::vector<uint32_t>& chunks, std::vector<std::vector<uint32_t> >& chunkGraph)
+void FractureToolImpl::rebuildAdjGraph(const std::vector<uint32_t>& chunks, const NvcVec2i* adjChunks,
+ uint32_t adjChunksSize, std::vector<std::vector<uint32_t> >& chunkGraph)
{
- std::vector<std::pair<uint64_t, uint32_t>> planeChunkIndex;
+ std::vector<std::pair<uint64_t, uint32_t> > planeChunkIndex;
for (uint32_t i = 0; i < chunks.size(); ++i)
{
@@ -2224,7 +2279,8 @@ void FractureToolImpl::rebuildAdjGraph(const std::vector<uint32_t>& chunks, std: {
if (mChunkData[chunks[i]].meshData->getFacet(fc)->userData != 0)
{
- planeChunkIndex.push_back(std::make_pair(std::abs(mChunkData[chunks[i]].meshData->getFacet(fc)->userData), chunks[i]));
+ planeChunkIndex.push_back(
+ std::make_pair(std::abs(mChunkData[chunks[i]].meshData->getFacet(fc)->userData), chunks[i]));
}
}
}
@@ -2246,7 +2302,8 @@ void FractureToolImpl::rebuildAdjGraph(const std::vector<uint32_t>& chunks, std: {
for (uint32_t p2 = p1 + 1; p2 < b; ++p2)
{
- if (planeChunkIndex[p1].second == planeChunkIndex[p2].second || mChunkData[planeChunkIndex[p1].second].parent != mChunkData[planeChunkIndex[p2].second].parent)
+ if (planeChunkIndex[p1].second == planeChunkIndex[p2].second ||
+ mChunkData[planeChunkIndex[p1].second].parent != mChunkData[planeChunkIndex[p2].second].parent)
{
continue;
}
@@ -2281,32 +2338,81 @@ void FractureToolImpl::rebuildAdjGraph(const std::vector<uint32_t>& chunks, std: a = b;
}
}
+
+ // Add in extra adjacency info, if we have it
+ if (adjChunks && adjChunksSize)
+ {
+ std::set<uint32_t> chunkSet(chunks.begin(), chunks.end());
+
+#if NV_DEBUG || NV_CHECKED // Make sure these arrays are sorted
+ for (std::vector<uint32_t>& adj : chunkGraph)
+ {
+ const bool isSorted = std::is_sorted(adj.begin(), adj.end());
+ if (!isSorted)
+ {
+ NVBLAST_ASSERT(0);
+ NvBlastGlobalGetErrorCallback()->reportError(Nv::Blast::ErrorCode::eDEBUG_WARNING, "Adjacency array not sorted; subsequent code assumes it is.", __FILE__, __LINE__);
+ }
+ }
+#endif
+ for (uint32_t i = 0; i < adjChunksSize; ++i)
+ {
+ const NvcVec2i& pair = adjChunks[i];
+ if (chunkSet.find((uint32_t)pair.x) == chunkSet.end() || chunkSet.find((uint32_t)pair.y) == chunkSet.end())
+ {
+ continue;
+ }
+
+ {
+ std::vector<uint32_t>& adj0 = chunkGraph[pair.x];
+ std::vector<uint32_t>::iterator it0 = std::lower_bound(adj0.begin(), adj0.end(), (uint32_t)pair.y);
+ if (it0 == adj0.end() || *it0 != (uint32_t)pair.y)
+ {
+ adj0.insert(it0, (uint32_t)pair.y);
+ }
+ }
+
+ {
+ std::vector<uint32_t>& adj1 = chunkGraph[pair.y];
+ std::vector<uint32_t>::iterator it1 = std::lower_bound(adj1.begin(), adj1.end(), (uint32_t)pair.x);
+ if (it1 == adj1.end() || *it1 != (uint32_t)pair.x)
+ {
+ adj1.insert(it1, (uint32_t)pair.x);
+ }
+ }
+ }
+ }
}
-bool VecIntComp(const std::pair<PxVec3, uint32_t>& a, const std::pair<PxVec3, uint32_t>& b)
+bool VecIntComp(const std::pair<NvcVec3, uint32_t>& a, const std::pair<NvcVec3, uint32_t>& b)
{
- if (a.first.x < b.first.x) return true;
- if (a.first.x > b.first.x) return false;
- if (a.first.y < b.first.y) return true;
- if (a.first.y > b.first.y) return false;
- if (a.first.z < b.first.z) return true;
- if (a.first.z > b.first.z) return false;
+ if (a.first.x < b.first.x)
+ return true;
+ if (a.first.x > b.first.x)
+ return false;
+ if (a.first.y < b.first.y)
+ return true;
+ if (a.first.y > b.first.y)
+ return false;
+ if (a.first.z < b.first.z)
+ return true;
+ if (a.first.z > b.first.z)
+ return false;
return a.second < b.second;
}
-#define MAXIMUM_DEPTH_TO_REARRANGE 255
-
-void FractureToolImpl::uniteChunks(uint32_t maxChunksAtLevel, uint32_t maxGroup)
+void FractureToolImpl::uniteChunks(uint32_t maxChunksAtLevel, uint32_t maxGroup, const NvcVec2i* adjChunks,
+ uint32_t adjChunksSize, bool removeOriginalChunks /*= false*/)
{
maxChunksAtLevel = std::max(maxChunksAtLevel, maxGroup);
std::vector<int32_t> depth(mChunkData.size(), 0);
- std::vector<std::vector<uint32_t>> chunkGraph(mChunkData.size());
+ std::vector<std::vector<uint32_t> > chunkGraph(mChunkData.size());
+
-
- std::vector<uint32_t> atEachDepth(MAXIMUM_DEPTH_TO_REARRANGE, 0); // Probably we will never have 255 depth levels...
+ std::vector<uint32_t> atEachDepth;
std::vector<uint32_t> childNumber(mChunkData.size(), 0);
@@ -2318,40 +2424,52 @@ void FractureToolImpl::uniteChunks(uint32_t maxChunksAtLevel, uint32_t maxGroup) NVBLAST_ASSERT(depth[i] >= 0);
if (depth[i] >= 0)
{
+ if ((size_t)depth[i] >= atEachDepth.size())
+ {
+ atEachDepth.resize(depth[i]+1, 0);
+ }
atEachDepth[depth[i]]++;
}
}
- std::vector<uint32_t> chunkUsage(mChunkData.size(), 0);
- uint32_t chunkUsageFlag = 1;
+ std::vector<uint32_t> chunksToRemove;
- for (int32_t level = MAXIMUM_DEPTH_TO_REARRANGE - 1; level >= 1; --level) // go from leaves to trunk and rebuild hierarchy
- {
- if (atEachDepth[level] < maxChunksAtLevel) continue;
+ std::vector<uint32_t> chunkFlags(mChunkData.size(), 0);
+
+ enum ChunkFlags
+ {
+ ChunkUsage = (1 << 0),
+ MergedChunk = (1 << 1)
+ };
+
+ for (int32_t level = (int32_t)atEachDepth.size(); level--;) // go from leaves to trunk and rebuild hierarchy
+ {
+ if (atEachDepth[level] < maxChunksAtLevel)
+ continue;
std::vector<uint32_t> cGroup;
std::vector<uint32_t> chunksToUnify;
- PxVec3 minPoint(MAXIMUM_EXTENT, MAXIMUM_EXTENT, MAXIMUM_EXTENT);
+ NvcVec3 minPoint = {MAXIMUM_EXTENT, MAXIMUM_EXTENT, MAXIMUM_EXTENT};
VrtPositionComparator posc;
-
+
for (uint32_t ch = 0; ch < depth.size(); ++ch)
{
if (depth[ch] == level && childNumber[getChunkIndex(mChunkData[ch].parent)] > maxChunksAtLevel)
{
chunksToUnify.push_back(ch);
- PxVec3 cp = mChunkData[ch].meshData->getBoundingBox().getCenter();
+ NvcVec3 cp = fromPxShared(toPxShared(mChunkData[ch].meshData->getBoundingBox()).getCenter());
if (posc(cp, minPoint))
{
minPoint = cp;
}
}
- }
+ }
std::vector<std::pair<float, uint32_t> > distances;
for (uint32_t i = 0; i < chunksToUnify.size(); ++i)
{
- float d = (minPoint - mChunkData[chunksToUnify[i]].meshData->getBoundingBox().getCenter()).magnitude();
+ float d = (toPxShared(minPoint) - toPxShared(mChunkData[chunksToUnify[i]].meshData->getBoundingBox()).getCenter()).magnitude();
distances.push_back(std::make_pair(d, chunksToUnify[i]));
}
std::sort(distances.begin(), distances.end());
@@ -2360,8 +2478,8 @@ void FractureToolImpl::uniteChunks(uint32_t maxChunksAtLevel, uint32_t maxGroup) {
chunksToUnify[i] = distances[i].second;
}
- rebuildAdjGraph(chunksToUnify, chunkGraph);
-
+ rebuildAdjGraph(chunksToUnify, adjChunks, adjChunksSize, chunkGraph);
+
for (uint32_t iter = 0; iter < 32 && chunksToUnify.size() > maxChunksAtLevel; ++iter)
{
@@ -2369,26 +2487,35 @@ void FractureToolImpl::uniteChunks(uint32_t maxChunksAtLevel, uint32_t maxGroup) for (uint32_t c = 0; c < chunksToUnify.size(); ++c)
{
- if (chunkUsage[chunksToUnify[c]] == chunkUsageFlag) continue;
+ if (chunkFlags[chunksToUnify[c]] & ChunkUsage)
+ continue;
- chunkUsage[chunksToUnify[c]] = chunkUsageFlag;
+ chunkFlags[chunksToUnify[c]] |= ChunkUsage;
cGroup.push_back(chunksToUnify[c]);
for (uint32_t sc = 0; sc < cGroup.size() && cGroup.size() < maxGroup; ++sc)
{
uint32_t sid = cGroup[sc];
for (uint32_t neighb = 0; neighb < chunkGraph[sid].size() && cGroup.size() < maxGroup; ++neighb)
{
- if (chunkUsage[chunkGraph[sid][neighb]] == chunkUsageFlag) continue;
+ if (chunkFlags[chunkGraph[sid][neighb]] & ChunkUsage)
+ continue;
cGroup.push_back(chunkGraph[sid][neighb]);
- chunkUsage[chunkGraph[sid][neighb]] = chunkUsageFlag;
+ chunkFlags[chunkGraph[sid][neighb]] |= ChunkUsage;
}
}
if (cGroup.size() > 1)
{
uint32_t newChunk = stretchGroup(cGroup, chunkGraph);
+ for (uint32_t chunk : cGroup)
+ {
+ if (removeOriginalChunks && !(chunkFlags[chunk] & MergedChunk))
+ {
+ chunksToRemove.push_back(chunk);
+ }
+ }
cGroup.clear();
newChunksToUnify.push_back(newChunk);
- chunkUsage.push_back(0);
+ chunkFlags.push_back(MergedChunk);
}
else
{
@@ -2396,10 +2523,18 @@ void FractureToolImpl::uniteChunks(uint32_t maxChunksAtLevel, uint32_t maxGroup) }
}
chunksToUnify = newChunksToUnify;
- rebuildAdjGraph(chunksToUnify, chunkGraph);
- }
+ rebuildAdjGraph(chunksToUnify, adjChunks, adjChunksSize, chunkGraph);
+ }
+ }
+
+ for (uint32_t i = (uint32_t)chunksToRemove.size(); i--;)
+ {
+ const uint32_t m = chunksToRemove[i];
+ delete mChunkData[m].meshData;
+ std::swap(mChunkData.back(), mChunkData[m]);
+ mChunkData.pop_back();
}
}
-} // namespace Blast
-} // namespace Nv
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h index fa6aed3..fb3ba37 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h @@ -72,13 +72,13 @@ public: \param[out] Pointer to generated voronoi sites
\return Count of generated voronoi sites.
*/
- uint32_t getVoronoiSites(const physx::PxVec3*& sites) override;
+ uint32_t getVoronoiSites(const NvcVec3*& sites) override;
/**
Add site in particular point
\param[in] site Site coordinates
*/
- void addSite(const physx::PxVec3& site) override;
+ void addSite(const NvcVec3& site) override;
/**
Uniformly generate sites inside the mesh
\param[in] numberOfSites Number of generated sites
@@ -103,7 +103,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) override;
+ void radialPattern(const NvcVec3& center, const NvcVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset = 0.0f, float variability = 0.0f) override;
/**
Generate sites inside sphere
@@ -111,7 +111,7 @@ 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) override;
+ void generateInSphere(const uint32_t count, const float radius, const NvcVec3& center) override;
/**
Set stencil mesh. With stencil mesh sites are generated only inside both of fracture and stencil meshes.
\param[in] stencil Stencil mesh.
@@ -128,10 +128,10 @@ 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) override;
+ void deleteInSphere(const float radius, const NvcVec3& center, const float eraserProbability = 1) override;
private:
- std::vector <physx::PxVec3> mGeneratedSites;
+ std::vector <NvcVec3> mGeneratedSites;
const Mesh* mMesh;
const Mesh* mStencil;
RandomGeneratorBase* mRnd;
@@ -156,7 +156,7 @@ public: mPlaneIndexerOffset = 1;
mChunkIdCounter = 0;
mRemoveIslands = false;
- mInteriorMaterialId = MATERIAL_INTERIOR;
+ mInteriorMaterialId = kMaterialInteriorId;
}
~FractureToolImpl()
@@ -172,7 +172,7 @@ public: void reset() override;
/**
- Set the material id to use for new interior faces. Defaults to MATERIAL_INTERIOR
+ Set the material id to use for new interior faces. Defaults to kMaterialInteriorId
*/
void setInteriorMaterialId(int32_t materialId) override;
@@ -205,7 +205,7 @@ public: 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;
+ void getTransformation(NvcVec3& offset, float& scale) override;
/**
@@ -216,7 +216,7 @@ public: 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;
+ int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const NvcVec3* cellPoints, bool replaceChunk) override;
/**
Fractures specified chunk with voronoi method. Cells can be scaled along x,y,z axes.
@@ -229,7 +229,7 @@ public: 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, const physx::PxQuat& rotation, bool replaceChunk) override;
+ int32_t voronoiFracturing(uint32_t chunkId, uint32_t cellCount, const NvcVec3* cellPoints, const NvcVec3& scale, const NvcQuat& rotation, bool replaceChunk) override;
/**
@@ -257,7 +257,7 @@ public: \return If 0, fracturing is successful.
*/
- int32_t cut(uint32_t chunkId, const physx::PxVec3& normal, const physx::PxVec3& position, const NoiseConfiguration& noise, bool replaceChunk, RandomGeneratorBase* rnd) override;
+ int32_t cut(uint32_t chunkId, const NvcVec3& normal, const NvcVec3& position, const NoiseConfiguration& noise, bool replaceChunk, RandomGeneratorBase* rnd) override;
/**
Cutout fracture for specified chunk.
@@ -375,7 +375,8 @@ public: bool deleteAllChildrenOfChunk(int32_t chunkId) override;
- void uniteChunks(uint32_t maxAtLevel, uint32_t maxGroupSize) override;
+ void uniteChunks(uint32_t maxAtLevel, uint32_t maxGroupSize, const NvcVec2i* adjChunks, uint32_t adjChunksSize,
+ bool removeOriginalChunks = false) override;
/**
@@ -398,7 +399,8 @@ private: bool isAncestorForChunk(int32_t ancestorId, int32_t chunkId);
int32_t slicingNoisy(uint32_t chunkId, const SlicingConfiguration& conf, bool replaceChunk, RandomGeneratorBase* rnd);
uint32_t stretchGroup(const std::vector<uint32_t>& group, std::vector<std::vector<uint32_t>>& graph);
- void rebuildAdjGraph(const std::vector<uint32_t>& chunksToRebuild, std::vector<std::vector<uint32_t> >& chunkGraph);
+ void rebuildAdjGraph(const std::vector<uint32_t>& chunksToRebuild, const NvcVec2i* adjChunks, uint32_t adjChunksSize,
+ std::vector<std::vector<uint32_t> >& chunkGraph);
void fitAllUvToRect(float side, std::set<uint32_t>& mask);
/**
@@ -412,7 +414,7 @@ protected: Mesh scaled to unite-cube and translated to the origin
*/
float mScaleFactor;
- physx::PxVec3 mOffset;
+ NvcVec3 mOffset;
/* Chunk mesh wrappers */
std::vector<Triangulator*> mChunkPostprocessors;
@@ -427,8 +429,8 @@ protected: int32_t mInteriorMaterialId;
};
-void findCellBasePlanes(const std::vector<physx::PxVec3>& sites, std::vector<std::vector<int32_t> >& neighboors);
-Mesh* getCellMesh(class BooleanEvaluator& eval, int32_t planeIndexerOffset, int32_t cellId, const std::vector<physx::PxVec3>& sites, std::vector < std::vector<int32_t> >& neighboors, int32_t interiorMaterialId, physx::PxVec3 origin);
+void findCellBasePlanes(const std::vector<NvcVec3>& sites, std::vector<std::vector<int32_t> >& neighboors);
+Mesh* getCellMesh(class BooleanEvaluator& eval, int32_t planeIndexerOffset, int32_t cellId, const std::vector<NvcVec3>& sites, std::vector < std::vector<int32_t> >& neighboors, int32_t interiorMaterialId, NvcVec3 origin);
} // namespace Blast
} // namespace Nv
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp index ba2bd89..f5bc66c 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp @@ -27,6 +27,7 @@ #include <PxVec3.h>
#include <PxVec2.h>
+#include <PxBounds3.h>
#include <vector>
#include <queue>
#include <map>
@@ -34,27 +35,21 @@ #include <NvBlastExtAuthoringMeshCleanerImpl.h>
#include <NvBlastExtAuthoringMeshImpl.h>
#include <NvBlastExtAuthoringInternalCommon.h>
+#include <NvBlastPxSharedHelpers.h>
#include <boost/multiprecision/cpp_int.hpp>
-
-
-
-using physx::PxVec3;
-using physx::PxVec2;
+using namespace physx;
using namespace Nv::Blast;
using namespace boost::multiprecision;
/**
- Exact rational vector types.
+ Exact rational vector types.
*/
struct RVec3
{
cpp_rational x, y, z;
- RVec3()
- {
-
- }
+ RVec3() {}
bool isZero()
{
@@ -68,7 +63,7 @@ struct RVec3 z = _z;
}
- RVec3(const PxVec3& p)
+ RVec3(const NvcVec3& p)
{
x = cpp_rational(p.x);
y = cpp_rational(p.y);
@@ -76,7 +71,7 @@ struct RVec3 }
PxVec3 toVec3()
{
- return PxVec3(x.convert_to<float>(), y.convert_to<float>(), z.convert_to<float>());
+ return { x.convert_to<float>(), y.convert_to<float>(), z.convert_to<float>() };
}
RVec3 operator-(const RVec3& b) const
@@ -99,17 +94,12 @@ struct RVec3 {
return RVec3(x * in, y * in, z * in);
}
-
-
};
struct RVec2
{
cpp_rational x, y;
- RVec2()
- {
-
- }
+ RVec2() {}
RVec2(cpp_rational _x, cpp_rational _y)
{
@@ -117,14 +107,14 @@ struct RVec2 y = _y;
}
- RVec2(const PxVec2& p)
+ RVec2(const NvcVec2& p)
{
x = cpp_rational(p.x);
y = cpp_rational(p.y);
}
PxVec2 toVec2()
{
- return PxVec2(x.convert_to<float>(), y.convert_to<float>());
+ return { x.convert_to<float>(), y.convert_to<float>() };
}
RVec2 operator-(const RVec2& b) const
@@ -166,15 +156,17 @@ struct RatPlane 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;
+ 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;
+ RVec3 on = a + (b - a) * t;
return on;
}
@@ -196,20 +188,26 @@ int32_t isPointInside(const RVec2& a, const RVec2& b, const RVec2& c, const RVec 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 * 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 && 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;
+ if (v1s == 0)
+ return ON_AB;
+ if (v2s == 0)
+ return ON_BC;
+ if (v3s == 0)
+ return ON_AC;
return INSIDE_TR;
}
@@ -247,41 +245,55 @@ struct DelTriangle 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;
+ 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;
+ 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;
+ 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];
+ 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;
+ 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
@@ -298,19 +310,22 @@ bool isIntersectsTriangle(RVec2& a, RVec2& b, RVec2& c, RVec2& s, RVec2& e) 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 ((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 ((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;
+ if ((s - c).cross(vec2) * (e - c).cross(vec) < 0)
+ return true;
}
return false;
@@ -319,18 +334,21 @@ bool isIntersectsTriangle(RVec2& a, RVec2& b, RVec2& c, RVec2& s, RVec2& e) inline int32_t inCircumcircle(RVec2& a, RVec2& b, RVec2& c, RVec2& p)
{
- RVec2 ta = a - p;
- RVec2 tb = b - p;
- RVec2 tc = c - 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);
+ 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;
+ if (pred > 0)
+ return 1;
+ if (pred < 0)
+ return -1;
return 0;
}
@@ -338,7 +356,8 @@ 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;
+ if (edges[i].s == s && edges[i].e == e)
+ return i;
}
edges.push_back(DelEdge());
@@ -355,15 +374,21 @@ void reubildAdjacency(std::vector<DelTriangle>& state) }
for (uint32_t i = 0; i < state.size(); ++i)
{
- if (state[i].p[0] == -1) continue;
+ if (state[i].p[0] == -1)
+ continue;
for (uint32_t j = i + 1; j < state.size(); ++j)
{
- if (state[j].p[0] == -1) continue;
+ 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; }
+ 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;
+ }
}
}
}
@@ -376,11 +401,13 @@ void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, for (uint32_t i = 0; i < state.size(); ++i)
{
- if (state[i].p[0] == -1) continue;
+ 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]);
+ 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 == OUTSIDE_TR)
+ continue;
if (cv == INSIDE_TR)
{
uint32_t taInd = state.size();
@@ -460,19 +487,23 @@ void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, 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[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;
+ 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 total = 2;
int32_t oppositeTr = 0;
if (state[i].n[cv] != -1)
{
@@ -496,16 +527,20 @@ void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, 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[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;
+ 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];
+ 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;
@@ -529,30 +564,41 @@ void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, int32_t ctrid = triangleToCheck.front();
triangleToCheck.pop();
DelTriangle& ctr = state[ctrid];
- int32_t oppTr = -5;
- int32_t ced = 0;
+ 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;
+ ced = i;
oppTr = ctr.n[i];
break;
}
}
- if (oppTr == -1) continue;
+ 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 ((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;
+ 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)
+ 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)
@@ -575,7 +621,8 @@ void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, 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;
+ 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];
@@ -585,32 +632,35 @@ void insertPoint(std::vector<RVec2>& vertices, std::vector<DelTriangle>& state, 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;
+ 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;
+ 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;
+ 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)
+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;
+ if (pseudo.empty())
+ return;
int32_t c = 0;
if (pseudo.size() > 1)
@@ -645,7 +695,6 @@ void triangulatePseudoPolygon(std::vector<RVec2>& vertices, int32_t ba, int32_t }
-
void insertEdge(std::vector<RVec2>& vertices, std::vector<DelTriangle>& output, int32_t edBeg, int32_t edEnd)
{
bool hasEdge = false;
@@ -657,18 +706,21 @@ void insertEdge(std::vector<RVec2>& vertices, std::vector<DelTriangle>& output, hasEdge = true;
}
}
- if (hasEdge) return;
+ if (hasEdge)
+ return;
int32_t startTriangle = -1;
- int32_t edg = -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] == -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]]))
+ if (edgeIsIntersected(vertices[edBeg], vertices[edEnd], vertices[output[i].p[edg]],
+ vertices[output[i].p[(edg + 1) % 3]]))
{
startTriangle = i;
break;
@@ -699,19 +751,19 @@ void insertEdge(std::vector<RVec2>& vertices, std::vector<DelTriangle>& output, while (1)
{
- DelTriangle& ctr = output[startTriangle];
- int32_t oed = ctr.getEdWP(cvertex);
+ 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;
+ 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 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)
@@ -740,8 +792,8 @@ void insertEdge(std::vector<RVec2>& vertices, std::vector<DelTriangle>& output, }
}
startTriangle = nextTriangle;
- cvertex = nextPoint;
- ctr.p[0] = -1;
+ cvertex = nextPoint;
+ ctr.p[0] = -1;
}
triangulatePseudoPolygon(vertices, edBeg, edEnd, pointsAboveEdge, output);
std::reverse(pointsBelowEdge.begin(), pointsBelowEdge.end());
@@ -750,11 +802,8 @@ void insertEdge(std::vector<RVec2>& vertices, std::vector<DelTriangle>& output, }
-
-
-
-
-void buildCDT(std::vector<RVec3>& vertices, std::vector<Edge>& edges, std::vector<DelTriangle>& output, ProjectionDirections dr)
+void buildCDT(std::vector<RVec3>& vertices, std::vector<Edge>& edges, std::vector<DelTriangle>& output,
+ ProjectionDirections dr)
{
std::vector<DelTriangle> state;
@@ -763,9 +812,9 @@ void buildCDT(std::vector<RVec3>& vertices, std::vector<Edge>& edges, std::vecto for (uint32_t i = 0; i < 3; ++i)
{
- crt.p[i] = edges[i].s;
+ crt.p[i] = edges[i].s;
added[edges[i].s] = true;
- crt.n[i] = -1; // dont have neighboors;
+ crt.n[i] = -1; // dont have neighboors;
}
state.push_back(crt);
@@ -803,9 +852,11 @@ void buildCDT(std::vector<RVec3>& vertices, std::vector<Edge>& edges, std::vecto }
}
-int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, ProjectionDirections dir, std::vector<cpp_rational>& t1v, std::vector<cpp_rational>& t2v);
+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)
+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];
@@ -831,13 +882,15 @@ void getTriangleIntersectionCoplanar(uint32_t tr1, uint32_t tr2, std::vector<std 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));
+ 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));
+ 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)
@@ -896,14 +949,16 @@ void getTriangleIntersectionCoplanar(uint32_t tr1, uint32_t tr2, std::vector<std }
-int32_t getTriangleIntersection3d(uint32_t tr1, uint32_t tr2, std::vector<std::vector<RVec3>>& stencil, ProjectionDirections dr)
+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;
+ if (pl1.n.isZero())
+ return 0;
}
@@ -1013,26 +1068,27 @@ int32_t getTriangleIntersection3d(uint32_t tr1, uint32_t tr2, std::vector<std::v pointOnIntersectionLine = ta0;
}
RVec3 interLineDir = pl1.n.cross(pl2.n);
- cpp_rational sqd = interLineDir.dot(interLineDir);
- if (sqd.is_zero()) return 0;
+ 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 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;
+ 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;
+ t1p2 = (tb1 - pointOnIntersectionLine).dot(interLineDir) / sqd;
cpp_rational t2p2param = t1p2;
if (d2 != d3)
{
@@ -1066,7 +1122,8 @@ int32_t getTriangleIntersection3d(uint32_t tr1, uint32_t tr2, std::vector<std::v 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)
+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);
@@ -1097,7 +1154,6 @@ int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, Projection {
t2v.push_back(t2);
}
-
}
else
{
@@ -1107,8 +1163,10 @@ int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, Projection {
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);
+ if (t1 > 0 && t1 < 1)
+ t1v.push_back(t1);
+ if (t2 > 0 && t2 < 1)
+ t1v.push_back(t2);
}
else
{
@@ -1116,8 +1174,10 @@ int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, Projection {
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 (t1 > 0 && t1 < 1)
+ t1v.push_back(t1);
+ if (t2 > 0 && t2 < 1)
+ t1v.push_back(t2);
}
}
}
@@ -1128,8 +1188,10 @@ int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, Projection {
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);
+ if (t1 > 0 && t1 < 1)
+ t2v.push_back(t1);
+ if (t2 > 0 && t2 < 1)
+ t2v.push_back(t2);
}
else
{
@@ -1137,8 +1199,10 @@ int32_t intersectSegments(RVec3& s1, RVec3& e1, RVec3& s2, RVec3& e2, Projection {
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);
+ if (t1 > 0 && t1 < 1)
+ t2v.push_back(t1);
+ if (t2 > 0 && t2 < 1)
+ t2v.push_back(t2);
}
}
}
@@ -1150,11 +1214,16 @@ 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;
+ 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;
}
};
@@ -1163,10 +1232,10 @@ void getBarycentricCoords(PxVec2& a, PxVec2& b, PxVec2& c, PxVec2& p, float& u, {
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;
+ u = resl.x / resl.z;
+ v = resl.y / resl.z;
}
@@ -1176,20 +1245,20 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) ======= Get mesh data ===========
*/
std::vector<Vertex> vertices;
- std::vector<Edge> edges;
+ std::vector<Edge> edges;
std::vector<Facet> facets;
vertices.resize(mesh->getVerticesCount());
edges.resize(mesh->getEdgesCount());
facets.resize(mesh->getFacetCount());
- PxBounds3 bnd;
+ physx::PxBounds3 bnd;
bnd.setEmpty();
for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i)
{
vertices[i] = mesh->getVertices()[i];
- bnd.include(vertices[i].p);
+ bnd.include(toPxShared(vertices[i].p));
}
for (uint32_t i = 0; i < mesh->getEdgesCount(); ++i)
{
@@ -1202,21 +1271,21 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) //======================================
/**
- Transform vertices to fit unit cube and snap them to grid.
+ 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.
+ 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 = (vertices[i].p - fromPxShared(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<std::vector<RVec3> > triangleStencil(facets.size());
std::vector<PxVec3> facetsNormals(facets.size());
std::vector<PxBounds3> facetBound(facets.size());
@@ -1237,24 +1306,28 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) 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].include(toPxShared(vertices[edges[fed].s].p));
+ facetBound[tr1].include(toPxShared(vertices[edges[fed].e].p));
+ facetBound[tr1].include(toPxShared(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);
+ facetsNormals[tr1] = toPxShared(vertices[edges[fed + 1].s].p - vertices[edges[fed].s].p)
+ .cross(toPxShared(vertices[edges[fed + 2].s].p - vertices[edges[fed].s].p));
}
/**
- Build intersections between all pairs of triangles.
+ Build intersections between all pairs of triangles.
*/
for (uint32_t tr1 = 0; tr1 < facets.size(); ++tr1)
{
- if (triangleStencil[tr1].empty()) continue;
+ 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;
+ if (triangleStencil[tr2].empty())
+ continue;
+ if (facetBound[tr1].intersects(facetBound[tr2]) == false)
+ continue;
getTriangleIntersection3d(tr1, tr2, triangleStencil, getProjectionDirection(facetsNormals[tr1]));
}
@@ -1271,7 +1344,9 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) {
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]);
+ intersectSegments(ctr[sg1], ctr[sg1 + 1], ctr[sg2], ctr[sg2 + 1],
+ getProjectionDirection(facetsNormals[tr]), perSegmentInters[sg1 / 2],
+ perSegmentInters[sg2 / 2]);
}
}
@@ -1295,7 +1370,7 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) {
if (perSegmentInters[csm][j] > current)
{
- current = perSegmentInters[csm][j];
+ current = perSegmentInters[csm][j];
RVec3 pnt = (ctr[i + 1] - ctr[i]) * current + ctr[i];
newStencil.push_back(pnt);
newStencil.push_back(pnt);
@@ -1309,7 +1384,7 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) std::vector<RVec3> finalPoints;
- std::vector<std::vector<Edge>> tsten(facets.size());
+ std::vector<std::vector<Edge> > tsten(facets.size());
{
std::map<RVec3, uint32_t, RVec3Comparer> mapping;
@@ -1318,12 +1393,12 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) for (uint32_t j = 0; j < triangleStencil[tr1].size(); j += 2)
{
- auto it = mapping.find(triangleStencil[tr1][j]);
+ auto it = mapping.find(triangleStencil[tr1][j]);
int32_t pt = 0;
if (it == mapping.end())
{
mapping[triangleStencil[tr1][j]] = finalPoints.size();
- pt = finalPoints.size();
+ pt = finalPoints.size();
finalPoints.push_back(triangleStencil[tr1][j]);
}
else
@@ -1339,14 +1414,14 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) if (it == mapping.end())
{
mapping[triangleStencil[tr1][j + 1]] = finalPoints.size();
- pt = finalPoints.size();
+ pt = finalPoints.size();
finalPoints.push_back(triangleStencil[tr1][j + 1]);
}
else
{
pt = it->second;
}
- newed.e = pt;
+ newed.e = pt;
bool hasNewEdge = false;
for (uint32_t e = 0; e < tsten[tr1].size(); ++e)
{
@@ -1361,19 +1436,21 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) break;
}
}
- if (!hasNewEdge) tsten[tr1].push_back(newed);
+ if (!hasNewEdge)
+ tsten[tr1].push_back(newed);
}
}
}
-
+
/**
- Build constrained DT
+ 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)
+ continue;
if (tsten[i].size() > 3)
{
int32_t oldSize = trs.size();
@@ -1384,18 +1461,17 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) else
{
trs.push_back(DelTriangle());
- trs.back().parentTriangle = i;
+ 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.
+ Remove 'deleted' triangles from array.
*/
{
- std::vector < DelTriangle > trstemp;
+ std::vector<DelTriangle> trstemp;
trstemp.reserve(trs.size());
for (uint32_t i = 0; i < trs.size(); ++i)
{
@@ -1406,7 +1482,7 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) }
/**
- Filter exterior surface
+ Filter exterior surface
*/
std::vector<bool> fillingMask(trs.size(), false);
@@ -1415,19 +1491,20 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) for (uint32_t i = 0; i < trs.size(); ++i)
{
- if (trs[i].p[0] == -1) continue;
+ 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 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
+#endif
for (uint32_t k = 0; k < 3; ++k)
{
int32_t es = trs[i].p[k];
@@ -1436,7 +1513,7 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) {
std::swap(es, ee);
}
- auto pr = std::make_pair(es, ee);
+ auto pr = std::make_pair(es, ee);
auto iter = edgeMap.find(pr);
if (iter == edgeMap.end())
{
@@ -1465,12 +1542,15 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) }
std::queue<int32_t> trque;
- float maxx = -1000;
+ 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 (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;
@@ -1481,11 +1561,11 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) trque.push(best);
while (!trque.empty())
{
- int32_t trid = trque.front();
+ int32_t trid = trque.front();
fillingMask[trid] = true;
- DelTriangle& tr = trs[trque.front()];
+ DelTriangle& tr = trs[trque.front()];
trque.pop();
-
+
for (uint32_t ed = 0; ed < 3; ++ed)
{
auto& tlist = edgeToTriangleMapping[tr.n[ed]];
@@ -1494,7 +1574,8 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) 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)
+ 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;
@@ -1504,34 +1585,37 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) 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);
+ 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);
+ 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);
+ 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);
+ oldDist = normal2.dot(normal2);
bestPath = tlist[k];
- bestDir = newOne;
+ 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)
+ 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;
@@ -1539,17 +1623,16 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) }
edgeToTriangleMapping[tr.n[ed]].clear();
}
-
}
for (uint32_t id = 0; id < trs.size(); ++id)
{
if (!fillingMask[id])
{
- trs[id].p[0] = -1; // Remove triangle
+ trs[id].p[0] = -1; // Remove triangle
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
-
+
std::vector<PxVec3> newVertices;
newVertices.resize(finalPoints.size());
for (uint32_t i = 0; i < finalPoints.size(); ++i)
@@ -1559,7 +1642,7 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) newVertices[i].z = finalPoints[i].z.convert_to<float>();
}
/**
- Rescale mesh to initial coordinates.
+ Rescale mesh to initial coordinates.
*/
for (uint32_t i = 0; i < finalPoints.size(); ++i)
{
@@ -1567,7 +1650,7 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) }
for (uint32_t i = 0; i < vertices.size(); ++i)
{
- vertices[i].p = vertices[i].p * (1.0f / scale) + bnd.minimum;
+ vertices[i].p = vertices[i].p * (1.0f / scale) + fromPxShared(bnd.minimum);
}
std::vector<Triangle> result;
@@ -1580,38 +1663,44 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) {
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]));
+ 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])).toVec2();
}
}
for (uint32_t i = 0; i < trs.size(); ++i)
{
- if (trs[i].p[0] == -1) continue;
- int32_t id = 0;
+ 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().materialId = facets[parentTriangle].materialId;
result.back().smoothingGroup = facets[parentTriangle].smoothingGroup;
- for (auto vert : { &result.back().a, &result.back().b , &result.back().c })
+ 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;
+ toPxShared(vert->p) = newVertices[trs[i].p[id]];
+ PxVec2 p = getProjectedPointWithWinding(vert->p, getProjectionDirection(facetsNormals[parentTriangle])).toVec2();
+ 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
+ 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<NvcVec3> newMeshVertices(result.size() * 3);
+ std::vector<NvcVec3> newMeshNormals(result.size() * 3);
+ std::vector<NvcVec2> newMeshUvs(result.size() * 3);
std::vector<int32_t> newMaterialIds(result.size());
std::vector<int32_t> newSmoothingGroups(result.size());
@@ -1619,12 +1708,12 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) for (uint32_t i = 0; i < result.size(); ++i)
{
- Vertex* arr[3] = { &result[i].a, &result[i].b , &result[i].c };
+ 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];
+ newMeshNormals[i * 3 + k] = arr[k]->n;
+ newMeshUvs[i * 3 + k] = arr[k]->uv[0];
}
}
std::vector<uint32_t> serializedIndices;
@@ -1632,14 +1721,16 @@ Mesh* MeshCleanerImpl::cleanMesh(const Mesh* mesh) int32_t cindex = 0;
for (uint32_t i = 0; i < result.size(); ++i)
{
- newMaterialIds[i] = result[i].materialId;
+ 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()));
+ 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;
@@ -1649,4 +1740,3 @@ void MeshCleanerImpl::release() {
delete this;
}
-
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp index 22e5d4d..5810b9a 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp @@ -38,11 +38,11 @@ #include <set>
#include <queue>
#include <NvBlastAssert.h>
+#include <NvBlastPxSharedHelpers.h>
using namespace Nv::Blast;
using namespace std;
-
void MeshNoiser::computeFalloffAndNormals()
{
// Map newly created vertices according to positions
@@ -73,8 +73,8 @@ void MeshNoiser::computeFalloffAndNormals() {
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];
+ 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);
@@ -89,7 +89,7 @@ void MeshNoiser::computeFalloffAndNormals() 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();
+ float d = mVerticesDistances[curr] + 0.1f; // (mVertices[to].p - mVertices[curr].p).magnitudeSquared();
if (d < mVerticesDistances[to])
{
mVerticesDistances[to] = d;
@@ -100,24 +100,28 @@ void MeshNoiser::computeFalloffAndNormals() for (uint32_t i = 0; i < mVerticesDistances.size(); ++i)
{
- int32_t from = mPositionMappedVrt[i];
- mVerticesDistances[i] = mVerticesDistances[from];
+ int32_t from = mPositionMappedVrt[i];
+ mVerticesDistances[i] = mVerticesDistances[from];
}
}
-bool edgeOverlapTest(PxVec3& as, PxVec3& ae, PxVec3& bs, PxVec3& be)
+bool edgeOverlapTest(NvcVec3& as, NvcVec3& ae, NvcVec3& bs, NvcVec3& 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;
+ // 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 (toPxShared(bs - as).cross(toPxShared(ae - as))).magnitudeSquared() < 1e-6f &&
+ (toPxShared(be - as).cross(toPxShared(ae - as))).magnitudeSquared() < 1e-6f;
}
void MeshNoiser::computePositionedMapping()
{
- std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap;
+ std::map<NvcVec3, int32_t, VrtPositionComparator> mPosMap;
mPositionMappedVrt.clear();
mPositionMappedVrt.resize(mVertices.size());
@@ -128,7 +132,7 @@ void MeshNoiser::computePositionedMapping() if (it == mPosMap.end())
{
mPosMap[mVertices[i].p] = i;
- mPositionMappedVrt[i] = i;
+ mPositionMappedVrt[i] = i;
}
else
{
@@ -138,8 +142,6 @@ void MeshNoiser::computePositionedMapping() }
-
-
void MeshNoiser::relax(int32_t iteration, float factor, std::vector<Vertex>& vertices)
{
std::vector<PxVec3> verticesTemp(vertices.size());
@@ -152,7 +154,7 @@ void MeshNoiser::relax(int32_t iteration, float factor, std::vector<Vertex>& ver {
continue;
}
- PxVec3 cps = vertices[i].p;
+ PxVec3 cps = toPxShared(vertices[i].p);
PxVec3 cns = mVerticesNormalsSmoothed[i];
PxVec3 averaged(0, 0, 0);
PxVec3 averagedNormal(0, 0, 0);
@@ -160,14 +162,13 @@ void MeshNoiser::relax(int32_t iteration, float factor, std::vector<Vertex>& ver for (uint32_t p = 0; p < mGeometryGraph[mPositionMappedVrt[i]].size(); ++p)
{
int32_t to = mGeometryGraph[mPositionMappedVrt[i]][p];
- averaged += vertices[to].p;
+ averaged += toPxShared(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;
+ normalsTemp[i] = cns * (1.0f - factor) + averagedNormal * factor;
}
for (uint32_t i = 0; i < vertices.size(); ++i)
{
@@ -175,15 +176,14 @@ void MeshNoiser::relax(int32_t iteration, float factor, std::vector<Vertex>& ver {
continue;
}
- vertices[i].p = verticesTemp[i];
+ vertices[i].p = fromPxShared(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)
+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)
{
@@ -227,7 +227,7 @@ void MeshNoiser::prebuildEdgeFlagArray() mEdgeFlag.clear();
mEdgeFlag.resize(mEdges.size(), NONE);
- std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap;
+ std::map<NvcVec3, int32_t, VrtPositionComparator> mPosMap;
mPositionMappedVrt.clear();
mPositionMappedVrt.resize(mVertices.size(), 0);
@@ -238,7 +238,7 @@ void MeshNoiser::prebuildEdgeFlagArray() if (it == mPosMap.end())
{
mPosMap[mVertices[i].p] = i;
- mPositionMappedVrt[i] = i;
+ mPositionMappedVrt[i] = i;
}
else
{
@@ -252,12 +252,13 @@ void MeshNoiser::prebuildEdgeFlagArray() 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);
+ Edge tmp = { 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;
+ mPositionEdgeMap[tmp] = i;
mPositionBasedEdges[i] = i;
}
else
@@ -278,7 +279,7 @@ void MeshNoiser::prebuildEdgeFlagArray() {
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);
@@ -289,29 +290,28 @@ void MeshNoiser::prebuildEdgeFlagArray() 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))];
+ int32_t ed = mPositionBasedEdges[findEdge({ 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))];
+ ed = mPositionBasedEdges[findEdge({ 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))];
+ ed = mPositionBasedEdges[findEdge({ 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)
@@ -321,20 +321,19 @@ void MeshNoiser::prebuildEdgeFlagArray() for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
- if (mTriangles[i].userData != 0) continue;
+ if (mTriangles[i].userData != 0)
+ continue;
- int32_t ed = findEdge(Edge(mTriangles[i].ea, mTriangles[i].eb));
+ int32_t ed = findEdge({ mTriangles[i].ea, mTriangles[i].eb });
mEdgeFlag[ed] = EXTERNAL_EDGE;
- ed = findEdge(Edge(mTriangles[i].ec, mTriangles[i].eb));
+ ed = findEdge({ mTriangles[i].ec, mTriangles[i].eb });
mEdgeFlag[ed] = EXTERNAL_EDGE;
- ed = findEdge(Edge(mTriangles[i].ea, mTriangles[i].ec));
+ ed = findEdge({ 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);
@@ -353,7 +352,8 @@ NV_FORCE_INLINE int32_t MeshNoiser::addVerticeIfNotExist(const Vertex& p) NV_FORCE_INLINE int32_t MeshNoiser::addEdge(const Edge& e)
{
Edge ed = e;
- if (ed.e < ed.s) std::swap(ed.s, ed.e);
+ if (ed.e < ed.s)
+ std::swap(ed.s, ed.e);
auto it = mEdgeMap.find(ed);
if (it == mEdgeMap.end())
{
@@ -372,7 +372,8 @@ NV_FORCE_INLINE int32_t MeshNoiser::addEdge(const Edge& e) NV_FORCE_INLINE int32_t MeshNoiser::findEdge(const Edge& e)
{
Edge ed = e;
- if (ed.e < ed.s) std::swap(ed.s, ed.e);
+ if (ed.e < ed.s)
+ std::swap(ed.s, ed.e);
auto it = mEdgeMap.find(ed);
if (it == mEdgeMap.end())
{
@@ -386,38 +387,37 @@ NV_FORCE_INLINE int32_t MeshNoiser::findEdge(const Edge& e) /**
- Weld input vertices, build edge and triangle buffers
+ Weld input vertices, build edge and triangle buffers
*/
void MeshNoiser::setMesh(const vector<Triangle>& mesh)
{
uint32_t a, b, c;
- PxBounds3 box;
+ physx::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;
+ a = addVerticeIfNotExist(tr.a);
+ b = addVerticeIfNotExist(tr.b);
+ c = addVerticeIfNotExist(tr.c);
+ box.include(toPxShared(tr.a.p));
+ box.include(toPxShared(tr.b.p));
+ box.include(toPxShared(tr.c.p));
+ addEdge({ a, b });
+ addEdge({ b, c });
+ addEdge({ a, c });
+ mTriangles.push_back({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)));
+ 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;
+ mVertices[i].p = mVertices[i].p - fromPxShared(box.getCenter());
+ mVertices[i].p = mVertices[i].p * invScale;
}
}
@@ -441,41 +441,41 @@ void MeshNoiser::tesselateInternalSurface(float maxLenIn) }
}
-
- float maxLen = maxLenIn;
- float mlSq = maxLen * maxLen;
- float minD = maxLen * 0.5f;
- minD = minD * minD;
-
- for (int32_t iter = 0; iter < 15; ++iter)
+
+ 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)
{
- 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)
{
- 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);
- }
+ continue;
}
- oldSize = (uint32_t)mEdges.size();
- updateEdgeTriangleInfo();
- for (uint32_t i = 0; i < oldSize; ++i)
+ if (toPxShared(mVertices[mEdges[i].s].p - mVertices[mEdges[i].e].p).magnitudeSquared() < minD)
{
- if (mEdgeFlag[i] == EXTERNAL_EDGE)
- {
- continue;
- }
- if ((mVertices[mEdges[i].s].p - mVertices[mEdges[i].e].p).magnitudeSquared() > mlSq)
- {
- divideEdge(i);
- }
+ collapseEdge(i);
+ }
+ }
+ oldSize = (uint32_t)mEdges.size();
+ updateEdgeTriangleInfo();
+ for (uint32_t i = 0; i < oldSize; ++i)
+ {
+ if (mEdgeFlag[i] == EXTERNAL_EDGE)
+ {
+ continue;
+ }
+ if (toPxShared(mVertices[mEdges[i].s].p - mVertices[mEdges[i].e].p).magnitudeSquared() > mlSq)
+ {
+ divideEdge(i);
}
}
+ }
computeFalloffAndNormals();
prebuildTesselatedTriangles();
isTesselated = true;
@@ -488,13 +488,13 @@ void MeshNoiser::updateEdgeTriangleInfo() for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
TriangleIndexed& tr = mTriangles[i];
- if (tr.ea == NOT_VALID_VERTEX)
+ if (tr.ea == kNotValidVertexIndex)
continue;
- int32_t ed = addEdge(Edge(tr.ea, tr.eb));
+ int32_t ed = addEdge({ tr.ea, tr.eb });
mTrMeshEdToTr[ed].add(i);
- ed = addEdge(Edge(tr.ea, tr.ec));
+ ed = addEdge({ tr.ea, tr.ec });
mTrMeshEdToTr[ed].add(i);
- ed = addEdge(Edge(tr.ec, tr.eb));
+ ed = addEdge({ tr.ec, tr.eb });
mTrMeshEdToTr[ed].add(i);
}
}
@@ -506,7 +506,8 @@ void MeshNoiser::updateVertEdgeInfo() for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
TriangleIndexed& tr = mTriangles[i];
- if (tr.ea == NOT_VALID_VERTEX) continue;
+ if (tr.ea == kNotValidVertexIndex)
+ continue;
mVertexToTriangleMap[tr.ea].push_back(i);
mVertexToTriangleMap[tr.eb].push_back(i);
mVertexToTriangleMap[tr.ec].push_back(i);
@@ -523,19 +524,22 @@ void MeshNoiser::updateVertEdgeInfo() }
}
}
-
+inline bool isContainEdge(const TriangleIndexed& t, uint32_t a, uint32_t b)
+{
+ return (a == t.ea || a == t.eb || a == t.ec) && (b == t.ea || b == t.eb || b == t.ec);
+}
void MeshNoiser::collapseEdge(int32_t id)
{
- Edge cEdge = mEdges[id];
+ Edge cEdge = mEdges[id];
uint32_t from = cEdge.s;
- uint32_t to = cEdge.e;
+ uint32_t to = cEdge.e;
if (mRestrictionFlag[from] && mRestrictionFlag[to])
{
return;
}
-
+
if (mVertexValence[from] > mVertexValence[to])
{
std::swap(from, to);
@@ -550,13 +554,14 @@ void MeshNoiser::collapseEdge(int32_t id) std::set<int32_t> connectedToEnd;
std::set<int32_t> neighboorTriangles;
- int32_t trWithEdge[2] = {-1, -1};
- int32_t cntr = 0;
+ 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)
+ if (mTriangles[mVertexToTriangleMap[from][i]].ea == kNotValidVertexIndex)
continue;
- if (neighboorTriangles.insert(mVertexToTriangleMap[from][i]).second && mTriangles[mVertexToTriangleMap[from][i]].isContainEdge(from, to))
+ if (neighboorTriangles.insert(mVertexToTriangleMap[from][i]).second &&
+ isContainEdge(mTriangles[mVertexToTriangleMap[from][i]] , from, to))
{
trWithEdge[cntr] = mVertexToTriangleMap[from][i];
cntr++;
@@ -564,9 +569,10 @@ void MeshNoiser::collapseEdge(int32_t id) }
for (uint32_t i = 0; i < mVertexToTriangleMap[to].size(); ++i)
{
- if (mTriangles[mVertexToTriangleMap[to][i]].ea == NOT_VALID_VERTEX)
+ if (mTriangles[mVertexToTriangleMap[to][i]].ea == kNotValidVertexIndex)
continue;
- if (neighboorTriangles.insert(mVertexToTriangleMap[to][i]).second && mTriangles[mVertexToTriangleMap[to][i]].isContainEdge(from, to))
+ if (neighboorTriangles.insert(mVertexToTriangleMap[to][i]).second &&
+ isContainEdge(mTriangles[mVertexToTriangleMap[to][i]], from, to))
{
trWithEdge[cntr] = mVertexToTriangleMap[to][i];
cntr++;
@@ -582,7 +588,7 @@ void MeshNoiser::collapseEdge(int32_t id) return;
}
- for (uint32_t i: neighboorTriangles)
+ for (uint32_t i : neighboorTriangles)
{
if (mTriangles[i].ea == from || mTriangles[i].eb == from || mTriangles[i].ec == from)
{
@@ -614,10 +620,10 @@ void MeshNoiser::collapseEdge(int32_t id) 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))
+ (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;
+ found = true;
break;
}
}
@@ -631,26 +637,28 @@ void MeshNoiser::collapseEdge(int32_t id) {
for (int32_t i : neighboorTriangles)
{
- if (trWithEdge[0] == i) continue;
- if (cntr == 2 && trWithEdge[1] == i) continue;
+ 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);
+ PxVec3 oldNormal =
+ toPxShared(mVertices[tr.eb].p - mVertices[tr.ea].p).cross(toPxShared(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);
+ else if (tr.eb == from)
+ {
+ tr.eb = to;
+ }
+ else if (tr.ec == from)
+ {
+ tr.ec = to;
+ }
+ PxVec3 newNormal =
+ toPxShared(mVertices[tr.eb].p - mVertices[tr.ea].p).cross(toPxShared(mVertices[tr.ec].p - mVertices[tr.ea].p));
if (newNormal.magnitude() < 1e-8f)
{
canBeCollapsed = false;
@@ -662,12 +670,13 @@ void MeshNoiser::collapseEdge(int32_t id) break;
}
}
- mTriangles[trWithEdge[0]].ea = NOT_VALID_VERTEX;
- if (cntr == 2)mTriangles[trWithEdge[1]].ea = NOT_VALID_VERTEX;
+ mTriangles[trWithEdge[0]].ea = kNotValidVertexIndex;
+ if (cntr == 2)
+ mTriangles[trWithEdge[1]].ea = kNotValidVertexIndex;
for (int32_t i : neighboorTriangles)
{
- if (mTriangles[i].ea == NOT_VALID_VERTEX)
+ if (mTriangles[i].ea == kNotValidVertexIndex)
continue;
if (mTriangles[i].ea == from)
{
@@ -675,15 +684,13 @@ void MeshNoiser::collapseEdge(int32_t id) mVertexToTriangleMap[from].clear();
mVertexToTriangleMap[to].push_back(i);
}
- else
- if (mTriangles[i].eb == from)
+ else if (mTriangles[i].eb == from)
{
mTriangles[i].eb = to;
mVertexToTriangleMap[from].clear();
mVertexToTriangleMap[to].push_back(i);
}
- else
- if (mTriangles[i].ec == from)
+ else if (mTriangles[i].ec == from)
{
mTriangles[i].ec = to;
mVertexToTriangleMap[from].clear();
@@ -697,21 +704,21 @@ void MeshNoiser::collapseEdge(int32_t id) void MeshNoiser::divideEdge(int32_t id)
{
- if (mTrMeshEdToTr[id].c == 0 )
+ if (mTrMeshEdToTr[id].c == 0)
{
return;
}
- Edge cEdge = mEdges[id];
+ Edge cEdge = mEdges[id];
EdgeFlag snapRestriction = mEdgeFlag[id];
Vertex middle;
- uint32_t nv = NOT_VALID_VERTEX;
+ uint32_t nv = kNotValidVertexIndex;
for (int32_t t = 0; t < mTrMeshEdToTr[id].c; ++t)
{
int32_t oldTriangleIndex = mTrMeshEdToTr[id].tr[t];
- TriangleIndexed tr = mTriangles[mTrMeshEdToTr[id].tr[t]];
+ TriangleIndexed tr = mTriangles[mTrMeshEdToTr[id].tr[t]];
- if (tr.ea == NOT_VALID_VERTEX)
+ if (tr.ea == kNotValidVertexIndex)
{
continue;
}
@@ -719,7 +726,7 @@ void MeshNoiser::divideEdge(int32_t id) uint32_t pbf[3];
pbf[0] = tr.ea;
pbf[1] = tr.eb;
- pbf[2] = tr.ec;
+ pbf[2] = tr.ec;
for (int32_t p = 0; p < 3; ++p)
{
int32_t pnx = (p + 1) % 3;
@@ -727,10 +734,10 @@ void MeshNoiser::divideEdge(int32_t id) if ((pbf[p] == cEdge.s && pbf[pnx] == cEdge.e) || (pbf[p] == cEdge.e && pbf[pnx] == cEdge.s))
{
- if (nv == NOT_VALID_VERTEX)
+ if (nv == kNotValidVertexIndex)
{
- 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.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();
@@ -738,40 +745,42 @@ void MeshNoiser::divideEdge(int32_t id) }
if (nv < mRestrictionFlag.size())
{
- mRestrictionFlag[nv] = ((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE));
+ mRestrictionFlag[nv] =
+ ((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE));
}
else
{
- mRestrictionFlag.push_back((snapRestriction == EXTERNAL_BORDER_EDGE) || (snapRestriction == INTERNAL_BORDER_EDGE));
+ 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]));
-
+ uint32_t ind1 = addEdge({ pbf[p], nv });
+ uint32_t ind2 = addEdge({ nv, pbf[pnx] });
+ uint32_t ind3 = addEdge({ 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;
- int32_t smId = mTriangles[mTrMeshEdToTr[id].tr[t]].smoothingGroup;
- 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;
+ int32_t userInfo = mTriangles[mTrMeshEdToTr[id].tr[t]].userData;
+ int32_t matId = mTriangles[mTrMeshEdToTr[id].tr[t]].materialId;
+ int32_t smId = mTriangles[mTrMeshEdToTr[id].tr[t]].smoothingGroup;
+ mTriangles[mTrMeshEdToTr[id].tr[t]] = {pbf[p], nv, pbf[opp]};
+ mTriangles[mTrMeshEdToTr[id].tr[t]].userData = userInfo;
+ mTriangles[mTrMeshEdToTr[id].tr[t]].materialId = matId;
mTriangles[mTrMeshEdToTr[id].tr[t]].smoothingGroup = smId;
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;
+ mTriangles.push_back({nv, pbf[pnx], pbf[opp]});
+ mTriangles.back().userData = userInfo;
+ mTriangles.back().materialId = matId;
mTriangles.back().smoothingGroup = smId;
- int32_t ed1 = findEdge(Edge(pbf[pnx], pbf[opp]));
+ int32_t ed1 = findEdge({ pbf[pnx], pbf[opp] });
mTrMeshEdToTr[ed1].replace(oldTriangleIndex, (int32_t)mTriangles.size() - 1);
break;
}
@@ -783,40 +792,40 @@ void MeshNoiser::divideEdge(int32_t id) float falloffFunction(float x, float mx)
{
float t = (x) / (mx + 1e-6f);
- t = std::min(1.0f, t);
+ t = std::min(1.0f, t);
return t * t;
}
void MeshNoiser::recalcNoiseDirs()
{
/**
- Compute normals direction to apply noise
+ 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)
+ if (mTriangles[i].ea == kNotValidVertexIndex)
{
continue;
}
TriangleIndexed& tr = mTriangles[i];
- if (tr.userData == 0) continue;
-
+ if (tr.userData == 0)
+ continue;
+
if (tr.userData < 0)
- mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += mVertices[tr.ea].n.getNormalized();
+ mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += toPxShared(mVertices[tr.ea].n).getNormalized();
else
- mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] -= mVertices[tr.ea].n.getNormalized();
+ mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] -= toPxShared(mVertices[tr.ea].n).getNormalized();
if (tr.userData < 0)
- mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += mVertices[tr.eb].n.getNormalized();
+ mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += toPxShared(mVertices[tr.eb].n).getNormalized();
else
- mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] -= mVertices[tr.eb].n.getNormalized();
+ mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] -= toPxShared(mVertices[tr.eb].n).getNormalized();
if (tr.userData < 0)
- mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] += mVertices[tr.ec].n.getNormalized();
+ mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] += toPxShared(mVertices[tr.ec].n).getNormalized();
else
- mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] -= mVertices[tr.ec].n.getNormalized();
-
+ mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]] -= toPxShared(mVertices[tr.ec].n).getNormalized();
}
for (uint32_t i = 0; i < mVerticesNormalsSmoothed.size(); ++i)
{
@@ -827,7 +836,6 @@ void MeshNoiser::recalcNoiseDirs() }
-
void MeshNoiser::applyNoise(SimplexNoise& noise, float falloff, int32_t /*relaxIterations*/, float /*relaxFactor*/)
{
NVBLAST_ASSERT(isTesselated);
@@ -850,14 +858,14 @@ void MeshNoiser::applyNoise(SimplexNoise& noise, float falloff, int32_t /*relaxI }
}
std::vector<Vertex> localVertices = mVertices;
-
+
recalcNoiseDirs();
- //relax(relaxIterations, relaxFactor, localVertices);
-
+ // relax(relaxIterations, relaxFactor, localVertices);
- /**
- Apply noise
+
+ /**
+ Apply noise
*/
for (uint32_t i = 0; i < localVertices.size(); ++i)
{
@@ -865,8 +873,9 @@ void MeshNoiser::applyNoise(SimplexNoise& noise, float falloff, int32_t /*relaxI if (!mRestrictionFlag[i])
{
- float d = noise.sample(localVertices[i].p);
- localVertices[i].p += (falloffFunction(mVerticesDistances[i], falloff)) * mVerticesNormalsSmoothed[i] * d;
+ float d = noise.sample(toPxShared(localVertices[i].p));
+ toPxShared(localVertices[i].p) +=
+ (falloffFunction(mVerticesDistances[i], falloff)) * mVerticesNormalsSmoothed[i] * d;
}
}
@@ -875,15 +884,16 @@ void MeshNoiser::applyNoise(SimplexNoise& noise, float falloff, int32_t /*relaxI mVerticesNormalsSmoothed.assign(mVerticesNormalsSmoothed.size(), PxVec3(0, 0, 0));
for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
- if (mTriangles[i].ea == NOT_VALID_VERTEX)
+ if (mTriangles[i].ea == kNotValidVertexIndex)
{
continue;
}
TriangleIndexed& tr = mTriangles[i];
- if (tr.userData == 0) continue;
+ if (tr.userData == 0)
+ continue;
Triangle pTr(localVertices[tr.ea], localVertices[tr.eb], localVertices[tr.ec]);
- PxVec3 nrm = pTr.getNormal().getNormalized();
+ PxVec3 nrm = toPxShared(pTr.b.p - pTr.a.p).cross(toPxShared(pTr.c.p - pTr.a.p)).getNormalized();
mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]] += nrm;
mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]] += nrm;
@@ -896,30 +906,29 @@ void MeshNoiser::applyNoise(SimplexNoise& noise, float falloff, int32_t /*relaxI }
for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
- if (mTriangles[i].ea == NOT_VALID_VERTEX)
+ if (mTriangles[i].ea == kNotValidVertexIndex)
{
continue;
}
TriangleIndexed& tr = mTriangles[i];
- if (tr.userData == 0) continue;
+ 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]];
+ localVertices[tr.ea].n = fromPxShared(mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ea]]);
+ localVertices[tr.eb].n = fromPxShared(mVerticesNormalsSmoothed[mPositionMappedVrt[tr.eb]]);
+ localVertices[tr.ec].n = fromPxShared(mVerticesNormalsSmoothed[mPositionMappedVrt[tr.ec]]);
}
mResultTriangles.clear();
for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
- if (mTriangles[i].ea == NOT_VALID_VERTEX)
+ if (mTriangles[i].ea == kNotValidVertexIndex)
{
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;
-
+ mResultTriangles.push_back({ localVertices[mTriangles[i].ea], localVertices[mTriangles[i].eb],
+ localVertices[mTriangles[i].ec], mTriangles[i].userData, mTriangles[i].materialId,
+ mTriangles[i].smoothingGroup });
}
}
@@ -930,22 +939,18 @@ void MeshNoiser::prebuildTesselatedTriangles() for (uint32_t i = 0; i < mVertices.size(); ++i)
{
- mVertices[i].p = mVertices[i].p * mScale + mOffset;
+ mVertices[i].p = mVertices[i].p * mScale + fromPxShared(mOffset);
}
for (uint32_t i = 0; i < mTriangles.size(); ++i)
{
- if (mTriangles[i].ea == NOT_VALID_VERTEX)
+ if (mTriangles[i].ea == kNotValidVertexIndex)
{
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;
-
+ mResultTriangles.push_back({ mVertices[mTriangles[i].ea], mVertices[mTriangles[i].eb], mVertices[mTriangles[i].ec],
+ mTriangles[i].userData, mTriangles[i].materialId, mTriangles[i].smoothingGroup });
}
-
}
@@ -962,7 +967,7 @@ void MeshNoiser::reset() mEdges.clear();
mVertMap.clear();
mEdgeMap.clear();
- mResultTriangles.clear();
+ mResultTriangles.clear();
mRestrictionFlag.clear();
mEdgeFlag.clear();
mTrMeshEdToTr.clear();
@@ -975,6 +980,6 @@ void MeshNoiser::reset() mGeometryGraph.clear();
isTesselated = false;
- mOffset = PxVec3(0, 0, 0);
- mScale = 1.0f;
+ 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 index 8e37b01..4fced5a 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h @@ -135,7 +135,7 @@ namespace Nv std::vector<Triangle> getMesh();
private:
- PxVec3 mOffset;
+ physx::PxVec3 mOffset;
float mScale;
bool isTesselated;
/**
@@ -178,7 +178,7 @@ namespace Nv std::vector<float> mVerticesDistances;
std::vector<physx::PxVec3> mVerticesNormalsSmoothed;
- std::vector<int32_t> mPositionMappedVrt;
+ std::vector<uint32_t> mPositionMappedVrt;
std::vector<std::vector<int32_t> > mGeometryGraph;
void prebuildEdgeFlagArray();
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp index e8a9a24..ffcbd0b 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp @@ -1,8 +1,8 @@ #include "NvBlastExtAuthoringMeshUtils.h" -#include "PxVec3.h" #include "NvBlastExtAuthoringMeshImpl.h" #include "NvBlastExtAuthoringPerlinNoise.h" #include "NvBlastExtAuthoringFractureTool.h" +#include <NvBlastPxSharedHelpers.h> #include <algorithm> @@ -10,932 +10,964 @@ using namespace physx; #define UV_SCALE 1.f -#define CYLINDER_UV_SCALE (UV_SCALE * 1.732) +#define CYLINDER_UV_SCALE (UV_SCALE * 1.732f) namespace Nv { - namespace Blast +namespace Blast +{ + +void getTangents(const PxVec3& normal, PxVec3& t1, PxVec3& t2) +{ + + if (std::abs(normal.z) < 0.9) { - - void getTangents(const PxVec3& normal, PxVec3& t1, PxVec3& t2) - { + t1 = normal.cross(PxVec3(0, 0, 1)); + } + else + { + t1 = normal.cross(PxVec3(1, 0, 0)); + } + t2 = t1.cross(normal); +} - if (std::abs(normal.z) < 0.9) - { - t1 = normal.cross(PxVec3(0, 0, 1)); - } - else - { - t1 = normal.cross(PxVec3(1, 0, 0)); - } - t2 = t1.cross(normal); - } +Mesh* getCuttingBox(const PxVec3& point, const PxVec3& normal, float size, int64_t id, int32_t interiorMaterialId) +{ + PxVec3 lNormal = normal.getNormalized(); + PxVec3 t1, t2; + getTangents(lNormal, t1, t2); - Mesh* getCuttingBox(const PxVec3& point, const PxVec3& normal, float size, int64_t id, int32_t interiorMaterialId) - { - PxVec3 lNormal = normal.getNormalized(); - PxVec3 t1, t2; - getTangents(lNormal, t1, t2); + std::vector<Vertex> positions(8); + toPxShared(positions[0].p) = point + (t1 + t2) * size; + toPxShared(positions[1].p) = point + (t2 - t1) * size; - std::vector<Vertex> positions(8); - positions[0].p = point + (t1 + t2) * size; - positions[1].p = point + (t2 - t1) * size; + toPxShared(positions[2].p) = point + (-t1 - t2) * size; + toPxShared(positions[3].p) = point + (t1 - t2) * size; - positions[2].p = point + (-t1 - t2) * size; - positions[3].p = point + (t1 - t2) * size; + toPxShared(positions[4].p) = point + (t1 + t2 + lNormal) * size; + toPxShared(positions[5].p) = point + (t2 - t1 + lNormal) * size; - positions[4].p = point + (t1 + t2 + lNormal) * size; - positions[5].p = point + (t2 - t1 + lNormal) * size; + toPxShared(positions[6].p) = point + (-t1 - t2 + lNormal) * size; + toPxShared(positions[7].p) = point + (t1 - t2 + lNormal) * size; - positions[6].p = point + (-t1 - t2 + lNormal) * size; - positions[7].p = point + (t1 - t2 + lNormal) * size; + toPxShared(positions[0].n) = -lNormal; + toPxShared(positions[1].n) = -lNormal; - positions[0].n = -lNormal; - positions[1].n = -lNormal; + toPxShared(positions[2].n) = -lNormal; + toPxShared(positions[3].n) = -lNormal; - positions[2].n = -lNormal; - positions[3].n = -lNormal; + toPxShared(positions[4].n) = -lNormal; + toPxShared(positions[5].n) = -lNormal; - positions[4].n = -lNormal; - positions[5].n = -lNormal; + toPxShared(positions[6].n) = -lNormal; + toPxShared(positions[7].n) = -lNormal; - positions[6].n = -lNormal; - positions[7].n = -lNormal; + positions[0].uv[0] = { 0, 0 }; + positions[1].uv[0] = {UV_SCALE, 0}; - positions[0].uv[0] = PxVec2(0, 0); - positions[1].uv[0] = PxVec2(UV_SCALE, 0); + positions[2].uv[0] = {UV_SCALE, UV_SCALE}; + positions[3].uv[0] = {0, UV_SCALE}; - positions[2].uv[0] = PxVec2(UV_SCALE, UV_SCALE); - positions[3].uv[0] = PxVec2(0, UV_SCALE); + positions[4].uv[0] = {0, 0}; + positions[5].uv[0] = {UV_SCALE, 0}; - positions[4].uv[0] = PxVec2(0, 0); - positions[5].uv[0] = PxVec2(UV_SCALE, 0); + positions[6].uv[0] = {UV_SCALE, UV_SCALE}; + positions[7].uv[0] = {0, UV_SCALE}; - positions[6].uv[0] = PxVec2(UV_SCALE, UV_SCALE); - positions[7].uv[0] = PxVec2(0, UV_SCALE); + std::vector<Edge> edges; + std::vector<Facet> facets; - std::vector<Edge> edges; - std::vector<Facet> facets; + edges.push_back({0, 1}); + edges.push_back({1, 2}); + edges.push_back({2, 3}); + edges.push_back({3, 0}); + facets.push_back({0, 4, id, interiorMaterialId, -1}); - edges.push_back(Edge(0, 1)); - edges.push_back(Edge(1, 2)); - edges.push_back(Edge(2, 3)); - edges.push_back(Edge(3, 0)); - facets.push_back(Facet(0, 4, interiorMaterialId, id, -1)); + edges.push_back({0, 3}); + edges.push_back({3, 7}); + edges.push_back({7, 4}); + edges.push_back({4, 0}); + facets.push_back({4, 4, id, interiorMaterialId, -1}); - 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, interiorMaterialId, id, -1)); + edges.push_back({3, 2}); + edges.push_back({2, 6}); + edges.push_back({6, 7}); + edges.push_back({7, 3}); + facets.push_back({8, 4, id, interiorMaterialId, -1}); - 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, interiorMaterialId, id, -1)); + edges.push_back({5, 6}); + edges.push_back({6, 2}); + edges.push_back({2, 1}); + edges.push_back({1, 5}); + facets.push_back({12, 4, id, interiorMaterialId, -1}); - 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, interiorMaterialId, id, -1)); + edges.push_back({4, 5}); + edges.push_back({5, 1}); + edges.push_back({1, 0}); + edges.push_back({0, 4}); + facets.push_back({16, 4, id, interiorMaterialId, -1}); - 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, interiorMaterialId, id, -1)); + edges.push_back({4, 7}); + edges.push_back({7, 6}); + edges.push_back({6, 5}); + edges.push_back({5, 4}); + facets.push_back({20, 4, id, interiorMaterialId, -1}); + 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())); +} - 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, interiorMaterialId, id, -1)); - 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 inverseNormalAndIndices(Mesh* mesh) +{ + for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) + { + toPxShared(mesh->getVerticesWritable()[i].n) *= -1.0f; + } + for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) + { + mesh->getFacetWritable(i)->userData = -mesh->getFacet(i)->userData; + } +} - void inverseNormalAndIndices(Mesh* mesh) - { - for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) - { - mesh->getVerticesWritable()[i].n *= -1.0f; - } - for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) - { - mesh->getFacetWritable(i)->userData = -mesh->getFacet(i)->userData; - } - } +void setCuttingBox(const PxVec3& point, const PxVec3& normal, Mesh* mesh, float size, int64_t id) +{ + PxVec3 t1, t2; + PxVec3 lNormal = normal.getNormalized(); + getTangents(lNormal, t1, t2); - void setCuttingBox(const PxVec3& point, const PxVec3& normal, Mesh* mesh, float size, int64_t id) - { - PxVec3 t1, t2; - PxVec3 lNormal = normal.getNormalized(); - getTangents(lNormal, t1, t2); + Vertex* positions = mesh->getVerticesWritable(); + toPxShared(positions[0].p) = point + (t1 + t2) * size; + toPxShared(positions[1].p) = point + (t2 - t1) * size; - Vertex* positions = mesh->getVerticesWritable(); - positions[0].p = point + (t1 + t2) * size; - positions[1].p = point + (t2 - t1) * size; + toPxShared(positions[2].p) = point + (-t1 - t2) * size; + toPxShared(positions[3].p) = point + (t1 - t2) * size; - positions[2].p = point + (-t1 - t2) * size; - positions[3].p = point + (t1 - t2) * size; + toPxShared(positions[4].p) = point + (t1 + t2 + lNormal) * size; + toPxShared(positions[5].p) = point + (t2 - t1 + lNormal) * size; - positions[4].p = point + (t1 + t2 + lNormal) * size; - positions[5].p = point + (t2 - t1 + lNormal) * size; + toPxShared(positions[6].p) = point + (-t1 - t2 + lNormal) * size; + toPxShared(positions[7].p) = point + (t1 - t2 + lNormal) * size; - positions[6].p = point + (-t1 - t2 + lNormal) * size; - positions[7].p = point + (t1 - t2 + lNormal) * size; + toPxShared(positions[0].n) = -lNormal; + toPxShared(positions[1].n) = -lNormal; - positions[0].n = -lNormal; - positions[1].n = -lNormal; + toPxShared(positions[2].n) = -lNormal; + toPxShared(positions[3].n) = -lNormal; - positions[2].n = -lNormal; - positions[3].n = -lNormal; + toPxShared(positions[4].n) = -lNormal; + toPxShared(positions[5].n) = -lNormal; - positions[4].n = -lNormal; - positions[5].n = -lNormal; + toPxShared(positions[6].n) = -lNormal; + toPxShared(positions[7].n) = -lNormal; - positions[6].n = -lNormal; - positions[7].n = -lNormal; + for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) + { + mesh->getFacetWritable(i)->userData = id; + } + mesh->recalculateBoundingBox(); +} - for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) - { - mesh->getFacetWritable(i)->userData = id; - } - mesh->recalculateBoundingBox(); - } +struct Stepper +{ + virtual physx::PxVec3 getStep1(uint32_t w, uint32_t h) const = 0; + virtual physx::PxVec3 getStep2(uint32_t w) const = 0; + virtual physx::PxVec3 getStart() const = 0; + virtual physx::PxVec3 getNormal(uint32_t w, uint32_t h) const = 0; + virtual bool isStep2ClosedLoop() const + { + return false; + } + virtual bool isStep2FreeBoundary() const + { + return false; + } +}; - struct Stepper +struct PlaneStepper : public Stepper +{ + PlaneStepper(const physx::PxVec3& normal, const physx::PxVec3& point, float sizeX, float sizeY, + uint32_t resolutionX, uint32_t resolutionY, bool swapTangents = false) + { + PxVec3 t1, t2; + lNormal = normal.getNormalized(); + getTangents(lNormal, t1, t2); + if (swapTangents) { - virtual physx::PxVec3 getStep1(uint32_t w, uint32_t h) const = 0; - virtual physx::PxVec3 getStep2(uint32_t w) const = 0; - virtual physx::PxVec3 getStart() const = 0; - virtual physx::PxVec3 getNormal(uint32_t w, uint32_t h) const = 0; - virtual bool isStep2ClosedLoop() const - { - return false; - } - virtual bool isStep2FreeBoundary() const - { - return false; - } - }; - - struct PlaneStepper : public Stepper + std::swap(t1, t2); + } + t11d = -t1 * 2.0f * sizeX / resolutionX; + t12d = -t2 * 2.0f * sizeY / resolutionY; + t21d = t11d; + t22d = t12d; + cPos = point + (t1 * sizeX + t2 * sizeY); + resY = resolutionY; + } + // Define face by 4 corner points, points should lay in plane + PlaneStepper(const physx::PxVec3& p11, const physx::PxVec3& p12, const physx::PxVec3& p21, const physx::PxVec3& p22, + uint32_t resolutionX, uint32_t resolutionY) + { + lNormal = -(p21 - p11).cross(p12 - p11).getNormalized(); + if (lNormal.magnitude() < 1e-5) { - PlaneStepper(const physx::PxVec3& normal, const physx::PxVec3& point, float sizeX, float sizeY, uint32_t resolutionX, uint32_t resolutionY, bool swapTangents = false) - { - PxVec3 t1, t2; - lNormal = normal.getNormalized(); - getTangents(lNormal, t1, t2); - if (swapTangents) - { - std::swap(t1, t2); - } - t11d = -t1 * 2.0f * sizeX / resolutionX; - t12d = -t2 * 2.0f * sizeY / resolutionY; - t21d = t11d; - t22d = t12d; - cPos = point + (t1 * sizeX + t2 * sizeY); - resY = resolutionY; - } - //Define face by 4 corner points, points should lay in plane - PlaneStepper(const physx::PxVec3& p11, const physx::PxVec3& p12, const physx::PxVec3& p21, const physx::PxVec3& p22, - uint32_t resolutionX, uint32_t resolutionY) - { - lNormal = -(p21 - p11).cross(p12 - p11).getNormalized(); - if (lNormal.magnitude() < 1e-5) - { - lNormal = (p21 - p22).cross(p12 - p22).getNormalized(); - } - t11d = (p11 - p21) / resolutionX; - t12d = (p12 - p11) / resolutionY; - t21d = (p12 - p22) / resolutionX; - t22d = (p22 - p21) / resolutionY; - cPos = p21; - resY = resolutionY; - } - physx::PxVec3 getStep1(uint32_t y, uint32_t) const - { - return (t11d * (resY - y) + t21d * y) / resY; - } - physx::PxVec3 getStep2(uint32_t) const - { - return t22d; - } - physx::PxVec3 getStart() const - { - return cPos; - } - physx::PxVec3 getNormal(uint32_t, uint32_t) const - { - return lNormal; - } + lNormal = (p21 - p22).cross(p12 - p22).getNormalized(); + } + t11d = (p11 - p21) / resolutionX; + t12d = (p12 - p11) / resolutionY; + t21d = (p12 - p22) / resolutionX; + t22d = (p22 - p21) / resolutionY; + cPos = p21; + resY = resolutionY; + } + physx::PxVec3 getStep1(uint32_t y, uint32_t) const + { + return (t11d * (resY - y) + t21d * y) / resY; + } + physx::PxVec3 getStep2(uint32_t) const + { + return t22d; + } + physx::PxVec3 getStart() const + { + return cPos; + } + physx::PxVec3 getNormal(uint32_t, uint32_t) const + { + return lNormal; + } - PxVec3 t11d, t12d, t21d, t22d, cPos, lNormal; - uint32_t resY; - }; + PxVec3 t11d, t12d, t21d, t22d, cPos, lNormal; + uint32_t resY; +}; - void fillEdgesAndFaces(std::vector<Edge>& edges, std::vector<Facet>& facets, - uint32_t h, uint32_t w, uint32_t firstVertex, uint32_t verticesCount, int64_t id, int32_t interiorMaterialId, int32_t smoothingGroup = -1, bool reflected = false) +void fillEdgesAndFaces(std::vector<Edge>& edges, std::vector<Facet>& facets, uint32_t h, uint32_t w, + uint32_t firstVertex, uint32_t verticesCount, int64_t id, int32_t interiorMaterialId, + int32_t smoothingGroup = -1, bool reflected = false) +{ + for (uint32_t i = 0; i < w; ++i) + { + for (uint32_t j = 0; j < h; ++j) { - for (uint32_t i = 0; i < w; ++i) - { - for (uint32_t j = 0; j < h; ++j) - { - uint32_t start = edges.size(); - uint32_t idx00 = i * (h + 1) + j + firstVertex; - uint32_t idx01 = idx00 + 1; - uint32_t idx10 = (idx00 + h + 1) % verticesCount; - uint32_t idx11 = (idx01 + h + 1) % verticesCount; - if (reflected) - { - edges.push_back(Edge(idx01, idx11)); - edges.push_back(Edge(idx11, idx10)); - edges.push_back(Edge(idx10, idx01)); - facets.push_back(Facet(start, 3, interiorMaterialId, id, smoothingGroup)); - - start = edges.size(); - edges.push_back(Edge(idx01, idx10)); - edges.push_back(Edge(idx10, idx00)); - edges.push_back(Edge(idx00, idx01)); - facets.push_back(Facet(start, 3, interiorMaterialId, id, smoothingGroup)); - } - else - { - edges.push_back(Edge(idx00, idx01)); - edges.push_back(Edge(idx01, idx11)); - edges.push_back(Edge(idx11, idx00)); - facets.push_back(Facet(start, 3, interiorMaterialId, id, smoothingGroup)); - - start = edges.size(); - edges.push_back(Edge(idx00, idx11)); - edges.push_back(Edge(idx11, idx10)); - edges.push_back(Edge(idx10, idx00)); - facets.push_back(Facet(start, 3, interiorMaterialId, id, smoothingGroup)); - } - } + int32_t start = edges.size(); + uint32_t idx00 = i * (h + 1) + j + firstVertex; + uint32_t idx01 = idx00 + 1; + uint32_t idx10 = (idx00 + h + 1) % verticesCount; + uint32_t idx11 = (idx01 + h + 1) % verticesCount; + if (reflected) + { + edges.push_back({idx01, idx11}); + edges.push_back({idx11, idx10}); + edges.push_back({idx10, idx01}); + facets.push_back({start, 3, id, interiorMaterialId, smoothingGroup}); + + start = edges.size(); + edges.push_back({idx01, idx10}); + edges.push_back({idx10, idx00}); + edges.push_back({idx00, idx01}); + facets.push_back({start, 3, id, interiorMaterialId, smoothingGroup}); } - } - - void getNoisyFace(std::vector<Vertex>& vertices, std::vector<Edge>& edges, std::vector<Facet>& facets, - uint32_t h, uint32_t w, const physx::PxVec2& uvOffset, const physx::PxVec2& uvScale, - const Stepper& stepper, SimplexNoise& nEval, int64_t id, int32_t interiorMaterialId, bool randomizeLast = false) - { - uint32_t randIdx = randomizeLast ? 1 : 0; - PxVec3 cPosit = stepper.getStart(); - uint32_t firstVertex = vertices.size(); - for (uint32_t i = 0; i < w + 1; ++i) + else { - PxVec3 lcPosit = cPosit; - for (uint32_t j = 0; j < h + 1; ++j) - { - vertices.push_back(Vertex()); - vertices.back().p = lcPosit; - vertices.back().uv[0] = uvOffset + uvScale.multiply(physx::PxVec2(j, i)); - lcPosit += stepper.getStep1(i, j); - } - cPosit += stepper.getStep2(i); - } + edges.push_back({idx00, idx01}); + edges.push_back({idx01, idx11}); + edges.push_back({idx11, idx00}); + facets.push_back({start, 3, id, interiorMaterialId, smoothingGroup}); - for (uint32_t i = 1 - randIdx; i < w + randIdx; ++i) - { - for (uint32_t j = 1; j < h; ++j) - { - //TODO limit max displacement for cylinder - PxVec3& pnt = vertices[i * (h + 1) + j + firstVertex].p; - pnt += stepper.getNormal(i, j) * nEval.sample(pnt); - } + start = edges.size(); + edges.push_back({idx00, idx11}); + edges.push_back({idx11, idx10}); + edges.push_back({idx10, idx00}); + facets.push_back({start, 3, id, interiorMaterialId, smoothingGroup}); } + } + } +} - fillEdgesAndFaces(edges, facets, h, w, firstVertex, vertices.size(), id, interiorMaterialId); +void getNoisyFace(std::vector<Vertex>& vertices, std::vector<Edge>& edges, std::vector<Facet>& facets, uint32_t h, + uint32_t w, const physx::PxVec2& uvOffset, const physx::PxVec2& uvScale, const Stepper& stepper, + SimplexNoise& nEval, int64_t id, int32_t interiorMaterialId, bool randomizeLast = false) +{ + uint32_t randIdx = randomizeLast ? 1 : 0; + PxVec3 cPosit = stepper.getStart(); + uint32_t firstVertex = vertices.size(); + for (uint32_t i = 0; i < w + 1; ++i) + { + PxVec3 lcPosit = cPosit; + for (uint32_t j = 0; j < h + 1; ++j) + { + vertices.push_back(Vertex()); + toPxShared(vertices.back().p) = lcPosit; + toPxShared(vertices.back().uv[0]) = uvOffset + uvScale.multiply(physx::PxVec2(j, i)); + lcPosit += stepper.getStep1(i, j); } + cPosit += stepper.getStep2(i); + } - PX_INLINE uint32_t unsignedMod(int32_t n, uint32_t modulus) + for (uint32_t i = 1 - randIdx; i < w + randIdx; ++i) + { + for (uint32_t j = 1; j < h; ++j) { - const int32_t d = n / (int32_t)modulus; - const int32_t m = n - d*(int32_t)modulus; - return m >= 0 ? (uint32_t)m : (uint32_t)m + modulus; + // TODO limit max displacement for cylinder + PxVec3& pnt = toPxShared(vertices[i * (h + 1) + j + firstVertex].p); + pnt += stepper.getNormal(i, j) * nEval.sample(pnt); } + } + + fillEdgesAndFaces(edges, facets, h, w, firstVertex, vertices.size(), id, interiorMaterialId); +} - void calculateNormals(std::vector<Vertex>& vertices, uint32_t h, uint32_t w, bool inverseNormals = false) +PX_INLINE uint32_t unsignedMod(int32_t n, uint32_t modulus) +{ + const int32_t d = n / (int32_t)modulus; + const int32_t m = n - d * (int32_t)modulus; + return m >= 0 ? (uint32_t)m : (uint32_t)m + modulus; +} + +void calculateNormals(std::vector<Vertex>& vertices, uint32_t h, uint32_t w, bool inverseNormals = false) +{ + for (uint32_t i = 1; i < w; ++i) + { + for (uint32_t j = 1; j < h; ++j) { - for (uint32_t i = 1; i < w; ++i) + int32_t idx = i * (h + 1) + j; + PxVec3 v1 = toPxShared(vertices[idx + h + 1].p - vertices[idx].p); + PxVec3 v2 = toPxShared(vertices[idx + 1].p - vertices[idx].p); + PxVec3 v3 = toPxShared(vertices[idx - (h + 1)].p - vertices[idx].p); + PxVec3 v4 = toPxShared(vertices[idx - 1].p - vertices[idx].p); + + PxVec3& n = toPxShared(vertices[idx].n); + n = v1.cross(v2) + v2.cross(v3) + v3.cross(v4) + v4.cross(v1); + if (inverseNormals) { - for (uint32_t j = 1; j < h; ++j) - { - int32_t idx = i * (h + 1) + j; - PxVec3 v1 = vertices[idx + h + 1].p - vertices[idx].p; - PxVec3 v2 = vertices[idx + 1].p - vertices[idx].p; - PxVec3 v3 = vertices[idx - (h + 1)].p - vertices[idx].p; - PxVec3 v4 = vertices[idx - 1].p - vertices[idx].p; - - vertices[idx].n = v1.cross(v2) + v2.cross(v3) + v3.cross(v4) + v4.cross(v1); - if (inverseNormals) - { - vertices[idx].n = -vertices[idx].n; - } - vertices[idx].n.normalize(); - } + n = -n; } + n.normalize(); } + } +} - Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& normal, float size, float jaggedPlaneSize, physx::PxVec3 resolution, int64_t id, float amplitude, float frequency, int32_t octaves, int32_t seed, int32_t interiorMaterialId) - { - PxVec3 t1, t2; - PxVec3 lNormal = normal.getNormalized(); - getTangents(lNormal, t1, t2); - float sz = 2.f * jaggedPlaneSize; - uint32_t resolutionX = std::max(1u, (uint32_t)std::roundf(sz * std::abs(t1.x) * resolution.x + sz * std::abs(t1.y) * resolution.y + sz * std::abs(t1.z) * resolution.z)); - uint32_t resolutionY = std::max(1u, (uint32_t)std::roundf(sz * std::abs(t2.x) * resolution.x + sz * std::abs(t2.y) * resolution.y + sz * std::abs(t2.z) * resolution.z)); - - PlaneStepper stepper(normal, point, jaggedPlaneSize, jaggedPlaneSize, resolutionX, resolutionY); - SimplexNoise nEval(amplitude, frequency, octaves, seed); - - std::vector<Vertex> vertices; vertices.reserve((resolutionX + 1) * (resolutionY + 1) + 12); - std::vector<Edge> edges; - std::vector<Facet> facets; - getNoisyFace(vertices, edges, facets, resolutionX, resolutionY, physx::PxVec2(0.f), physx::PxVec2(UV_SCALE / resolutionX, UV_SCALE / resolutionY), - stepper, nEval, id, interiorMaterialId); - calculateNormals(vertices, resolutionX, resolutionY); - - uint32_t offset = (resolutionX + 1) * (resolutionY + 1); - vertices.resize(offset + 12); - - vertices[0 + offset].p = point + (t1 + t2) * size; - vertices[1 + offset].p = point + (t2 - t1) * size; - - vertices[2 + offset].p = point + (-t1 - t2) * size; - vertices[3 + offset].p = point + (t1 - t2) * size; - - vertices[8 + offset].p = point + (t1 + t2) * jaggedPlaneSize; - vertices[9 + offset].p = point + (t2 - t1) * jaggedPlaneSize; - - vertices[10 + offset].p = point + (-t1 - t2) * jaggedPlaneSize; - vertices[11 + offset].p = point + (t1 - t2) * jaggedPlaneSize; - - vertices[4 + offset].p = point + (t1 + t2 + lNormal) * size; - vertices[5 + offset].p = point + (t2 - t1 + lNormal) * size; - - vertices[6 + offset].p = point + (-t1 - t2 + lNormal) * size; - vertices[7 + offset].p = point + (t1 - t2 + lNormal) * size; - - int32_t edgeOffset = edges.size(); - edges.push_back(Edge(0 + offset, 1 + offset)); - edges.push_back(Edge(1 + offset, 2 + offset)); - edges.push_back(Edge(2 + offset, 3 + offset)); - edges.push_back(Edge(3 + offset, 0 + offset)); - - edges.push_back(Edge(11 + offset, 10 + offset)); - edges.push_back(Edge(10 + offset, 9 + offset)); - edges.push_back(Edge(9 + offset, 8 + offset)); - edges.push_back(Edge(8 + offset, 11 + offset)); - - facets.push_back(Facet(edgeOffset, 8, interiorMaterialId, id, -1)); - - edges.push_back(Edge(0 + offset, 3 + offset)); - 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, interiorMaterialId, id, -1)); - - 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, interiorMaterialId, id, -1)); - - 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, interiorMaterialId, id, -1)); - - 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, interiorMaterialId, id, -1)); - - 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, interiorMaterialId, id, -1)); - - // - return new MeshImpl(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size()); - } +Mesh* getNoisyCuttingBoxPair(const physx::PxVec3& point, const physx::PxVec3& normal, float size, float jaggedPlaneSize, + physx::PxVec3 resolution, int64_t id, float amplitude, float frequency, int32_t octaves, + int32_t seed, int32_t interiorMaterialId) +{ + PxVec3 t1, t2; + PxVec3 lNormal = normal.getNormalized(); + getTangents(lNormal, t1, t2); + float sz = 2.f * jaggedPlaneSize; + uint32_t resolutionX = + std::max(1u, (uint32_t)std::roundf(sz * std::abs(t1.x) * resolution.x + sz * std::abs(t1.y) * resolution.y + + sz * std::abs(t1.z) * resolution.z)); + uint32_t resolutionY = + std::max(1u, (uint32_t)std::roundf(sz * std::abs(t2.x) * resolution.x + sz * std::abs(t2.y) * resolution.y + + sz * std::abs(t2.z) * resolution.z)); + + PlaneStepper stepper(normal, point, jaggedPlaneSize, jaggedPlaneSize, resolutionX, resolutionY); + SimplexNoise nEval(amplitude, frequency, octaves, seed); + + std::vector<Vertex> vertices; + vertices.reserve((resolutionX + 1) * (resolutionY + 1) + 12); + std::vector<Edge> edges; + std::vector<Facet> facets; + getNoisyFace(vertices, edges, facets, resolutionX, resolutionY, physx::PxVec2(0.f), + physx::PxVec2(UV_SCALE / resolutionX, UV_SCALE / resolutionY), stepper, nEval, id, interiorMaterialId); + calculateNormals(vertices, resolutionX, resolutionY); + + uint32_t offset = (resolutionX + 1) * (resolutionY + 1); + vertices.resize(offset + 12); + + toPxShared(vertices[0 + offset].p) = point + (t1 + t2) * size; + toPxShared(vertices[1 + offset].p) = point + (t2 - t1) * size; + + toPxShared(vertices[2 + offset].p) = point + (-t1 - t2) * size; + toPxShared(vertices[3 + offset].p) = point + (t1 - t2) * size; + + toPxShared(vertices[8 + offset].p) = point + (t1 + t2) * jaggedPlaneSize; + toPxShared(vertices[9 + offset].p) = point + (t2 - t1) * jaggedPlaneSize; + + toPxShared(vertices[10 + offset].p) = point + (-t1 - t2) * jaggedPlaneSize; + toPxShared(vertices[11 + offset].p) = point + (t1 - t2) * jaggedPlaneSize; + + toPxShared(vertices[4 + offset].p) = point + (t1 + t2 + lNormal) * size; + toPxShared(vertices[5 + offset].p) = point + (t2 - t1 + lNormal) * size; + + toPxShared(vertices[6 + offset].p) = point + (-t1 - t2 + lNormal) * size; + toPxShared(vertices[7 + offset].p) = point + (t1 - t2 + lNormal) * size; + + int32_t edgeOffset = edges.size(); + edges.push_back({0 + offset, 1 + offset}); + edges.push_back({ 1 + offset, 2 + offset }); + edges.push_back({ 2 + offset, 3 + offset }); + edges.push_back({3 + offset, 0 + offset}); + + edges.push_back({ 11 + offset, 10 + offset }); + edges.push_back({ 10 + offset, 9 + offset }); + edges.push_back({ 9 + offset, 8 + offset }); + edges.push_back({ 8 + offset, 11 + offset }); + + facets.push_back({ edgeOffset, 8, id, interiorMaterialId, -1 }); + + edges.push_back({ 0 + offset, 3 + offset }); + edges.push_back({ 3 + offset, 7 + offset }); + edges.push_back({ 7 + offset, 4 + offset }); + edges.push_back({ 4 + offset, 0 + offset }); + facets.push_back({ 8 + edgeOffset, 4, id, interiorMaterialId, -1 }); + + edges.push_back({ 3 + offset, 2 + offset }); + edges.push_back({ 2 + offset, 6 + offset }); + edges.push_back({ 6 + offset, 7 + offset }); + edges.push_back({ 7 + offset, 3 + offset }); + facets.push_back({ 12 + edgeOffset, 4, id, interiorMaterialId, -1 }); + + edges.push_back({ 5 + offset, 6 + offset }); + edges.push_back({ 6 + offset, 2 + offset }); + edges.push_back({ 2 + offset, 1 + offset }); + edges.push_back({ 1 + offset, 5 + offset }); + facets.push_back({ 16 + edgeOffset, 4, id, interiorMaterialId, -1 }); + + edges.push_back({ 4 + offset, 5 + offset }); + edges.push_back({ 5 + offset, 1 + offset }); + edges.push_back({ 1 + offset, 0 + offset }); + edges.push_back({ 0 + offset, 4 + offset }); + facets.push_back({ 20 + edgeOffset, 4, id, interiorMaterialId, -1 }); + + edges.push_back({ 4 + offset, 7 + offset }); + edges.push_back({ 7 + offset, 6 + offset }); + edges.push_back({ 6 + offset, 5 + offset }); + edges.push_back({ 5 + offset, 4 + offset }); + facets.push_back({ 24 + edgeOffset, 4, id, interiorMaterialId, -1 }); + + // + return new MeshImpl(vertices.data(), edges.data(), facets.data(), vertices.size(), edges.size(), facets.size()); +} + +Mesh* getBigBox(const PxVec3& point, float size, int32_t interiorMaterialId) +{ + PxVec3 normal(0, 0, 1); + normal.normalize(); + PxVec3 t1, t2; + getTangents(normal, t1, t2); - Mesh* getBigBox(const PxVec3& point, float size, int32_t interiorMaterialId) - { - PxVec3 normal(0, 0, 1); - normal.normalize(); - PxVec3 t1, t2; - getTangents(normal, t1, t2); + std::vector<Vertex> positions(8); + toPxShared(positions[0].p) = point + (t1 + t2 - normal) * size; + toPxShared(positions[1].p) = point + (t2 - t1 - normal) * size; + + toPxShared(positions[2].p) = point + (-t1 - t2 - normal) * size; + toPxShared(positions[3].p) = point + (t1 - t2 - normal) * size; + + toPxShared(positions[4].p) = point + (t1 + t2 + normal) * size; + toPxShared(positions[5].p) = point + (t2 - t1 + normal) * size; + + toPxShared(positions[6].p) = point + (-t1 - t2 + normal) * size; + toPxShared(positions[7].p) = point + (t1 - t2 + normal) * size; - std::vector<Vertex> positions(8); - positions[0].p = point + (t1 + t2 - normal) * size; - positions[1].p = point + (t2 - t1 - normal) * size; + positions[0].uv[0] = {0, 0}; + positions[1].uv[0] = {UV_SCALE, 0}; - positions[2].p = point + (-t1 - t2 - normal) * size; - positions[3].p = point + (t1 - t2 - normal) * size; + positions[2].uv[0] = {UV_SCALE, UV_SCALE}; + positions[3].uv[0] = {0, UV_SCALE}; - positions[4].p = point + (t1 + t2 + normal) * size; - positions[5].p = point + (t2 - t1 + normal) * size; + positions[4].uv[0] = {0, 0}; + positions[5].uv[0] = {UV_SCALE, 0}; - positions[6].p = point + (-t1 - t2 + normal) * size; - positions[7].p = point + (t1 - t2 + normal) * size; + positions[6].uv[0] = {UV_SCALE, UV_SCALE}; + positions[7].uv[0] = {0, UV_SCALE}; - positions[0].uv[0] = PxVec2(0, 0); - positions[1].uv[0] = PxVec2(UV_SCALE, 0); - positions[2].uv[0] = PxVec2(UV_SCALE, UV_SCALE); - positions[3].uv[0] = PxVec2(0, UV_SCALE); + std::vector<Edge> edges; + std::vector<Facet> facets; + edges.push_back({0, 1}); + edges.push_back({1, 2}); + edges.push_back({2, 3}); + edges.push_back({3, 0}); + facets.push_back({0, 4, 0, interiorMaterialId, -1}); - positions[4].uv[0] = PxVec2(0, 0); - positions[5].uv[0] = PxVec2(UV_SCALE, 0); - positions[6].uv[0] = PxVec2(UV_SCALE, UV_SCALE); - positions[7].uv[0] = PxVec2(0, UV_SCALE); + edges.push_back({0, 3}); + edges.push_back({3, 7}); + edges.push_back({7, 4}); + edges.push_back({4, 0}); + facets.push_back({4, 4, 0, interiorMaterialId, -1}); + edges.push_back({3, 2}); + edges.push_back({2, 6}); + edges.push_back({6, 7}); + edges.push_back({7, 3}); + facets.push_back({8, 4, 0, interiorMaterialId, -1}); - std::vector<Edge> edges; - std::vector<Facet> facets; + edges.push_back({5, 6}); + edges.push_back({6, 2}); + edges.push_back({2, 1}); + edges.push_back({1, 5}); + facets.push_back({12, 4, 0, interiorMaterialId, -1}); - edges.push_back(Edge(0, 1)); - edges.push_back(Edge(1, 2)); - edges.push_back(Edge(2, 3)); - edges.push_back(Edge(3, 0)); - facets.push_back(Facet(0, 4, interiorMaterialId, 0, -1)); + edges.push_back({4, 5}); + edges.push_back({5, 1}); + edges.push_back({1, 0}); + edges.push_back({0, 4}); + facets.push_back({16, 4, 0, interiorMaterialId, -1}); + edges.push_back({4, 7}); + edges.push_back({7, 6}); + edges.push_back({6, 5}); + edges.push_back({5, 4}); + facets.push_back({20, 4, 0, interiorMaterialId, -1}); + for (int i = 0; i < 8; ++i) + positions[i].n = {0, 0, 0}; + 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())); +} - 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, interiorMaterialId, 0, -1)); +bool CmpSharedFace:: +operator()(const std::pair<physx::PxVec3, physx::PxVec3>& pv1, const std::pair<physx::PxVec3, physx::PxVec3>& pv2) const +{ + CmpVec vc; + if ((pv1.first - pv2.first).magnitude() < 1e-5) + { + return vc(pv1.second, pv2.second); + } + return vc(pv1.first, pv2.first); +} - 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, interiorMaterialId, 0, -1)); +#define INDEXER_OFFSET (1ll << 32) - 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, interiorMaterialId, 0, -1)); +void buildCuttingConeFaces(const CutoutConfiguration& conf, const std::vector<std::vector<physx::PxVec3> >& cutoutPoints, + float heightBot, float heightTop, float conicityBot, float conicityTop, int64_t& id, + int32_t seed, int32_t interiorMaterialId, SharedFacesMap& sharedFacesMap) +{ + if (conf.noise.amplitude <= FLT_EPSILON) + { + return; + } + std::map<physx::PxVec3, std::pair<uint32_t, std::vector<physx::PxVec3> >, CmpVec> newCutoutPoints; + uint32_t resH = std::max((uint32_t)std::roundf((heightBot + heightTop) / conf.noise.samplingInterval.z), 1u); - 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, interiorMaterialId, 0, -1)); + // generate noisy faces + SimplexNoise nEval(conf.noise.amplitude, conf.noise.frequency, conf.noise.octaveNumber, seed); - 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, interiorMaterialId, 0, -1)); - for (int i = 0; i < 8; ++i) - positions[i].n = PxVec3(0, 0, 0); - 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())); + for (uint32_t i = 0; i < cutoutPoints.size(); i++) + { + auto& points = cutoutPoints[i]; + uint32_t pointCount = points.size(); + float finalP = 0, currentP = 0; + for (uint32_t j = 0; j < pointCount; j++) + { + finalP += (points[(j + 1) % pointCount] - points[j]).magnitude(); } - bool CmpSharedFace::operator()(const std::pair<physx::PxVec3, physx::PxVec3>& pv1, const std::pair<physx::PxVec3, physx::PxVec3>& pv2) const + for (uint32_t p = 0; p < pointCount; p++) { - CmpVec vc; - if ((pv1.first - pv2.first).magnitude() < 1e-5) - { - return vc(pv1.second, pv2.second); + auto p0 = points[p]; + auto p1 = points[(p + 1) % pointCount]; + + auto cp0 = newCutoutPoints.find(p0); + if (cp0 == newCutoutPoints.end()) + { + newCutoutPoints[p0] = std::make_pair(0u, std::vector<physx::PxVec3>(resH + 1, physx::PxVec3(0.f))); + cp0 = newCutoutPoints.find(p0); + } + auto cp1 = newCutoutPoints.find(p1); + if (cp1 == newCutoutPoints.end()) + { + newCutoutPoints[p1] = std::make_pair(0u, std::vector<physx::PxVec3>(resH + 1, physx::PxVec3(0.f))); + cp1 = newCutoutPoints.find(p1); + } + + + auto vec = p1 - p0; + auto cPos = (p0 + p1) * 0.5f; + uint32_t numPts = (uint32_t)(std::abs(vec.x) / conf.noise.samplingInterval.x + + std::abs(vec.y) / conf.noise.samplingInterval.y) + + 1; + auto normal = vec.cross(physx::PxVec3(0, 0, 1)); + normal = normal; + + auto p00 = p0 * conicityBot; + p00.z = -heightBot; + auto p01 = p1 * conicityBot; + p01.z = -heightBot; + auto p10 = p0 * conicityTop; + p10.z = heightTop; + auto p11 = p1 * conicityTop; + p11.z = heightTop; + PlaneStepper stepper(p00, p01, p10, p11, resH, numPts); + + PlaneStepper stepper1(normal, cPos, heightTop, vec.magnitude() * 0.5f, resH, numPts, true); + stepper1.getNormal(0, 0); + + auto t = std::make_pair(p0, p1); + auto sfIt = sharedFacesMap.find(t); + if (sfIt == sharedFacesMap.end() && sharedFacesMap.find(std::make_pair(p1, p0)) == sharedFacesMap.end()) + { + sharedFacesMap[t] = SharedFace(numPts, resH, -(id + INDEXER_OFFSET), interiorMaterialId); + sfIt = sharedFacesMap.find(t); + auto& SF = sfIt->second; + getNoisyFace(SF.vertices, SF.edges, SF.facets, resH, numPts, + physx::PxVec2(0, CYLINDER_UV_SCALE * currentP / (heightBot + heightTop)), + physx::PxVec2(CYLINDER_UV_SCALE / resH, + CYLINDER_UV_SCALE * vec.magnitude() / (heightBot + heightTop) / numPts), + stepper, nEval, id++ + INDEXER_OFFSET, interiorMaterialId, true); + + currentP += vec.magnitude(); + cp0->second.first++; + cp1->second.first++; + for (uint32_t k = 0; k <= resH; k++) + { + cp0->second.second[k] += toPxShared(SF.vertices[k].p); + cp1->second.second[k] += toPxShared(SF.vertices[SF.vertices.size() - resH - 1 + k].p); + } } - return vc(pv1.first, pv2.first); } + } -#define INDEXER_OFFSET (1ll << 32) - - void buildCuttingConeFaces(const CutoutConfiguration& conf, const std::vector<std::vector<physx::PxVec3>>& cutoutPoints, - float heightBot, float heightTop, float conicityBot, float conicityTop, - int64_t& id, int32_t seed, int32_t interiorMaterialId, SharedFacesMap& sharedFacesMap) + // limit faces displacement iteratively + for (uint32_t i = 0; i < cutoutPoints.size(); i++) + { + auto& points = cutoutPoints[i]; + uint32_t pointCount = points.size(); + for (uint32_t p = 0; p < pointCount; p++) { - if (conf.noise.amplitude <= FLT_EPSILON) + auto p0 = points[p]; + auto p1 = points[(p + 1) % pointCount]; + auto p2 = points[(p + 2) % pointCount]; + auto& cp1 = newCutoutPoints.find(p1)->second; + float d = physx::PxClamp((p1 - p0).getNormalized().dot((p2 - p1).getNormalized()), 0.f, 1.f); + + for (uint32_t h = 0; h <= resH; h++) { - return; + float z = cp1.second[h].z; + float conicity = (conicityBot * h + conicityTop * (resH - h)) / resH; + cp1.second[h] = cp1.second[h] * d + p1 * cp1.first * conicity * (1.f - d); + cp1.second[h].z = z; } - std::map<physx::PxVec3, std::pair<uint32_t, std::vector<physx::PxVec3>>, CmpVec> newCutoutPoints; - uint32_t resH = std::max((uint32_t)std::roundf((heightBot + heightTop) / conf.noise.samplingInterval.z), 1u); - - //generate noisy faces - SimplexNoise nEval(conf.noise.amplitude, conf.noise.frequency, conf.noise.octaveNumber, seed); + } + } - for (uint32_t i = 0; i < cutoutPoints.size(); i++) - { - auto& points = cutoutPoints[i]; - uint32_t pointCount = points.size(); - float finalP = 0, currentP = 0; - for (uint32_t j = 0; j < pointCount; j++) - { - finalP += (points[(j + 1) % pointCount] - points[j]).magnitude(); - } + // relax nearby points for too big faces displacement limitations + for (uint32_t i = 0; i < cutoutPoints.size(); i++) + { + auto& points = cutoutPoints[i]; + uint32_t pointCount = points.size(); + for (uint32_t p = 0; p < pointCount; p++) + { + auto p0 = points[p]; + auto p1 = points[(p + 1) % pointCount]; + auto& cp0 = newCutoutPoints.find(p0)->second; + auto& cp1 = newCutoutPoints.find(p1)->second; - for (uint32_t p = 0; p < pointCount; p++) - { - auto p0 = points[p]; - auto p1 = points[(p + 1) % pointCount]; - - auto cp0 = newCutoutPoints.find(p0); - if (cp0 == newCutoutPoints.end()) - { - newCutoutPoints[p0] = std::make_pair(0u, std::vector<physx::PxVec3>(resH + 1, physx::PxVec3(0.f))); - cp0 = newCutoutPoints.find(p0); - } - auto cp1 = newCutoutPoints.find(p1); - if (cp1 == newCutoutPoints.end()) - { - newCutoutPoints[p1] = std::make_pair(0u, std::vector<physx::PxVec3>(resH + 1, physx::PxVec3(0.f))); - cp1 = newCutoutPoints.find(p1); - } - - - auto vec = p1 - p0; - auto cPos = (p0 + p1) * 0.5f; - uint32_t numPts = (uint32_t)(std::abs(vec.x) / conf.noise.samplingInterval.x + std::abs(vec.y) / conf.noise.samplingInterval.y) + 1; - auto normal = vec.cross(physx::PxVec3(0, 0, 1)); - normal = normal; - - auto p00 = p0 * conicityBot; p00.z = -heightBot; - auto p01 = p1 * conicityBot; p01.z = -heightBot; - auto p10 = p0 * conicityTop; p10.z = heightTop; - auto p11 = p1 * conicityTop; p11.z = heightTop; - PlaneStepper stepper(p00, p01, p10, p11, resH, numPts); - - PlaneStepper stepper1(normal, cPos, heightTop, vec.magnitude() * 0.5f, resH, numPts, true); - stepper1.getNormal(0, 0); - - auto t = std::make_pair(p0, p1); - auto sfIt = sharedFacesMap.find(t); - if (sfIt == sharedFacesMap.end() && sharedFacesMap.find(std::make_pair(p1, p0)) == sharedFacesMap.end()) - { - sharedFacesMap[t] = SharedFace(numPts, resH, -(id + INDEXER_OFFSET), interiorMaterialId); - sfIt = sharedFacesMap.find(t); - auto& SF = sfIt->second; - getNoisyFace(SF.vertices, SF.edges, SF.facets, resH, numPts, - physx::PxVec2(0, CYLINDER_UV_SCALE * currentP / (heightBot + heightTop)), - physx::PxVec2(CYLINDER_UV_SCALE / resH, CYLINDER_UV_SCALE * vec.magnitude() / (heightBot + heightTop) / numPts), - stepper, nEval, id++ + INDEXER_OFFSET, interiorMaterialId, true); - - currentP += vec.magnitude(); - cp0->second.first++; - cp1->second.first++; - for (uint32_t k = 0; k <= resH; k++) - { - cp0->second.second[k] += SF.vertices[k].p; - cp1->second.second[k] += SF.vertices[SF.vertices.size() - resH - 1 + k].p; - } - } - } - } + auto SFIt = sharedFacesMap.find(std::make_pair(p0, p1)); - //limit faces displacement iteratively - for (uint32_t i = 0; i < cutoutPoints.size(); i++) + uint32_t idx0 = 0, idx1; + if (SFIt == sharedFacesMap.end()) { - auto& points = cutoutPoints[i]; - uint32_t pointCount = points.size(); - for (uint32_t p = 0; p < pointCount; p++) - { - auto p0 = points[p]; - auto p1 = points[(p + 1) % pointCount]; - auto p2 = points[(p + 2) % pointCount]; - auto& cp1 = newCutoutPoints.find(p1)->second; - float d = physx::PxClamp((p1 - p0).getNormalized().dot((p2 - p1).getNormalized()), 0.f, 1.f); - - for (uint32_t h = 0; h <= resH; h++) - { - float z = cp1.second[h].z; - float conicity = (conicityBot * h + conicityTop * (resH - h)) / resH; - cp1.second[h] = cp1.second[h] * d + p1 * cp1.first * conicity * (1.f - d); - cp1.second[h].z = z; - } - } + SFIt = sharedFacesMap.find(std::make_pair(p1, p0)); + idx1 = 0; + idx0 = SFIt->second.w * (SFIt->second.h + 1); } - - //relax nearby points for too big faces displacement limitations - for (uint32_t i = 0; i < cutoutPoints.size(); i++) + else { - auto& points = cutoutPoints[i]; - uint32_t pointCount = points.size(); - for (uint32_t p = 0; p < pointCount; p++) - { - auto p0 = points[p]; - auto p1 = points[(p + 1) % pointCount]; - auto& cp0 = newCutoutPoints.find(p0)->second; - auto& cp1 = newCutoutPoints.find(p1)->second; - - auto SFIt = sharedFacesMap.find(std::make_pair(p0, p1)); - - uint32_t idx0 = 0, idx1; - if (SFIt == sharedFacesMap.end()) - { - SFIt = sharedFacesMap.find(std::make_pair(p1, p0)); - idx1 = 0; - idx0 = SFIt->second.w * (SFIt->second.h + 1); - } - else - { - idx1 = SFIt->second.w * (SFIt->second.h + 1); - } - - for (uint32_t h = 0; h <= resH; h++) - { - float z = cp1.second[h].z; - float R0 = (cp0.second[h] / cp0.first - SFIt->second.vertices[idx0 + h].p).magnitude(); - float R1 = (cp1.second[h] / cp1.first - SFIt->second.vertices[idx1 + h].p).magnitude(); - float R = R0 - R1; - float r = 0.25f * (cp1.second[h] / cp1.first - cp0.second[h] / cp0.first).magnitude(); - float conicity = (conicityBot * h + conicityTop * (resH - h)) / resH; - if (R > r) - { - float w = std::min(1.f, r / R); - cp1.second[h] = cp1.second[h] * w + p1 * cp1.first * conicity * (1.f - w); - cp1.second[h].z = z; - } - } - } - - for (int32_t p = pointCount - 1; p >= 0; p--) - { - auto p0 = points[p]; - auto p1 = points[unsignedMod(p - 1, pointCount)]; - auto& cp0 = newCutoutPoints.find(p0)->second; - auto& cp1 = newCutoutPoints.find(p1)->second; - - auto SFIt = sharedFacesMap.find(std::make_pair(p0, p1)); - uint32_t idx0 = 0, idx1; - if (SFIt == sharedFacesMap.end()) - { - SFIt = sharedFacesMap.find(std::make_pair(p1, p0)); - idx1 = 0; - idx0 = SFIt->second.w * (SFIt->second.h + 1); - } - else - { - idx1 = SFIt->second.w * (SFIt->second.h + 1); - } - - for (uint32_t h = 0; h <= resH; h++) - { - float z = cp1.second[h].z; - float R0 = (cp0.second[h] / cp0.first - SFIt->second.vertices[idx0 + h].p).magnitude(); - float R1 = (cp1.second[h] / cp1.first - SFIt->second.vertices[idx1 + h].p).magnitude(); - float R = R0 - R1; - float r = 0.25f * (cp1.second[h] / cp1.first - cp0.second[h] / cp0.first).magnitude(); - float conicity = (conicityBot * h + conicityTop * (resH - h)) / resH; - if (R > r) - { - float w = std::min(1.f, r / R); - cp1.second[h] = cp1.second[h] * w + p1 * cp1.first * conicity * (1.f - w); - cp1.second[h].z = z; - } - } - } + idx1 = SFIt->second.w * (SFIt->second.h + 1); } - //glue faces - for (auto& SF : sharedFacesMap) + for (uint32_t h = 0; h <= resH; h++) { - auto& cp0 = newCutoutPoints.find(SF.first.first)->second; - auto& cp1 = newCutoutPoints.find(SF.first.second)->second; - auto& v = SF.second.vertices; - float invW = 1.f / SF.second.w; - - for (uint32_t w = 0; w <= SF.second.w; w++) + float z = cp1.second[h].z; + float R0 = (cp0.second[h] / cp0.first - toPxShared(SFIt->second.vertices[idx0 + h].p)).magnitude(); + float R1 = (cp1.second[h] / cp1.first - toPxShared(SFIt->second.vertices[idx1 + h].p)).magnitude(); + float R = R0 - R1; + float r = 0.25f * (cp1.second[h] / cp1.first - cp0.second[h] / cp0.first).magnitude(); + float conicity = (conicityBot * h + conicityTop * (resH - h)) / resH; + if (R > r) { - for (uint32_t h = 0; h <= SF.second.h; h++) - { - v[w * (SF.second.h + 1) + h].p += ((cp0.second[h] / cp0.first - v[h].p) * (SF.second.w - w) - + (cp1.second[h] / cp1.first - v[SF.second.w * (SF.second.h + 1) + h].p) * w) * invW; - } + float w = std::min(1.f, r / R); + cp1.second[h] = cp1.second[h] * w + p1 * cp1.first * conicity * (1.f - w); + cp1.second[h].z = z; } } } - Mesh* getNoisyCuttingCone(const std::vector<physx::PxVec3>& points, const std::set<int32_t>& smoothingGroups, - const physx::PxTransform& transform, bool useSmoothing, float heightBot, float heightTop, float conicityMultiplierBot, float conicityMultiplierTop, - physx::PxVec3 samplingInterval, uint32_t interiorMaterialId, const SharedFacesMap& sharedFacesMap, bool inverseNormals) + for (int32_t p = pointCount - 1; p >= 0; p--) { - uint32_t pointCount = points.size(); - uint32_t resP = pointCount; - for (uint32_t i = 0; i < pointCount; i++) + auto p0 = points[p]; + auto p1 = points[unsignedMod(p - 1, pointCount)]; + auto& cp0 = newCutoutPoints.find(p0)->second; + auto& cp1 = newCutoutPoints.find(p1)->second; + + auto SFIt = sharedFacesMap.find(std::make_pair(p0, p1)); + uint32_t idx0 = 0, idx1; + if (SFIt == sharedFacesMap.end()) { - auto vec = (points[(i + 1) % pointCount] - points[i]); - resP += (uint32_t)(std::abs(vec.x) / samplingInterval.x + std::abs(vec.y) / samplingInterval.y); + SFIt = sharedFacesMap.find(std::make_pair(p1, p0)); + idx1 = 0; + idx0 = SFIt->second.w * (SFIt->second.h + 1); } - uint32_t resH = std::max((uint32_t)std::roundf((heightBot + heightTop) / samplingInterval.z), 1u); - - std::vector<Vertex> positions; positions.reserve((resH + 1) * (resP + 1)); - std::vector<Edge> edges; edges.reserve(resH * resP * 6 + (resP + 1) * 2); - std::vector<Facet> facets; facets.reserve(resH * resP * 2 + 2); - - uint32_t pCount = 0; - int sg = useSmoothing ? 1 : -1; - for (uint32_t p = 0; p < pointCount; p++) + else { - if (useSmoothing && smoothingGroups.find(p) != smoothingGroups.end()) - { - sg = sg ^ 3; - } - auto p0 = points[p]; - auto p1 = points[(p + 1) % pointCount]; - - uint32_t firstVertexIndex = positions.size(); - uint32_t firstEdgeIndex = edges.size(); - - auto sfIt = sharedFacesMap.find(std::make_pair(p0, p1)); - int32_t vBegin = 0, vEnd = -1, vIncr = 1; - if (sfIt == sharedFacesMap.end()) - { - sfIt = sharedFacesMap.find(std::make_pair(p1, p0));; - vBegin = sfIt->second.w; - vIncr = -1; - } - else - { - vEnd = sfIt->second.w + 1; - } - - auto& SF = sfIt->second; - positions.resize(firstVertexIndex + (SF.w + 1) * (SF.h + 1)); - if (vBegin < vEnd) - { - for (auto& e : SF.edges) - { - edges.push_back(Edge(e.s + firstVertexIndex, e.e + firstVertexIndex)); - } - for (auto& f : SF.facets) - { - facets.push_back(f); - facets.back().firstEdgeNumber += firstEdgeIndex; - facets.back().smoothingGroup = sg; - } - } - else - { - fillEdgesAndFaces(edges, facets, SF.h, SF.w, firstVertexIndex, positions.size(), SF.f.userData, SF.f.materialId, sg, true); - } - for (int32_t v = vBegin; v != vEnd; v += vIncr) - { - std::copy(SF.vertices.begin() + v * (resH + 1), SF.vertices.begin() + (v + 1) * (SF.h + 1), positions.begin() + firstVertexIndex); - firstVertexIndex += SF.h + 1; - } - pCount += SF.vertices.size() / (resH + 1) - 1; + idx1 = SFIt->second.w * (SFIt->second.h + 1); } - if (inverseNormals) + for (uint32_t h = 0; h <= resH; h++) { - for (uint32_t e = 0; e < edges.size(); e += 3) + float z = cp1.second[h].z; + float R0 = (cp0.second[h] / cp0.first - toPxShared(SFIt->second.vertices[idx0 + h].p)).magnitude(); + float R1 = (cp1.second[h] / cp1.first - toPxShared(SFIt->second.vertices[idx1 + h].p)).magnitude(); + float R = R0 - R1; + float r = 0.25f * (cp1.second[h] / cp1.first - cp0.second[h] / cp0.first).magnitude(); + float conicity = (conicityBot * h + conicityTop * (resH - h)) / resH; + if (R > r) { - std::swap(edges[e + 0].s, edges[e + 0].e); - std::swap(edges[e + 1].s, edges[e + 1].e); - std::swap(edges[e + 2].s, edges[e + 2].e); - std::swap(edges[e + 0], edges[e + 2]); + float w = std::min(1.f, r / R); + cp1.second[h] = cp1.second[h] * w + p1 * cp1.first * conicity * (1.f - w); + cp1.second[h].z = z; } } + } + } - uint32_t totalCount = pCount + pointCount; - calculateNormals(positions, resH, totalCount - 1, inverseNormals); + // glue faces + for (auto& SF : sharedFacesMap) + { + auto& cp0 = newCutoutPoints.find(SF.first.first)->second; + auto& cp1 = newCutoutPoints.find(SF.first.second)->second; + auto& v = SF.second.vertices; + float invW = 1.f / SF.second.w; - std::vector<float> xPos, yPos; - int32_t ii = 0; - for (auto& p : positions) + for (uint32_t w = 0; w <= SF.second.w; w++) + { + for (uint32_t h = 0; h <= SF.second.h; h++) { - if ((ii++) % (resH + 1) == 1) - { - xPos.push_back(p.p.x); - yPos.push_back(p.p.y); - } - p.p = transform.transform(p.p); - p.n = transform.rotate(p.n); + toPxShared(v[w * (SF.second.h + 1) + h].p) += + ((cp0.second[h] / cp0.first - toPxShared(v[h].p)) * (SF.second.w - w) + + (cp1.second[h] / cp1.first - toPxShared(v[SF.second.w * (SF.second.h + 1) + h].p)) * w) * + invW; } - totalCount /= 2; + } + } +} + +Mesh* getNoisyCuttingCone(const std::vector<physx::PxVec3>& points, const std::set<int32_t>& smoothingGroups, + const physx::PxTransform& transform, bool useSmoothing, float heightBot, float heightTop, + float conicityMultiplierBot, float conicityMultiplierTop, physx::PxVec3 samplingInterval, + int32_t interiorMaterialId, const SharedFacesMap& sharedFacesMap, bool inverseNormals) +{ + uint32_t pointCount = points.size(); + uint32_t resP = pointCount; + for (uint32_t i = 0; i < pointCount; i++) + { + auto vec = (points[(i + 1) % pointCount] - points[i]); + resP += (uint32_t)(std::abs(vec.x) / samplingInterval.x + std::abs(vec.y) / samplingInterval.y); + } + uint32_t resH = std::max((uint32_t)std::roundf((heightBot + heightTop) / samplingInterval.z), 1u); + + std::vector<Vertex> positions; + positions.reserve((resH + 1) * (resP + 1)); + std::vector<Edge> edges; + edges.reserve(resH * resP * 6 + (resP + 1) * 2); + std::vector<Facet> facets; + facets.reserve(resH * resP * 2 + 2); + + uint32_t pCount = 0; + int sg = useSmoothing ? 1 : -1; + for (uint32_t p = 0; p < pointCount; p++) + { + if (useSmoothing && smoothingGroups.find(p) != smoothingGroups.end()) + { + sg = sg ^ 3; + } + auto p0 = points[p]; + auto p1 = points[(p + 1) % pointCount]; + + uint32_t firstVertexIndex = positions.size(); + uint32_t firstEdgeIndex = edges.size(); - for (uint32_t i = 0; i < totalCount; i++) + auto sfIt = sharedFacesMap.find(std::make_pair(p0, p1)); + int32_t vBegin = 0, vEnd = -1, vIncr = 1; + if (sfIt == sharedFacesMap.end()) + { + sfIt = sharedFacesMap.find(std::make_pair(p1, p0)); + ; + vBegin = sfIt->second.w; + vIncr = -1; + } + else + { + vEnd = sfIt->second.w + 1; + } + + auto& SF = sfIt->second; + positions.resize(firstVertexIndex + (SF.w + 1) * (SF.h + 1)); + if (vBegin < vEnd) + { + for (auto& e : SF.edges) { - uint32_t idx = 2 * i * (resH + 1); - edges.push_back(Edge(idx, (idx + 2 * (resH + 1)) % positions.size())); + edges.push_back({e.s + firstVertexIndex, e.e + firstVertexIndex}); } - for (int32_t i = totalCount; i > 0; i--) + for (auto& f : SF.facets) { - uint32_t idx = (2 * i + 1) * (resH + 1) - 1; - edges.push_back(Edge(idx % positions.size(), idx - 2 * (resH + 1))); + facets.push_back(f); + facets.back().firstEdgeNumber += firstEdgeIndex; + facets.back().smoothingGroup = sg; } + } + else + { + fillEdgesAndFaces(edges, facets, SF.h, SF.w, firstVertexIndex, positions.size(), SF.f.userData, + SF.f.materialId, sg, true); + } + for (int32_t v = vBegin; v != vEnd; v += vIncr) + { + std::copy(SF.vertices.begin() + v * (resH + 1), SF.vertices.begin() + (v + 1) * (SF.h + 1), + positions.begin() + firstVertexIndex); + firstVertexIndex += SF.h + 1; + } + pCount += SF.vertices.size() / (resH + 1) - 1; + } - if (smoothingGroups.find(0) != smoothingGroups.end() || smoothingGroups.find(pointCount - 1) != smoothingGroups.end()) - { - if (facets[0].smoothingGroup == facets[facets.size() - 1].smoothingGroup) - { - for (uint32_t i = 0; i < resH; i++) - { - facets[i].smoothingGroup = 4; - } - } - } + if (inverseNormals) + { + for (uint32_t e = 0; e < edges.size(); e += 3) + { + std::swap(edges[e + 0].s, edges[e + 0].e); + std::swap(edges[e + 1].s, edges[e + 1].e); + std::swap(edges[e + 2].s, edges[e + 2].e); + std::swap(edges[e + 0], edges[e + 2]); + } + } - facets.push_back(Facet(resH * pCount * 6, totalCount, interiorMaterialId, 0, -1)); - facets.push_back(Facet(resH * pCount * 6 + totalCount, totalCount, interiorMaterialId, 0, -1)); - 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())); + uint32_t totalCount = pCount + pointCount; + calculateNormals(positions, resH, totalCount - 1, inverseNormals); + + std::vector<float> xPos, yPos; + int32_t ii = 0; + for (auto& p : positions) + { + if ((ii++) % (resH + 1) == 1) + { + xPos.push_back(p.p.x); + yPos.push_back(p.p.y); } + toPxShared(p.p) = transform.transform(toPxShared(p.p)); + toPxShared(p.n) = transform.rotate(toPxShared(p.n)); + } + totalCount /= 2; + + for (uint32_t i = 0; i < totalCount; i++) + { + uint32_t idx = 2 * i * (resH + 1); + edges.push_back({idx, (idx + 2 * (resH + 1)) % (uint32_t)positions.size()}); + } + for (int32_t i = totalCount; i > 0; i--) + { + uint32_t idx = (2 * i + 1) * (resH + 1) - 1; + edges.push_back({ idx % (uint32_t)positions.size(), idx - 2 * (resH + 1)}); + } - Mesh* getCuttingCone(const CutoutConfiguration& conf, const std::vector<physx::PxVec3>& points, const std::set<int32_t>& smoothingGroups, - float heightBot, float heightTop, float conicityBot, float conicityTop, - int64_t& id, int32_t seed, int32_t interiorMaterialId, const SharedFacesMap& sharedFacesMap, bool inverseNormals) + if (smoothingGroups.find(0) != smoothingGroups.end() || smoothingGroups.find(pointCount - 1) != smoothingGroups.end()) + { + if (facets[0].smoothingGroup == facets[facets.size() - 1].smoothingGroup) { - uint32_t pointCount = points.size(); - if (conf.noise.amplitude > FLT_EPSILON) + for (uint32_t i = 0; i < resH; i++) { - return getNoisyCuttingCone(points, smoothingGroups, conf.transform, conf.useSmoothing, heightBot, heightTop, conicityBot, conicityTop, - conf.noise.samplingInterval, interiorMaterialId, sharedFacesMap, inverseNormals); + facets[i].smoothingGroup = 4; } + } + } - float currentP = 0; - std::vector<Vertex> positions((pointCount + 1) * 2); - std::vector<Edge> edges(pointCount * 6 + 2); - std::vector<Facet> facets(pointCount + 2); + facets.push_back({ (int32_t)(resH * pCount * 6), totalCount, 0, interiorMaterialId, -1 }); + facets.push_back({ (int32_t)(resH * pCount * 6 + totalCount), totalCount, 0, interiorMaterialId, -1 }); + 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())); +} - int sg = conf.useSmoothing ? 1 : -1; - for (uint32_t i = 0; i < pointCount + 1; i++) - { - if (conf.useSmoothing && smoothingGroups.find(i) != smoothingGroups.end()) - { - sg = sg ^ 3; - } - uint32_t i1 = i + pointCount + 1; - uint32_t i3 = i + 1; - uint32_t i2 = i3 + pointCount + 1; - - auto& p0 = positions[i]; - auto& p1 = positions[i1]; - p0.n = p1.n = physx::PxVec3(0.f, 0.f, 0.f); - p0.p = points[i % pointCount] * conicityBot; - p0.p.z = -heightBot; - p1.p = points[i % pointCount] * conicityTop; - p1.p.z = heightTop; - p0.p = conf.transform.transform(p0.p); - p1.p = conf.transform.transform(p1.p); - p0.uv[0] = PxVec2(0.f, CYLINDER_UV_SCALE * currentP / (heightBot + heightTop)); - p1.uv[0] = PxVec2(CYLINDER_UV_SCALE, CYLINDER_UV_SCALE * currentP / (heightBot + heightTop)); - if (i == pointCount) - { - break; - } - currentP += (points[(i + 1) % pointCount] - points[i]).magnitude(); - - int32_t edgeIdx = 4 * i; - if (inverseNormals) - { - edges[edgeIdx + 1] = Edge(i1, i2); - edges[edgeIdx + 2] = Edge(i2, i3); - edges[edgeIdx + 3] = Edge(i3, i); - edges[edgeIdx + 0] = Edge(i, i1); - } - else - { - edges[edgeIdx + 0] = Edge(i, i3); - edges[edgeIdx + 1] = Edge(i3, i2); - edges[edgeIdx + 2] = Edge(i2, i1); - edges[edgeIdx + 3] = Edge(i1, i); - } - facets[i] = Facet(edgeIdx, 4, interiorMaterialId, id, sg); +Mesh* getCuttingCone(const CutoutConfiguration& conf, const std::vector<physx::PxVec3>& points, + const std::set<int32_t>& smoothingGroups, float heightBot, float heightTop, float conicityBot, + float conicityTop, int64_t& id, int32_t seed, int32_t interiorMaterialId, + const SharedFacesMap& sharedFacesMap, bool inverseNormals) +{ + uint32_t pointCount = points.size(); + if (conf.noise.amplitude > FLT_EPSILON) + { + return getNoisyCuttingCone(points, smoothingGroups, toPxShared(conf.transform), conf.useSmoothing, heightBot, heightTop, + conicityBot, conicityTop, toPxShared(conf.noise.samplingInterval), interiorMaterialId, + sharedFacesMap, inverseNormals); + } - edges[5 * pointCount + i + 1] = Edge(i1, i2); - edges[5 * pointCount - i - 1] = Edge(i3, i); - } - edges[5 * pointCount] = Edge(0, pointCount); - edges[6 * pointCount + 1] = Edge(2 * pointCount + 1, pointCount + 1); + float currentP = 0; + std::vector<Vertex> positions((pointCount + 1) * 2); + std::vector<Edge> edges(pointCount * 6 + 2); + std::vector<Facet> facets(pointCount + 2); - if (smoothingGroups.find(0) != smoothingGroups.end() || smoothingGroups.find(pointCount - 1) != smoothingGroups.end()) - { - if (facets[0].smoothingGroup == facets[pointCount - 1].smoothingGroup) - { - facets[0].smoothingGroup = 4; - } - } + int sg = conf.useSmoothing ? 1 : -1; + for (uint32_t i = 0; i < pointCount + 1; i++) + { + if (conf.useSmoothing && smoothingGroups.find(i) != smoothingGroups.end()) + { + sg = sg ^ 3; + } + uint32_t i1 = i + pointCount + 1; + uint32_t i3 = i + 1; + uint32_t i2 = i3 + pointCount + 1; + + auto& p0 = positions[i]; + auto& p1 = positions[i1]; + p0.n = p1.n = {0.f, 0.f, 0.f}; + toPxShared(p0.p) = points[i % pointCount] * conicityBot; + p0.p.z = -heightBot; + toPxShared(p1.p) = points[i % pointCount] * conicityTop; + p1.p.z = heightTop; + toPxShared(p0.p) = toPxShared(conf.transform).transform(toPxShared(p0.p)); + toPxShared(p1.p) = toPxShared(conf.transform).transform(toPxShared(p1.p)); + p0.uv[0] = {0.f, CYLINDER_UV_SCALE * currentP / (heightBot + heightTop)}; + p1.uv[0] = {CYLINDER_UV_SCALE, CYLINDER_UV_SCALE * currentP / (heightBot + heightTop)}; + if (i == pointCount) + { + break; + } + currentP += (points[(i + 1) % pointCount] - points[i]).magnitude(); - facets[pointCount + 0] = Facet(4 * pointCount, pointCount + 1, interiorMaterialId, 0, -1); - facets[pointCount + 1] = Facet(5 * pointCount + 1, pointCount + 1, interiorMaterialId, 0, -1); - 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())); + int32_t edgeIdx = 4 * i; + if (inverseNormals) + { + edges[edgeIdx + 1] = {i1, i2}; + edges[edgeIdx + 2] = {i2, i3}; + edges[edgeIdx + 3] = {i3, i}; + edges[edgeIdx + 0] = {i, i1}; + } + else + { + edges[edgeIdx + 0] = {i, i3}; + edges[edgeIdx + 1] = {i3, i2}; + edges[edgeIdx + 2] = {i2, i1}; + edges[edgeIdx + 3] = {i1, i}; } + facets[i] = {edgeIdx, 4, id, interiorMaterialId, sg}; + edges[5 * pointCount + i + 1] = {i1, i2}; + edges[5 * pointCount - i - 1] = {i3, i}; } -}
\ No newline at end of file + edges[5 * pointCount] = {0, pointCount}; + edges[6 * pointCount + 1] = {2 * pointCount + 1, pointCount + 1}; + + if (smoothingGroups.find(0) != smoothingGroups.end() || smoothingGroups.find(pointCount - 1) != smoothingGroups.end()) + { + if (facets[0].smoothingGroup == facets[pointCount - 1].smoothingGroup) + { + facets[0].smoothingGroup = 4; + } + } + + facets[pointCount + 0] = { 4 * (int32_t)pointCount, pointCount + 1, 0, interiorMaterialId, -1 }; + facets[pointCount + 1] = { 5 * (int32_t)pointCount + 1, pointCount + 1, interiorMaterialId, 0, -1 }; + 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 +} // namespace Nv
\ No newline at end of file diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.h index b4841ef..eb1d458 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.h @@ -77,8 +77,7 @@ typedef std::map<physx::PxVec3, std::map<uint32_t, uint32_t>, CmpVec> PointMap; struct SharedFace { SharedFace() {} - SharedFace(uint32_t inW, uint32_t inH, int64_t inUD, int32_t inMatId) - : w(inW), h(inH), f(0, 3, inMatId, inUD) + SharedFace(uint32_t inW, uint32_t inH, int64_t inUD, int32_t inMatId) : w(inW), h(inH), f(Facet( 0, 3, inUD, inMatId )) { vertices.reserve((w + 1) * (h + 1)); } diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp index f12c931..000767a 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp @@ -35,9 +35,9 @@ #include "NvBlastExtAuthoringBooleanTool.h" #include "NvBlastExtAuthoringTriangulator.h" #include "NvBlastExtAuthoringPerlinNoise.h" +#include <NvBlastPxSharedHelpers.h> #include <vector> -#include "PxVec3.h" using namespace Nv::Blast; using namespace physx; @@ -49,7 +49,7 @@ struct DamagePatternImpl : public DamagePattern DamagePattern* PatternGeneratorImpl::generateUniformPattern(const UniformPatternDesc* desc) { - std::vector<PxVec3> points; + std::vector<NvcVec3> points; float radiusDelta = desc->radiusMax - desc->radiusMin; for (uint32_t i = 0; i < desc->cellsCount; ++i) { @@ -67,7 +67,7 @@ DamagePattern* PatternGeneratorImpl::generateUniformPattern(const UniformPattern float y = rd * sin(phi) * sin(theta); float z = rd * cos(theta); - points.push_back(PxVec3(x, y, z)); + points.push_back({x, y, z}); } @@ -76,23 +76,23 @@ DamagePattern* PatternGeneratorImpl::generateUniformPattern(const UniformPattern return pattern; } -DamagePattern* PatternGeneratorImpl::generateVoronoiPattern(uint32_t cellCount, const physx::PxVec3* inPoints, int32_t interiorMaterialId) +DamagePattern* PatternGeneratorImpl::generateVoronoiPattern(uint32_t cellCount, const NvcVec3* inPoints, int32_t interiorMaterialId) { return generateVoronoiPatternInternal(cellCount, inPoints, interiorMaterialId); } -DamagePattern* PatternGeneratorImpl::generateVoronoiPatternInternal(uint32_t cellCount, const physx::PxVec3* inPoints, int32_t interiorMaterialId, float angle) +DamagePattern* PatternGeneratorImpl::generateVoronoiPatternInternal(uint32_t cellCount, const NvcVec3* inPoints, int32_t interiorMaterialId, float angle) { DamagePatternImpl* pattern = NVBLAST_NEW(DamagePatternImpl); - std::vector<PxVec3> points(cellCount); - physx::PxVec3 orig(0.f); + std::vector<NvcVec3> points(cellCount); + NvcVec3 orig = {0, 0, 0}; for (uint32_t i = 0; i < cellCount; ++i) { points[i] = inPoints[i]; - orig += points[i]; + orig = orig + points[i]; } - orig /= cellCount; + orig = orig / cellCount; std::vector<std::vector<int32_t> > neighboors; findCellBasePlanes(points, neighboors); @@ -153,7 +153,7 @@ DamagePattern* PatternGeneratorImpl::generateVoronoiPatternInternal(uint32_t cel DamagePattern* PatternGeneratorImpl::generateBeamPattern(const BeamPatternDesc* desc) { - std::vector<PxVec3> points; + std::vector<NvcVec3> points; float radiusDelta = desc->radiusMax - desc->radiusMin; @@ -165,7 +165,7 @@ DamagePattern* PatternGeneratorImpl::generateBeamPattern(const BeamPatternDesc* float x = rd * cos(phi); float y = rd * sin(phi); float z = desc->RNG() - 1; - points.push_back(PxVec3(x, y, z)); + points.push_back({x, y, z}); } auto pattern = generateVoronoiPattern((uint32_t)points.size(), points.data(), desc->interiorMaterialId); pattern->activationType = DamagePattern::Line; @@ -205,7 +205,7 @@ DamagePattern* PatternGeneratorImpl::generateRegularRadialPattern(const RegularR float ap = std::max(0.0f, desc->aperture); - auto pattern = generateVoronoiPatternInternal((uint32_t)points.size(), points.data(), desc->interiorMaterialId, ap); + auto pattern = generateVoronoiPatternInternal((uint32_t)points.size(), fromPxShared(points.data()), desc->interiorMaterialId, ap); pattern->activationRadius = desc->radiusMax * desc->debrisRadiusMult; pattern->activationType = (ap == 0) ? DamagePattern::Line : DamagePattern::Cone; diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.h index 566cf71..98e3842 100644 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.h @@ -46,9 +46,9 @@ namespace Blast virtual DamagePattern* generateRegularRadialPattern(const RegularRadialPatternDesc* desc) override; virtual void release() override; - virtual DamagePattern* generateVoronoiPattern(uint32_t pointCount, const physx::PxVec3* points, int32_t interiorMaterialId) override; + virtual DamagePattern* generateVoronoiPattern(uint32_t pointCount, const NvcVec3* points, int32_t interiorMaterialId) override; private: - DamagePattern* generateVoronoiPatternInternal(uint32_t pointCount, const physx::PxVec3* points, int32_t interiorMaterialId, float angle = 0.0f); + DamagePattern* generateVoronoiPatternInternal(uint32_t pointCount, const NvcVec3* points, int32_t interiorMaterialId, float angle = 0.0f); }; diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h b/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h index 3cb65c1..a47c40e 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h @@ -29,8 +29,7 @@ #ifndef NVBLASTEXTAUTHORINGPERLINNOISE_H
#define NVBLASTEXTAUTHORINGPERLINNOISE_H
-
-#include <NvBlastExtAuthoringTypes.h>
+#include <NvBlastExtAuthoringFractureTool.h>
#include <PxVec4.h>
#include <PxVec3.h>
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp index 79965a1..af04d4a 100755 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp @@ -43,9 +43,10 @@ #include "NvBlastExtAuthoringBooleanTool.h"
#include <queue>
#include <NvBlastAssert.h>
+#include <NvBlastPxSharedHelpers.h>
-using physx::PxVec3;
using physx::PxVec2;
+using physx::PxVec3;
namespace Nv
{
@@ -79,18 +80,18 @@ NV_FORCE_INLINE bool pointInside(PxVec2 a, PxVec2 b, PxVec2 c, PxVec2 pnt) float v2 = (getRotation((c - b), (pnt - b)));
float v3 = (getRotation((a - c), (pnt - c)));
- return (v1 >= 0.0f && v2 >= 0.0f && v3 >= 0.0f) ||
- (v1 <= 0.0f && v2 <= 0.0f && v3 <= 0.0f);
-
+ return (v1 >= 0.0f && v2 >= 0.0f && v3 >= 0.0f) || (v1 <= 0.0f && v2 <= 0.0f && v3 <= 0.0f);
}
-void Triangulator::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)
+ // for (uint32_t i = 0; i < inputPolygon.size(); ++i)
//{
- // mBaseMeshTriangles.push_back(TriangleIndexed(inputPolygon[i], inputPolygon[i], inputPolygon[(i + 1) % inputPolygon.size()]));
+ // mBaseMeshTriangles.push_back(TriangleIndexed(inputPolygon[i], inputPolygon[i], inputPolygon[(i + 1) %
+ //inputPolygon.size()]));
//}
- //return;
+ // return;
int32_t vCount = static_cast<int32_t>(inputPolygon.size());
if (vCount < 3)
@@ -112,13 +113,15 @@ void Triangulator::triangulatePolygonWithEarClipping(std::vector<uint32_t>& inpu // Check wheather curr is ear-tip
float rot = getRotation((pVp - nVp).getNormalized(), (cVp - nVp).getNormalized());
- if (!(dir & OPPOSITE_WINDING)) rot = -rot;
+ if (!(dir & OPPOSITE_WINDING))
+ rot = -rot;
if (rot > 0.0001)
{
bool good = true;
for (int vrt = 0; vrt < vCount; ++vrt)
{
- if (vrt == curr || vrt == prev || vrt == next) continue;
+ if (vrt == curr || vrt == prev || vrt == next)
+ continue;
if (pointInside(cVp, nVp, pVp, getProjectedPoint(vert[inputPolygon[vrt]].p, dir)))
{
good = false;
@@ -137,7 +140,6 @@ void Triangulator::triangulatePolygonWithEarClipping(std::vector<uint32_t>& inpu }
-
struct LoopInfo
{
LoopInfo()
@@ -154,14 +156,15 @@ struct LoopInfo }
};
-int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t>& internalLoop, Vertex* vrx, ProjectionDirections dir)
+int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t>& internalLoop, Vertex* vrx,
+ ProjectionDirections dir)
{
if (externalLoop.size() < 3 || internalLoop.size() < 3)
return 1;
/**
- Find point with maximum x-coordinate
+ Find point with maximum x-coordinate
*/
- float x_max = -MAXIMUM_EXTENT;
+ float x_max = -MAXIMUM_EXTENT;
int32_t mIndex = -1;
for (uint32_t i = 0; i < internalLoop.size(); ++i)
{
@@ -169,7 +172,7 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> if (nx > x_max)
{
mIndex = i;
- x_max = nx;
+ x_max = nx;
}
}
if (mIndex == -1)
@@ -178,16 +181,16 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> }
/**
- Search for base point on external loop
+ Search for base point on external loop
*/
- float minX = MAXIMUM_EXTENT;
- int32_t vrtIndex = -1;
+ float minX = MAXIMUM_EXTENT;
+ int32_t vrtIndex = -1;
bool isFromBuffer = 0;
- PxVec2 holePoint = getProjectedPoint(vrx[internalLoop[mIndex]].p, dir);
+ PxVec2 holePoint = getProjectedPoint(vrx[internalLoop[mIndex]].p, dir);
PxVec2 computedPoint;
for (uint32_t i = 0; i < externalLoop.size(); ++i)
{
- int32_t nx = (i + 1) % externalLoop.size();
+ int32_t nx = (i + 1) % externalLoop.size();
PxVec2 pnt1 = getProjectedPoint(vrx[externalLoop[i]].p, dir);
PxVec2 pnt2 = getProjectedPoint(vrx[externalLoop[nx]].p, dir);
if (pnt1.x < x_max && pnt2.x < x_max)
@@ -199,14 +202,14 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> {
if (pnt1.x < minX && pnt1.x < pnt2.x && pnt1.x > x_max)
{
- minX = pnt1.x;
- vrtIndex = i;
+ minX = pnt1.x;
+ vrtIndex = i;
isFromBuffer = true;
}
if (pnt2.x < minX && pnt2.x < pnt1.x && pnt2.x > x_max)
{
- minX = pnt2.x;
- vrtIndex = nx;
+ minX = pnt2.x;
+ vrtIndex = nx;
isFromBuffer = true;
}
}
@@ -218,9 +221,9 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> PxVec2 tempPoint = vc * t + pnt1;
if (tempPoint.x < minX && tempPoint.x > x_max)
{
- minX = tempPoint.x;
- vrtIndex = i;
- isFromBuffer = false;
+ minX = tempPoint.x;
+ vrtIndex = i;
+ isFromBuffer = false;
computedPoint = tempPoint;
}
}
@@ -232,7 +235,7 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> return 1;
}
int32_t bridgePoint = -1;
- float bestAngle = 100;
+ float bestAngle = 100;
if (!isFromBuffer)
{
PxVec2 ex1 = getProjectedPoint(vrx[externalLoop[vrtIndex]].p, dir);
@@ -241,7 +244,7 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> if (ex1.x > ex2.x)
{
vrtIndex = (vrtIndex + 1) % externalLoop.size();
- ex1 = ex2;
+ ex1 = ex2;
}
/* Check if some point is inside triangle */
bool notFound = true;
@@ -250,18 +253,20 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> PxVec2 tempPoint = getProjectedPoint(vrx[externalLoop[i]].p, dir);
if (pointInside(holePoint, ex1, computedPoint, tempPoint))
{
- notFound = false;
+ notFound = false;
PxVec2 cVp = getProjectedPoint(vrx[externalLoop[i]].p, dir);
- PxVec2 pVp = getProjectedPoint(vrx[externalLoop[(i - 1 + externalLoop.size()) % externalLoop.size()]].p, dir);
+ PxVec2 pVp =
+ getProjectedPoint(vrx[externalLoop[(i - 1 + externalLoop.size()) % externalLoop.size()]].p, dir);
PxVec2 nVp = getProjectedPoint(vrx[externalLoop[(i + 1) % externalLoop.size()]].p, dir);
- float rt = getRotation((cVp - pVp).getNormalized(), (nVp - pVp).getNormalized());
- if ((dir & OPPOSITE_WINDING)) rt = -rt;
+ float rt = getRotation((cVp - pVp).getNormalized(), (nVp - pVp).getNormalized());
+ if ((dir & OPPOSITE_WINDING))
+ rt = -rt;
if (rt < 0.000001)
continue;
float tempAngle = PxVec2(1, 0).dot((tempPoint - holePoint).getNormalized());
if (bestAngle < tempAngle)
{
- bestAngle = tempAngle;
+ bestAngle = tempAngle;
bridgePoint = i;
}
}
@@ -300,7 +305,8 @@ int32_t unitePolygons(std::vector<uint32_t>& externalLoop, std::vector<uint32_t> return 0;
}
-void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* vertices, int32_t userData, int32_t materialId, int32_t smoothingGroup)
+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;
@@ -315,9 +321,9 @@ void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* edgesIds.push_back(0);
visitedVertices.insert(edges[0].s);
visitedVertices.insert(edges[0].e);
- used[0] = true;
- collected = 1;
- uint32_t lastEdge = 0;
+ used[0] = true;
+ collected = 1;
+ uint32_t lastEdge = 0;
bool successfullPass = false;
for (; collected < edges.size();)
{
@@ -331,7 +337,8 @@ void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* used[p] = true;
edgesIds.push_back(p);
lastEdge = p;
- if (visitedVertices.find(edges[p].e) != visitedVertices.end()) // if we formed loop, detach it and triangulate
+ if (visitedVertices.find(edges[p].e) != visitedVertices.end()) // if we formed loop, detach it and
+ // triangulate
{
serializedLoops.push_back(std::vector<uint32_t>());
std::vector<uint32_t>& serializedPositions = serializedLoops.back();
@@ -388,11 +395,12 @@ void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* std::vector<uint32_t>& pos = serializedLoops[loop];
for (uint32_t vrt = 1; vrt + 1 < serializedLoops[loop].size(); ++vrt)
{
- loopNormal += (vertices[pos[vrt]].p - vertices[pos[0]].p).cross(vertices[pos[vrt + 1]].p - vertices[pos[0]].p);
+ loopNormal += toPxShared(vertices[pos[vrt]].p - vertices[pos[0]].p)
+ .cross(toPxShared(vertices[pos[vrt + 1]].p - vertices[pos[0]].p));
}
- loopsInfo[loop].area = loopNormal.magnitude();
+ loopsInfo[loop].area = loopNormal.magnitude();
loopsInfo[loop].normal = loopNormal;
- loopsInfo[loop].index = loop;
+ loopsInfo[loop].index = loop;
wholeFacetNormal += loopNormal;
}
@@ -413,12 +421,13 @@ void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* {
if (loopsInfo[extPoly].area < 0)
{
- continue; // Polygon with negative area is hole
+ continue; // Polygon with negative area is hole
}
int32_t baseLoop = loopsInfo[extPoly].index;
for (uint32_t intPoly = 0; intPoly < loopsInfo.size(); ++intPoly)
{
- if (loopsInfo[intPoly].area > 0 || loopsInfo[intPoly].used || std::abs(loopsInfo[intPoly].area) > loopsInfo[extPoly].area)
+ if (loopsInfo[intPoly].area > 0 || loopsInfo[intPoly].used ||
+ std::abs(loopsInfo[intPoly].area) > loopsInfo[extPoly].area)
{
continue;
}
@@ -429,12 +438,12 @@ void Triangulator::buildPolygonAndTriangulate(std::vector<Edge>& edges, Vertex* loopsInfo[intPoly].used = true;
};
}
- triangulatePolygonWithEarClipping(serializedLoops[baseLoop],vertices, dir);
+ triangulatePolygonWithEarClipping(serializedLoops[baseLoop], vertices, dir);
}
for (uint32_t i = oldSize; i < mBaseMeshTriangles.size(); ++i)
{
- mBaseMeshTriangles[i].userData = userData;
- mBaseMeshTriangles[i].materialId = materialId;
+ mBaseMeshTriangles[i].userData = userData;
+ mBaseMeshTriangles[i].materialId = materialId;
mBaseMeshTriangles[i].smoothingGroup = smoothingGroup;
}
}
@@ -467,23 +476,22 @@ NV_FORCE_INLINE void Triangulator::addEdgeIfValid(EdgeWithParent& ed) }
else
{
- if (mBaseMeshEdges[it->second].s == NOT_VALID_VERTEX)
+ if (mBaseMeshEdges[it->second].s == kNotValidVertexIndex)
{
mBaseMeshEdges[it->second].s = ed.s;
mBaseMeshEdges[it->second].e = ed.e;
}
else
{
- mBaseMeshEdges[it->second].s = NOT_VALID_VERTEX;
+ mBaseMeshEdges[it->second].s = kNotValidVertexIndex;
}
}
}
-
void Triangulator::prepare(const Mesh* mesh)
{
- const Edge* ed = mesh->getEdges();
+ const Edge* ed = mesh->getEdges();
const Vertex* vr = mesh->getVertices();
mBaseMapping.resize(mesh->getVerticesCount());
for (uint32_t i = 0; i < mesh->getFacetCount(); ++i)
@@ -491,8 +499,8 @@ void Triangulator::prepare(const Mesh* mesh) 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]);
- int32_t b = addVerticeIfNotExist(vr[ed[j].e]);
+ int32_t a = addVerticeIfNotExist(vr[ed[j].s]);
+ int32_t b = addVerticeIfNotExist(vr[ed[j].e]);
mBaseMapping[ed[j].s] = a;
mBaseMapping[ed[j].e] = b;
EdgeWithParent e(a, b, i);
@@ -503,7 +511,7 @@ void Triangulator::prepare(const Mesh* mesh) temp.reserve(mBaseMeshEdges.size());
for (uint32_t i = 0; i < mBaseMeshEdges.size(); ++i)
{
- if (mBaseMeshEdges[i].s != NOT_VALID_VERTEX)
+ if (mBaseMeshEdges[i].s != kNotValidVertexIndex)
{
temp.push_back(mBaseMeshEdges[i]);
}
@@ -541,36 +549,36 @@ void Triangulator::triangulate(const Mesh* mesh) {
if (temp.empty() == false)
{
- buildPolygonAndTriangulate(temp, mVertices.data(), mesh->getFacet(fP)->userData, mesh->getFacet(fP)->materialId, mesh->getFacet(fP)->smoothingGroup);
+ 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));
+ temp.push_back({ mBaseMeshEdges[i].s, mBaseMeshEdges[i].e });
}
- buildPolygonAndTriangulate(temp, mVertices.data(), mesh->getFacet(fP)->userData, mesh->getFacet(fP)->materialId, mesh->getFacet(fP)->smoothingGroup);
+ 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)
{
- if (mBaseMeshTriangles[i].ea == NOT_VALID_VERTEX)
+ if (mBaseMeshTriangles[i].ea == kNotValidVertexIndex)
{
continue;
}
- mBaseMeshResultTriangles.push_back(Triangle(mVertices[mBaseMeshTriangles[i].ea], mVertices[mBaseMeshTriangles[i].eb], mVertices[mBaseMeshTriangles[i].ec]));
- mBaseMeshResultTriangles.back().userData = mBaseMeshTriangles[i].userData;
- mBaseMeshResultTriangles.back().materialId = mBaseMeshTriangles[i].materialId;
- mBaseMeshResultTriangles.back().smoothingGroup = mBaseMeshTriangles[i].smoothingGroup;
-
+ mBaseMeshResultTriangles.push_back({ mVertices[mBaseMeshTriangles[i].ea], mVertices[mBaseMeshTriangles[i].eb],
+ mVertices[mBaseMeshTriangles[i].ec], mBaseMeshTriangles[i].userData,
+ mBaseMeshTriangles[i].materialId, mBaseMeshTriangles[i].smoothingGroup });
}
- mBaseMeshUVFittedTriangles = mBaseMeshResultTriangles; // Uvs will be fitted later, in FractureTool.
+ mBaseMeshUVFittedTriangles = mBaseMeshResultTriangles; // Uvs will be fitted later, in FractureTool.
computePositionedMapping();
}
void Triangulator::computePositionedMapping()
{
- std::map<PxVec3, int32_t, VrtPositionComparator> mPosMap;
+ std::map<NvcVec3, int32_t, VrtPositionComparator> mPosMap;
mPositionMappedVrt.clear();
mPositionMappedVrt.resize(mVertices.size());
@@ -581,7 +589,7 @@ void Triangulator::computePositionedMapping() if (it == mPosMap.end())
{
mPosMap[mVertices[i].p] = i;
- mPositionMappedVrt[i] = i;
+ mPositionMappedVrt[i] = i;
}
else
{
@@ -590,5 +598,5 @@ void Triangulator::computePositionedMapping() }
}
-} // namespace Blast
-} // namespace Nv
\ No newline at end of file +} // namespace Blast
+} // namespace Nv
\ No newline at end of file diff --git a/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h b/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h index 132edad..cf60469 100755 --- a/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h +++ b/sdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h @@ -29,7 +29,8 @@ #ifndef NVBLASTEXTTRIANGLEPROCESSOR_H
#define NVBLASTEXTTRIANGLEPROCESSOR_H
-#include <PxPhysicsAPI.h>
+#include <PxVec2.h>
+#include <PxVec3.h>
#include <vector>
#include <algorithm>
@@ -40,9 +41,9 @@ namespace Nv {
namespace Blast
{
-
+
/**
- Triangle processor internal triangle representation. Contains only vertex positions.
+ Triangle processor internal triangle representation. Contains only vertex positions.
*/
struct TrPrcTriangle
{
@@ -75,7 +76,7 @@ struct TrPrcTriangle };
/**
- Triangle processor internal 2D triangle representation. Contains only vertex positions.
+ Triangle processor internal 2D triangle representation. Contains only vertex positions.
*/
struct TrPrcTriangle2d
{
@@ -105,72 +106,68 @@ struct TrPrcTriangle2d class TriangleProcessor
{
-public:
-
+ public:
+ TriangleProcessor(){};
+ ~TriangleProcessor() {}
- TriangleProcessor()
- {};
- ~TriangleProcessor()
- {
- }
-
/**
- Build intersection between two triangles
- \param[in] a First triangle (A)
- \param[in] aProjected Projected triangle A
- \param[in] b Second triangle (B)
- \param[in] centroid Centroid of first triangle (A)
- \param[out] intersectionBuffer Result intersection polygon
- \param[in] normal Normal vector to triangle (Common for both A and B).
- \return 1 - if if intersection is found.
- */
- uint32_t getTriangleIntersection(TrPrcTriangle& a, TrPrcTriangle2d& aProjected, TrPrcTriangle &b, PxVec3& centroid, std::vector<PxVec3>& intersectionBuffer, PxVec3 normal);
+ Build intersection between two triangles
+ \param[in] a First triangle (A)
+ \param[in] aProjected Projected triangle A
+ \param[in] b Second triangle (B)
+ \param[in] centroid Centroid of first triangle (A)
+ \param[out] intersectionBuffer Result intersection polygon
+ \param[in] normal Normal vector to triangle (Common for both A and B).
+ \return 1 - if if intersection is found.
+ */
+ uint32_t getTriangleIntersection(TrPrcTriangle& a, TrPrcTriangle2d& aProjected, TrPrcTriangle& b, PxVec3& centroid,
+ std::vector<PxVec3>& intersectionBuffer, PxVec3 normal);
/**
- Test whether BB of triangles intersect.
- \param[in] a First triangle (A)
- \param[in] b Second triangle (B)
- \return true - if intersect
+ Test whether BB of triangles intersect.
+ \param[in] a First triangle (A)
+ \param[in] b Second triangle (B)
+ \return true - if intersect
*/
- bool triangleBoundingBoxIntersection(TrPrcTriangle2d& a, TrPrcTriangle2d& b);
-
+ bool triangleBoundingBoxIntersection(TrPrcTriangle2d& a, TrPrcTriangle2d& b);
+
/**
- Test whether point is inside of triangle.
- \param[in] point Point coordinates in 2d space.
- \param[in] triangle Triangle in 2d space.
- \return 1 - if inside, 2 if on edge, 0 if neither inside nor edge.
+ Test whether point is inside of triangle.
+ \param[in] point Point coordinates in 2d space.
+ \param[in] triangle Triangle in 2d space.
+ \return 1 - if inside, 2 if on edge, 0 if neither inside nor edge.
*/
- uint32_t isPointInside(const PxVec2& point, const TrPrcTriangle2d& triangle);
+ uint32_t isPointInside(const PxVec2& point, const TrPrcTriangle2d& triangle);
/**
- Segment intersection point
- \param[in] s1 Segment-1 start point
- \param[in] e1 Segment-1 end point
- \param[in] s2 Segment-2 start point
- \param[in] e2 Segment-2 end point
- \param[out] t1 Intersection point parameter relatively to Segment-1, lies in [0.0, 1.0] range.
- \return 0 if there is no intersections, 1 - if intersection is found.
+ Segment intersection point
+ \param[in] s1 Segment-1 start point
+ \param[in] e1 Segment-1 end point
+ \param[in] s2 Segment-2 start point
+ \param[in] e2 Segment-2 end point
+ \param[out] t1 Intersection point parameter relatively to Segment-1, lies in [0.0, 1.0] range.
+ \return 0 if there is no intersections, 1 - if intersection is found.
*/
- uint32_t getSegmentIntersection(const PxVec2& s1, const PxVec2& e1, const PxVec2& s2, const PxVec2& e2, PxF32& t1);
+ uint32_t getSegmentIntersection(const PxVec2& s1, const PxVec2& e1, const PxVec2& s2, const PxVec2& e2, PxF32& t1);
/**
- Sort vertices of polygon in CCW-order
+ Sort vertices of polygon in CCW-order
*/
- void sortToCCW(std::vector<PxVec3>& points, PxVec3& normal);
-
+ void sortToCCW(std::vector<PxVec3>& points, PxVec3& normal);
+
/**
- Builds convex polygon for given set of points. Points should be coplanar.
- \param[in] points Input array of points
- \param[out] convexHull Output polygon
- \param[in] normal Normal vector to polygon.
+ Builds convex polygon for given set of points. Points should be coplanar.
+ \param[in] points Input array of points
+ \param[out] convexHull Output polygon
+ \param[in] normal Normal vector to polygon.
*/
- void buildConvexHull(std::vector<PxVec3>& points, std::vector<PxVec3>& convexHull, const PxVec3& normal);
+ void buildConvexHull(std::vector<PxVec3>& points, std::vector<PxVec3>& convexHull, const PxVec3& normal);
};
-} // namespace Blast
-} // namespace Nv
+} // namespace Blast
+} // namespace Nv
-#endif // NVBLASTEXTTRIANGLEPROCESSOR_H
+#endif // NVBLASTEXTTRIANGLEPROCESSOR_H
diff --git a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringAccelerator.h b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringAccelerator.h index fdbc524..facd6a7 100644 --- a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringAccelerator.h +++ b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringAccelerator.h @@ -54,7 +54,7 @@ namespace Nv \param[in] ed Edge buffer \param[in] fc Facet which should be tested. */ - virtual void setState(const physx::PxBounds3* bounds) = 0; + virtual void setState(const NvcBounds3* bounds) = 0; /** Set state of accelerator to return all facets which possibly can intersect given facet. @@ -67,7 +67,7 @@ namespace Nv 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. */ - virtual void setState(const physx::PxVec3& point) = 0; + virtual void setState(const NvcVec3& point) = 0; /** Recieve next facet for setted state. \return Next facet index, or -1 if no facets left. @@ -92,15 +92,15 @@ namespace Nv \param[in] count Mesh facets count for which accelerator should be built. */ DummyAccelerator(int32_t count); - virtual void setState(const physx::PxBounds3* bounds) override; + virtual void setState(const NvcBounds3* bounds) override; virtual void setState(const Vertex* pos, const Edge* ed, const Facet& fc) override; - virtual void setState(const physx::PxVec3& point) override; + virtual void setState(const NvcVec3& point) override; virtual int32_t getNextFacet() override; virtual void setPointCmpDirection(int32_t dir) override {}; private: - int32_t count; - int32_t current; + int32_t m_count; + int32_t m_current; }; struct SegmentToIndex @@ -132,12 +132,12 @@ namespace Nv void setMesh(const Nv::Blast::Mesh* m); private: - int32_t mResolution; - int32_t r3; - int32_t mappedFacetCount; - physx::PxVec3 spos; - physx::PxVec3 deltas; - std::vector< std::vector<int32_t> > mSpatialMap; + int32_t m_resolution; + int32_t m_r3; + int32_t m_mappedFacetCount; + NvcVec3 m_spos; + NvcVec3 m_deltas; + std::vector< std::vector<int32_t> > m_spatialMap; }; class GridWalker : public SpatialAccelerator // Iterator to traverse the grid @@ -145,22 +145,22 @@ namespace Nv public: GridWalker(Grid* grd); - virtual void setState(const physx::PxBounds3* bounds) override; + virtual void setState(const NvcBounds3* bounds) override; virtual void setState(const Vertex* pos, const Edge* ed, const Facet& fc) override; - virtual void setState(const physx::PxVec3& point) override; + virtual void setState(const NvcVec3& point) override; virtual int32_t getNextFacet() override; virtual void setPointCmpDirection(int32_t dir) override; private: - Grid* mGrid; + Grid* m_grid; // Iterator data - std::vector<uint32_t> alreadyGotFlag; - uint32_t alreadyGotValue; - std::vector<int32_t> cellList; - int32_t gotCells; - int32_t mIteratorCell; - int32_t mIteratorFacet; - int32_t pointCmdDir; + std::vector<uint32_t> m_alreadyGotFlag; + uint32_t m_alreadyGotValue; + std::vector<int32_t> m_cellList; + int32_t m_gotCells; + int32_t m_iteratorCell; + int32_t m_iteratorFacet; + int32_t m_pointCmdDir; }; @@ -172,8 +172,8 @@ namespace Nv */ SweepingAccelerator(Nv::Blast::Mesh* in); virtual void setState(const Vertex* pos, const Edge* ed, const Facet& fc) override; - virtual void setState(const physx::PxBounds3* bounds) override; - virtual void setState(const physx::PxVec3& point) override; + virtual void setState(const NvcBounds3* bounds) override; + virtual void setState(const NvcVec3& point) override; virtual int32_t getNextFacet() override; virtual void setPointCmpDirection(int32_t dir) override {}; private: @@ -182,21 +182,21 @@ namespace Nv /* For fast point test. */ - std::vector<std::vector<uint32_t> > xSegm; - std::vector<std::vector<uint32_t> > ySegm; - std::vector<std::vector<uint32_t> > zSegm; - std::vector<uint32_t> indices; - std::vector<uint32_t> foundx; - std::vector<uint32_t> foundy; + std::vector<std::vector<uint32_t> > m_xSegm; + std::vector<std::vector<uint32_t> > m_ySegm; + std::vector<std::vector<uint32_t> > m_zSegm; + std::vector<uint32_t> m_indices; + std::vector<uint32_t> m_foundx; + std::vector<uint32_t> m_foundy; - uint32_t iterId; - int32_t current; - uint32_t facetCount; + uint32_t m_iterId; + int32_t m_current; + uint32_t m_facetCount; - physx::PxVec3 minimal; - physx::PxVec3 maximal; + NvcVec3 m_minimal; + NvcVec3 m_maximal; - physx::PxVec3 rescale; + NvcVec3 m_rescale; }; @@ -218,27 +218,26 @@ namespace Nv virtual ~BBoxBasedAccelerator(); int32_t getNextFacet() override; void setState(const Vertex* pos, const Edge* ed, const Facet& fc) override; - void setState(const physx::PxBounds3* bounds) override; - void setState(const physx::PxVec3& p) override; + void setState(const NvcBounds3* bounds) override; + void setState(const NvcVec3& p) override; void setPointCmpDirection(int32_t dir) override {}; private: void buildAccelStructure(const Vertex* pos, const Edge* edges, const Facet* fc, int32_t facetCount); - int32_t mResolution; - physx::PxBounds3 mBounds; - std::vector< std::vector<int32_t> > mSpatialMap; - std::vector<physx::PxBounds3> mCells; + int32_t m_resolution; + NvcBounds3 m_bounds; + std::vector< std::vector<int32_t> > m_spatialMap; + std::vector<NvcBounds3> m_cells; // Iterator data - std::vector<uint32_t> alreadyGotFlag; - uint32_t alreadyGotValue; - std::vector<int32_t> cellList; - int32_t gotCells; - //std::vector<int32_t> cellList; - int32_t mIteratorCell; - int32_t mIteratorFacet; + std::vector<uint32_t> m_alreadyGotFlag; + uint32_t m_alreadyGotValue; + std::vector<int32_t> m_cellList; + int32_t m_gotCells; + int32_t m_iteratorCell; + int32_t m_iteratorFacet; }; } // namespace Blast diff --git a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringConvexMeshBuilder.h b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringConvexMeshBuilder.h new file mode 100644 index 0000000..7565174 --- /dev/null +++ b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringConvexMeshBuilder.h @@ -0,0 +1,74 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation 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-2018 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTAUTHORINGCONVEXMESHBUILDER_H +#define NVBLASTEXTAUTHORINGCONVEXMESHBUILDER_H + +#include "NvCTypes.h" + +namespace Nv +{ +namespace Blast +{ + +struct CollisionHull; + +/** + ConvexMeshBuilder provides routine to build collision hulls from array of vertices. + Collision hull is built as convex hull of provided point set. + If due to some reason building of convex hull is failed, collision hull is built as bounding box of vertex set. + PhysX implementation can be found in NvBlastExtPx. +*/ +class ConvexMeshBuilder +{ +public: + + /** + Release ConvexMeshBuilder memory + */ + 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 + */ + virtual CollisionHull* buildCollisionGeometry(uint32_t verticesCount, const NvcVec3* vertexData) = 0; + + /** + Release CollisionHull memory. + */ + virtual void releaseCollisionHull(CollisionHull* hull) const = 0; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTAUTHORINGCONVEXMESHBUILDER_H diff --git a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringMesh.h b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringMesh.h index b8a8b72..7fc079f 100644 --- a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringMesh.h +++ b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringMesh.h @@ -113,12 +113,12 @@ public: /** Return reference on mesh bounding box. */ - virtual const physx::PxBounds3& getBoundingBox() const = 0; + virtual const NvcBounds3& getBoundingBox() const = 0; /** Return writable reference on mesh bounding box. */ - virtual physx::PxBounds3& getBoundingBoxWritable() = 0; + virtual NvcBounds3& getBoundingBoxWritable() = 0; /** @@ -156,7 +156,7 @@ public: /** Get pointer on facet bounding box, if not calculated return nullptr. */ - virtual const physx::PxBounds3* getFacetBound(uint32_t index) const = 0; + virtual const NvcBounds3* getFacetBound(uint32_t index) const = 0; }; diff --git a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringPatternGenerator.h b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringPatternGenerator.h index e446109..d53dacc 100644 --- a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringPatternGenerator.h +++ b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringPatternGenerator.h @@ -113,7 +113,7 @@ namespace Nv virtual DamagePattern* generateRegularRadialPattern(const RegularRadialPatternDesc* desc) = 0; - virtual DamagePattern* generateVoronoiPattern(uint32_t pointCount, const physx::PxVec3* points, int32_t interiorMaterialId) = 0; + virtual DamagePattern* generateVoronoiPattern(uint32_t pointCount, const NvcVec3* points, int32_t interiorMaterialId) = 0; virtual void release() = 0; }; diff --git a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringTypes.h b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringTypes.h index 729453b..ed5aa47 100644 --- a/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringTypes.h +++ b/sdk/extensions/authoringCommon/include/NvBlastExtAuthoringTypes.h @@ -29,263 +29,182 @@ #ifndef NVBLASTAUTHORINGTYPES_H #define NVBLASTAUTHORINGTYPES_H -#include <PxVec3.h> -#include <PxVec2.h> -#include <PxBounds3.h> #include "NvBlastTypes.h" - -#define NOT_VALID_VERTEX UINT32_MAX +#include "NvCTypes.h" namespace Nv { namespace Blast { +/** +Default material id assigned to interior faces (faces which created between 2 fractured chunks) +*/ +const uint32_t kMaterialInteriorId = 1000; + +/** +Default smoothing group id assigned to interior faces +*/ +const uint32_t kSmoothingGroupInteriorId = 1000; /** - Edge representation +Vertex index which considired by NvBlast as not valid. +*/ +const uint32_t kNotValidVertexIndex = UINT32_MAX; + +/** +Edge representation */ struct Edge { - uint32_t s, e; - Edge() : s(NOT_VALID_VERTEX), e(NOT_VALID_VERTEX){} - Edge(uint32_t s, uint32_t e) : s(s), e(e) {} - bool operator<(const Edge& b) const - { - if (s == b.s) - return e < b.e; - else - return s < b.s; - } - uint32_t operator[](uint32_t i) const - { - return *(reinterpret_cast<const uint32_t*>(this) + i); - } - + Edge(uint32_t s = kNotValidVertexIndex, uint32_t e = kNotValidVertexIndex) : s(s), e(e) {} + uint32_t s; + uint32_t e; }; /** - Mesh vertex representation + Mesh vertex representation */ struct Vertex { - physx::PxVec3 p; // Position - physx::PxVec3 n; // Normal - physx::PxVec2 uv[1]; // UV-coordinates array, currently supported only one UV coordinate. + Vertex() {}; + Vertex(const NvcVec3& p, const NvcVec3& n, const NvcVec2& _uv) : p(p), n(n) { uv[0] = _uv; } + NvcVec3 p; // Position + NvcVec3 n; // Normal + NvcVec2 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 + Mesh triangle representation */ struct Triangle { Triangle() {}; - Triangle(Vertex a, Vertex b, Vertex c) : a(a), b(b), c(c) {}; + Triangle(const Vertex& a, const Vertex& b, const Vertex& c, int32_t ud = 0, int32_t mid = 0, int32_t sid = 0) + : a(a), b(b), c(c), userData(ud), materialId(mid), smoothingGroup(sid) {} Vertex a, b, c; int32_t userData; int32_t materialId; int32_t smoothingGroup; - physx::PxVec3 getNormal() const - { - return ((b.p - a.p).cross(c.p - a.p)); - } - inline Vertex& getVertex(uint32_t index) - { - return (&a)[index]; - } - inline const Vertex& getVertex(uint32_t index) const - { - return (&a)[index]; - } }; - /** - Index based triangle + Index based triangle */ struct TriangleIndexed { - TriangleIndexed() {}; - TriangleIndexed(uint32_t a, uint32_t b, uint32_t c) : ea(a), eb(b), ec(c) {}; - - uint32_t getOpposite(uint32_t a, uint32_t b) - { - if (ea != a && ea != b) - return ea; - if (eb != a && eb != b) - return eb; - if (ec != a && ec != b) - return ec; - return NOT_VALID_VERTEX; - } - - bool isContainEdge(uint32_t a, uint32_t b) - { - 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; - } - + TriangleIndexed(uint32_t ea, uint32_t eb, uint32_t ec, int32_t mid = 0, int32_t sid = 0, int32_t ud = 0) + : ea(ea), eb(eb), ec(ec), materialId(mid), smoothingGroup(sid), userData(ud) {} uint32_t ea, eb, ec; int32_t materialId; int32_t smoothingGroup; int32_t userData; }; - - - /** - Mesh facet representation + Mesh facet representation */ struct Facet { - int32_t firstEdgeNumber; - uint32_t edgesCount; - int64_t userData; - int32_t materialId; - int32_t smoothingGroup; - Facet(int32_t fEdge = 0, uint32_t eCount = 0, int32_t materialId = 0, int64_t userData = 0, int32_t smoothingGroup = 0) : firstEdgeNumber(fEdge), edgesCount(eCount), userData(userData), materialId(materialId), smoothingGroup(smoothingGroup) {} + Facet(int32_t fen = 0, uint32_t ec = 0, int64_t ud = 0, int32_t mid = 0, int32_t sid = 0) + : firstEdgeNumber(fen), edgesCount(ec), userData(ud), materialId(mid), smoothingGroup(sid) {} + int32_t firstEdgeNumber; + uint32_t edgesCount; + int64_t userData; + int32_t materialId; + int32_t smoothingGroup; }; /** - Abstract base class for user-defined random value generator. + Collision hull geometry format. */ -class RandomGeneratorBase +struct HullPolygon { -public: - // Generates uniformly distributed value in [0, 1] range. - virtual float getRandomValue() = 0; - // Seeds random value generator - virtual void seed(int32_t seed) = 0; - virtual ~RandomGeneratorBase() {}; + // Polygon base plane + float plane[4]; + // Number vertices in polygon + uint16_t vertexCount; + // First index in CollisionHull.indices array for this polygon + uint16_t indexBase; }; /** - Collision hull geometry format. +Collsion hull geometry. */ 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; + uint32_t pointsCount; + uint32_t indicesCount; + uint32_t polygonDataCount; + NvcVec3* points; + uint32_t* indices; + HullPolygon* polygonData; }; /** - Authoring results. Which contains NvBlastAsset, render and collision meshes + Authoring results. Which contains NvBlastAsset, render and collision meshes. + If it was created by NvBlast it should be released with NvBlastExtAuthoringReleaseAuthoringResult + For releasing just collsion geometry call NvBlastExtAuthoringReleaseAuthoringResultCollision */ struct AuthoringResult { - uint32_t chunkCount; //Number of chunks in Blast asset + uint32_t chunkCount; // Number of chunks in Blast asset - uint32_t bondCount; //Number of bonds in Blast asset + uint32_t bondCount; // Number of bonds in Blast asset - NvBlastAsset* asset; //Blast asset + NvBlastAsset* asset; // Blast asset /** - assetToFractureChunkIdMap used for getting internal FractureChunkId with FractureTool::getChunkId. - FractureChunkId = FractureTool.getChunkId(aResult.assetToFractureChunkIdMap(AssetChunkId); + assetToFractureChunkIdMap used for getting internal FractureChunkId with FractureTool::getChunkId. + FractureChunkId = FractureTool.getChunkId(aResult.assetToFractureChunkIdMap(AssetChunkId); */ - uint32_t* assetToFractureChunkIdMap; + 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 + 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 + uint32_t* geometryOffset; - NvBlastBondDesc* bondDescs; //Array of bond descriptors. Contains bondCount elements + Triangle* geometry; // Raw array of Triangle for all chunks - /** - 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; + NvBlastChunkDesc* chunkDescs; // Array of chunk descriptors. Contains chunkCount elements - CollisionHull** collisionHull; //Raw array of pointers to collision hull for all chunks. + NvBlastBondDesc* bondDescs; // Array of bond descriptors. Contains bondCount elements /** - Array of chunk physics parameters. Contains chunkCount 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 */ - struct ExtPxChunk* physicsChunks; + uint32_t* collisionHullOffset; - /** - Array of phisics subchunks (convex mesh) descriptors. - Use collisionHullOffset for accessing elements. - */ - struct ExtPxSubchunk* physicsSubchunks; + CollisionHull** collisionHull; // Raw array of pointers to collision hull for all chunks. /** - Array of material names. + Array of material names. */ const char** materialNames; /** - Size of array of material names. + 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; }; +struct ConvexDecompositionParams +{ + uint32_t maximumNumberOfHulls = 8; // Maximum number of convex hull generated for one chunk. If equal to 1 convex + // decomposition is disabled. + uint32_t maximumNumberOfVerticesPerHull = 64; // Controls the maximum number of triangles per convex-hull + // (default=64, range=4-1024) + uint32_t voxelGridResolution = 1000000; // Voxel grid resolution used for chunk convex decomposition + // (default=1,000,000, range=10,000-16,000,000). + float concavity = 0.0025f; // Value between 0 and 1, controls how accurate hull generation is +}; -} // namespace Blast -} // namespace Nv +} // namespace Blast +} // namespace Nv -#endif // ifndef NVBLASTAUTHORINGTYPES_H +#endif // ifndef NVBLASTAUTHORINGTYPES_H diff --git a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringAccelerator.cpp b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringAccelerator.cpp index 20ff78b..5b3d4b6 100644 --- a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringAccelerator.cpp +++ b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringAccelerator.cpp @@ -30,88 +30,87 @@ #include "NvBlastExtAuthoringMesh.h" #include "NvBlastExtAuthoringInternalCommon.h" #include "NvBlastGlobals.h" - -using namespace physx; - +#include "NvBlastPxSharedHelpers.h" namespace Nv { namespace Blast { -DummyAccelerator::DummyAccelerator(int32_t count) :count(count) +DummyAccelerator::DummyAccelerator(int32_t count) : m_count(count) { - current = 0; + m_current = 0; } void DummyAccelerator::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { - current = 0; + m_current = 0; NV_UNUSED(pos); NV_UNUSED(ed); NV_UNUSED(fc); } -void DummyAccelerator::setState(const physx::PxBounds3* bound) { - current = 0; +void DummyAccelerator::setState(const NvcBounds3* bound) { + m_current = 0; NV_UNUSED(bound); } -void DummyAccelerator::setState(const physx::PxVec3& point) { - current = 0; +void DummyAccelerator::setState(const NvcVec3& point) { + m_current = 0; NV_UNUSED(point); } int32_t DummyAccelerator::getNextFacet() { - if (current < count) + if (m_current < m_count) { - ++current; - return current - 1; + ++m_current; + return m_current - 1; } else return -1; } -Grid::Grid(int32_t resolution) : mResolution(resolution) +Grid::Grid(int32_t resolution) : m_resolution(resolution) { /** Set up 3d grid */ - r3 = resolution * resolution * resolution; - mSpatialMap.resize(resolution * resolution * resolution); + m_r3 = resolution * resolution * resolution; + m_spatialMap.resize(resolution * resolution * resolution); } void Grid::setMesh(const Mesh* m) { - physx::PxBounds3 bd = m->getBoundingBox(); - mappedFacetCount = m->getFacetCount(); + physx::PxBounds3 bd = toPxShared(m->getBoundingBox()); + m_mappedFacetCount = m->getFacetCount(); bd.fattenFast(0.001f); - spos = bd.minimum; - deltas = PxVec3(mResolution / bd.getDimensions().x, mResolution / bd.getDimensions().y, mResolution / bd.getDimensions().z); + m_spos = fromPxShared(bd.minimum); + m_deltas = { m_resolution / bd.getDimensions().x, m_resolution / bd.getDimensions().y, + m_resolution / bd.getDimensions().z }; - for (int32_t i = 0; i < r3; ++i) - mSpatialMap[i].clear(); + for (int32_t i = 0; i < m_r3; ++i) + m_spatialMap[i].clear(); const float ofs = 0.001f; for (uint32_t fc = 0; fc < m->getFacetCount(); ++fc) { - physx::PxBounds3 cfc = *m->getFacetBound(fc); + NvcBounds3 cfc = *m->getFacetBound(fc); - int32_t is = std::max(0.f, (cfc.minimum.x - spos.x - ofs) * deltas.x); - int32_t ie = std::max(0.f, (cfc.maximum.x - spos.x + ofs) * deltas.x); + int32_t is = std::max(0.f, (cfc.minimum.x - m_spos.x - ofs) * m_deltas.x); + int32_t ie = std::max(0.f, (cfc.maximum.x - m_spos.x + ofs) * m_deltas.x); - int32_t js = std::max(0.f, (cfc.minimum.y - spos.y - ofs) * deltas.y); - int32_t je = std::max(0.f, (cfc.maximum.y - spos.y + ofs) * deltas.y); + int32_t js = std::max(0.f, (cfc.minimum.y - m_spos.y - ofs) * m_deltas.y); + int32_t je = std::max(0.f, (cfc.maximum.y - m_spos.y + ofs) * m_deltas.y); - int32_t ks = std::max(0.f, (cfc.minimum.z - spos.z - ofs) * deltas.z); - int32_t ke = std::max(0.f, (cfc.maximum.z - spos.z + ofs) * deltas.z); + int32_t ks = std::max(0.f, (cfc.minimum.z - m_spos.z - ofs) * m_deltas.z); + int32_t ke = std::max(0.f, (cfc.maximum.z - m_spos.z + ofs) * m_deltas.z); - for (int32_t i = is; i < mResolution && i <= ie; ++i) + for (int32_t i = is; i < m_resolution && i <= ie; ++i) { - for (int32_t j = js; j < mResolution && j <= je; ++j) + for (int32_t j = js; j < m_resolution && j <= je; ++j) { - for (int32_t k = ks; k < mResolution && k <= ke; ++k) + for (int32_t k = ks; k < m_resolution && k <= ke; ++k) { - mSpatialMap[(i * mResolution + j) * mResolution + k].push_back(fc); + m_spatialMap[(i * m_resolution + j) * m_resolution + k].push_back(fc); } } } @@ -121,236 +120,234 @@ void Grid::setMesh(const Mesh* m) GridWalker::GridWalker(Grid* grd) { - mGrid = grd; - alreadyGotValue = 0; - alreadyGotFlag.resize(1 << 12); - cellList.resize(1 << 12); - pointCmdDir = 0; + m_grid = grd; + m_alreadyGotValue = 0; + m_alreadyGotFlag.resize(1 << 12); + m_cellList.resize(1 << 12); + m_pointCmdDir = 0; } void GridWalker::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { - physx::PxBounds3 cfc(PxBounds3::empty()); + physx::PxBounds3 cfc(physx::PxBounds3::empty()); for (uint32_t v = 0; v < fc.edgesCount; ++v) { - cfc.include(pos[ed[fc.firstEdgeNumber + v].s].p); - cfc.include(pos[ed[fc.firstEdgeNumber + v].e].p); + cfc.include(toPxShared(pos[ed[fc.firstEdgeNumber + v].s].p)); + cfc.include(toPxShared(pos[ed[fc.firstEdgeNumber + v].e].p)); } - setState(&cfc); + setState(&fromPxShared(cfc)); } -void GridWalker::setState(const PxBounds3* facetBounding) +void GridWalker::setState(const NvcBounds3* facetBounding) { - alreadyGotValue++; - mIteratorCell = -1; - mIteratorFacet = -1; - gotCells = 0; - - physx::PxBounds3 cfc = *facetBounding; - + m_alreadyGotValue++; + m_iteratorCell = -1; + m_iteratorFacet = -1; + m_gotCells = 0; + NvcBounds3 cfc = *facetBounding; - int32_t is = std::max(0.f, (cfc.minimum.x - mGrid->spos.x - 0.001f) * mGrid->deltas.x); - int32_t ie = std::max(0.f, (cfc.maximum.x - mGrid->spos.x + 0.001f) * mGrid->deltas.x); + int32_t is = std::max(0.f, (cfc.minimum.x - m_grid->m_spos.x - 0.001f) * m_grid->m_deltas.x); + int32_t ie = std::max(0.f, (cfc.maximum.x - m_grid->m_spos.x + 0.001f) * m_grid->m_deltas.x); - int32_t js = std::max(0.f, (cfc.minimum.y - mGrid->spos.y - 0.001f) * mGrid->deltas.y); - int32_t je = std::max(0.f, (cfc.maximum.y - mGrid->spos.y + 0.001f) * mGrid->deltas.y); + int32_t js = std::max(0.f, (cfc.minimum.y - m_grid->m_spos.y - 0.001f) * m_grid->m_deltas.y); + int32_t je = std::max(0.f, (cfc.maximum.y - m_grid->m_spos.y + 0.001f) * m_grid->m_deltas.y); - int32_t ks = std::max(0.f, (cfc.minimum.z - mGrid->spos.z - 0.001f) * mGrid->deltas.z); - int32_t ke = std::max(0.f, (cfc.maximum.z - mGrid->spos.z + 0.001f) * mGrid->deltas.z); + int32_t ks = std::max(0.f, (cfc.minimum.z - m_grid->m_spos.z - 0.001f) * m_grid->m_deltas.z); + int32_t ke = std::max(0.f, (cfc.maximum.z - m_grid->m_spos.z + 0.001f) * m_grid->m_deltas.z); - for (int32_t i = is; i < mGrid->mResolution && i <= ie; ++i) + for (int32_t i = is; i < m_grid->m_resolution && i <= ie; ++i) { - for (int32_t j = js; j < mGrid->mResolution && j <= je; ++j) + for (int32_t j = js; j < m_grid->m_resolution && j <= je; ++j) { - for (int32_t k = ks; k < mGrid->mResolution && k <= ke; ++k) + for (int32_t k = ks; k < m_grid->m_resolution && k <= ke; ++k) { - int32_t id = (i * mGrid->mResolution + j) * mGrid->mResolution + k; - if (!mGrid->mSpatialMap[id].empty()) + int32_t id = (i * m_grid->m_resolution + j) * m_grid->m_resolution + k; + if (!m_grid->m_spatialMap[id].empty()) { - cellList[gotCells++] = id; + m_cellList[m_gotCells++] = id; } } } } - if (gotCells != 0) + if (m_gotCells != 0) { - mIteratorFacet = 0; - mIteratorCell = cellList[gotCells - 1]; - gotCells--; + m_iteratorFacet = 0; + m_iteratorCell = m_cellList[m_gotCells - 1]; + m_gotCells--; } } void GridWalker::setPointCmpDirection(int32_t d) { - pointCmdDir = d; + m_pointCmdDir = d; } -void GridWalker::setState(const physx::PxVec3& point) +void GridWalker::setState(const NvcVec3& point) { - alreadyGotValue++; - mIteratorCell = -1; - mIteratorFacet = -1; - gotCells = 0; + m_alreadyGotValue++; + m_iteratorCell = -1; + m_iteratorFacet = -1; + m_gotCells = 0; - int32_t is = std::max(0.f, (point.x - mGrid->spos.x - 0.001f) * mGrid->deltas.x); - int32_t ie = std::max(0.f, (point.x - mGrid->spos.x + 0.001f) * mGrid->deltas.x); + int32_t is = std::max(0.f, (point.x - m_grid->m_spos.x - 0.001f) * m_grid->m_deltas.x); + int32_t ie = std::max(0.f, (point.x - m_grid->m_spos.x + 0.001f) * m_grid->m_deltas.x); - int32_t js = std::max(0.f, (point.y - mGrid->spos.y - 0.001f) * mGrid->deltas.y); - int32_t je = std::max(0.f, (point.y - mGrid->spos.y + 0.001f) * mGrid->deltas.y); + int32_t js = std::max(0.f, (point.y - m_grid->m_spos.y - 0.001f) * m_grid->m_deltas.y); + int32_t je = std::max(0.f, (point.y - m_grid->m_spos.y + 0.001f) * m_grid->m_deltas.y); int32_t ks = 0; - int32_t ke = mGrid->mResolution; - switch (pointCmdDir) + int32_t ke = m_grid->m_resolution; + switch (m_pointCmdDir) { case 1: - ks = std::max(0.f, (point.z - mGrid->spos.z - 0.001f) * mGrid->deltas.z); + ks = std::max(0.f, (point.z - m_grid->m_spos.z - 0.001f) * m_grid->m_deltas.z); break; case -1: - ke = std::max(0.f, (point.z - mGrid->spos.z + 0.001f) * mGrid->deltas.z); + ke = std::max(0.f, (point.z - m_grid->m_spos.z + 0.001f) * m_grid->m_deltas.z); } - for (int32_t i = is; i < mGrid->mResolution && i <= ie; ++i) + for (int32_t i = is; i < m_grid->m_resolution && i <= ie; ++i) { - for (int32_t j = js; j < mGrid->mResolution && j <= je; ++j) + for (int32_t j = js; j < m_grid->m_resolution && j <= je; ++j) { - for (int32_t k = ks; k <= ke && k < mGrid->mResolution; ++k) + for (int32_t k = ks; k <= ke && k < m_grid->m_resolution; ++k) { - int32_t id = (i * mGrid->mResolution + j) * mGrid->mResolution + k; - if (!mGrid->mSpatialMap[id].empty()) + int32_t id = (i * m_grid->m_resolution + j) * m_grid->m_resolution + k; + if (!m_grid->m_spatialMap[id].empty()) { - cellList[gotCells++] = id; + m_cellList[m_gotCells++] = id; } } } } - if (gotCells != 0) + if (m_gotCells != 0) { - mIteratorFacet = 0; - mIteratorCell = cellList[gotCells - 1]; - gotCells--; + m_iteratorFacet = 0; + m_iteratorCell = m_cellList[m_gotCells - 1]; + m_gotCells--; } } int32_t GridWalker::getNextFacet() { int32_t facetId = -1; - while (mIteratorCell != -1) + while (m_iteratorCell != -1) { - if (mIteratorFacet >= (int32_t)mGrid->mSpatialMap[mIteratorCell].size()) + if (m_iteratorFacet >= (int32_t)m_grid->m_spatialMap[m_iteratorCell].size()) { - if (gotCells != 0) + if (m_gotCells != 0) { - mIteratorCell = cellList[gotCells - 1]; - gotCells--; - mIteratorFacet = 0; + m_iteratorCell = m_cellList[m_gotCells - 1]; + m_gotCells--; + m_iteratorFacet = 0; } else { - mIteratorCell = -1; + m_iteratorCell = -1; break; } } - if (alreadyGotFlag[mGrid->mSpatialMap[mIteratorCell][mIteratorFacet]] != alreadyGotValue) + if (m_alreadyGotFlag[m_grid->m_spatialMap[m_iteratorCell][m_iteratorFacet]] != m_alreadyGotValue) { - facetId = mGrid->mSpatialMap[mIteratorCell][mIteratorFacet]; - mIteratorFacet++; + facetId = m_grid->m_spatialMap[m_iteratorCell][m_iteratorFacet]; + m_iteratorFacet++; break; } else { - mIteratorFacet++; + m_iteratorFacet++; } } if (facetId != -1) { - alreadyGotFlag[facetId] = alreadyGotValue; + m_alreadyGotFlag[facetId] = m_alreadyGotValue; } return facetId; } -BBoxBasedAccelerator::BBoxBasedAccelerator(const Mesh* mesh, int32_t resolution) : mResolution(resolution), alreadyGotValue(1) +BBoxBasedAccelerator::BBoxBasedAccelerator(const Mesh* mesh, int32_t resolution) : m_resolution(resolution), m_alreadyGotValue(1) { - mBounds = mesh->getBoundingBox(); - mSpatialMap.resize(resolution * resolution * resolution); - mCells.resize(resolution * resolution * resolution); + m_bounds = mesh->getBoundingBox(); + m_spatialMap.resize(resolution * resolution * resolution); + m_cells.resize(resolution * resolution * resolution); int32_t currentCell = 0; - PxVec3 incr = (mBounds.maximum - mBounds.minimum) * (1.0f / mResolution); + NvcVec3 incr = (m_bounds.maximum - m_bounds.minimum) * (1.0f / m_resolution); for (int32_t z = 0; z < resolution; ++z) { for (int32_t y = 0; y < resolution; ++y) { for (int32_t x = 0; x < resolution; ++x) { - mCells[currentCell].minimum.x = mBounds.minimum.x + x * incr.x; - mCells[currentCell].minimum.y = mBounds.minimum.y + y * incr.y; - mCells[currentCell].minimum.z = mBounds.minimum.z + z * incr.z; + m_cells[currentCell].minimum.x = m_bounds.minimum.x + x * incr.x; + m_cells[currentCell].minimum.y = m_bounds.minimum.y + y * incr.y; + m_cells[currentCell].minimum.z = m_bounds.minimum.z + z * incr.z; - mCells[currentCell].maximum.x = mBounds.minimum.x + (x + 1) * incr.x; - mCells[currentCell].maximum.y = mBounds.minimum.y + (y + 1) * incr.y; - mCells[currentCell].maximum.z = mBounds.minimum.z + (z + 1) * incr.z; + m_cells[currentCell].maximum.x = m_bounds.minimum.x + (x + 1) * incr.x; + m_cells[currentCell].maximum.y = m_bounds.minimum.y + (y + 1) * incr.y; + m_cells[currentCell].maximum.z = m_bounds.minimum.z + (z + 1) * incr.z; ++currentCell; } } } - cellList.resize(1 << 16); - gotCells = 0; + m_cellList.resize(1 << 16); + m_gotCells = 0; buildAccelStructure(mesh->getVertices(), mesh->getEdges(), mesh->getFacetsBuffer(), mesh->getFacetCount()); } BBoxBasedAccelerator::~BBoxBasedAccelerator() { - mResolution = 0; - mBounds.setEmpty(); - mSpatialMap.clear(); - mCells.clear(); - cellList.clear(); + m_resolution = 0; + toPxShared(m_bounds).setEmpty(); + m_spatialMap.clear(); + m_cells.clear(); + m_cellList.clear(); } int32_t BBoxBasedAccelerator::getNextFacet() { int32_t facetId = -1; - while (mIteratorCell != -1) + while (m_iteratorCell != -1) { - if (mIteratorFacet >= (int32_t)mSpatialMap[mIteratorCell].size()) + if (m_iteratorFacet >= (int32_t)m_spatialMap[m_iteratorCell].size()) { - if (gotCells != 0) + if (m_gotCells != 0) { - mIteratorCell = cellList[gotCells - 1]; - gotCells--; - mIteratorFacet = 0; + m_iteratorCell = m_cellList[m_gotCells - 1]; + m_gotCells--; + m_iteratorFacet = 0; } else { - mIteratorCell = -1; + m_iteratorCell = -1; break; } } - if (alreadyGotFlag[mSpatialMap[mIteratorCell][mIteratorFacet]] != alreadyGotValue) + if (m_alreadyGotFlag[m_spatialMap[m_iteratorCell][m_iteratorFacet]] != m_alreadyGotValue) { - facetId = mSpatialMap[mIteratorCell][mIteratorFacet]; - mIteratorFacet++; + facetId = m_spatialMap[m_iteratorCell][m_iteratorFacet]; + m_iteratorFacet++; break; } else { - mIteratorFacet++; + m_iteratorFacet++; } } if (facetId != -1) { - alreadyGotFlag[facetId] = alreadyGotValue; + m_alreadyGotFlag[facetId] = m_alreadyGotValue; } return facetId; } @@ -359,65 +356,65 @@ int32_t BBoxBasedAccelerator::getNextFacet() void BBoxBasedAccelerator::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { - physx::PxBounds3 cfc(PxBounds3::empty()); + physx::PxBounds3 cfc(physx::PxBounds3::empty()); for (uint32_t v = 0; v < fc.edgesCount; ++v) { - cfc.include(pos[ed[fc.firstEdgeNumber + v].s].p); - cfc.include(pos[ed[fc.firstEdgeNumber + v].e].p); + cfc.include(toPxShared(pos[ed[fc.firstEdgeNumber + v].s].p)); + cfc.include(toPxShared(pos[ed[fc.firstEdgeNumber + v].e].p)); } - setState(&cfc); + setState(&fromPxShared(cfc)); } -void BBoxBasedAccelerator::setState(const PxBounds3* facetBox) +void BBoxBasedAccelerator::setState(const NvcBounds3* facetBox) { - alreadyGotValue++; - mIteratorCell = -1; - mIteratorFacet = -1; - gotCells = 0; + m_alreadyGotValue++; + m_iteratorCell = -1; + m_iteratorFacet = -1; + m_gotCells = 0; - for (uint32_t i = 0; i < mCells.size(); ++i) + for (uint32_t i = 0; i < m_cells.size(); ++i) { - if (weakBoundingBoxIntersection(mCells[i], *facetBox)) + if (weakBoundingBoxIntersection(toPxShared(m_cells[i]), *toPxShared(facetBox))) { - if (!mSpatialMap[i].empty()) - cellList[gotCells++] = i; + if (!m_spatialMap[i].empty()) + m_cellList[m_gotCells++] = i; } } - if (gotCells != 0) + if (m_gotCells != 0) { - mIteratorFacet = 0; - mIteratorCell = cellList[gotCells - 1]; - gotCells--; + m_iteratorFacet = 0; + m_iteratorCell = m_cellList[m_gotCells - 1]; + m_gotCells--; } } -void BBoxBasedAccelerator::setState(const PxVec3& p) +void BBoxBasedAccelerator::setState(const NvcVec3& p) { - alreadyGotValue++; - mIteratorCell = -1; - mIteratorFacet = -1; - gotCells = 0; - int32_t perSlice = mResolution * mResolution; - for (uint32_t i = 0; i < mCells.size(); ++i) + m_alreadyGotValue++; + m_iteratorCell = -1; + m_iteratorFacet = -1; + m_gotCells = 0; + int32_t perSlice = m_resolution * m_resolution; + for (uint32_t i = 0; i < m_cells.size(); ++i) { - if (mCells[i].contains(p)) + if (toPxShared(m_cells[i]).contains(toPxShared(p))) { int32_t xyCellId = i % perSlice; - for (int32_t zCell = 0; zCell < mResolution; ++zCell) + for (int32_t zCell = 0; zCell < m_resolution; ++zCell) { int32_t cell = zCell * perSlice + xyCellId; - if (!mSpatialMap[cell].empty()) - cellList[gotCells++] = cell; + if (!m_spatialMap[cell].empty()) + m_cellList[m_gotCells++] = cell; } } } - if (gotCells != 0) + if (m_gotCells != 0) { - mIteratorFacet = 0; - mIteratorCell = cellList[gotCells - 1]; - gotCells--; + m_iteratorFacet = 0; + m_iteratorCell = m_cellList[m_gotCells - 1]; + m_gotCells--; } } @@ -426,27 +423,27 @@ void BBoxBasedAccelerator::buildAccelStructure(const Vertex* pos, const Edge* ed { for (int32_t facet = 0; facet < facetCount; ++facet) { - PxBounds3 bBox; + physx::PxBounds3 bBox; bBox.setEmpty(); const Edge* edge = &edges[0] + fc->firstEdgeNumber; int32_t count = fc->edgesCount; for (int32_t ec = 0; ec < count; ++ec) { - bBox.include(pos[edge->s].p); - bBox.include(pos[edge->e].p); + bBox.include(toPxShared(pos[edge->s].p)); + bBox.include(toPxShared(pos[edge->e].p)); edge++; } - for (uint32_t i = 0; i < mCells.size(); ++i) + for (uint32_t i = 0; i < m_cells.size(); ++i) { - if (weakBoundingBoxIntersection(mCells[i], bBox)) + if (weakBoundingBoxIntersection(toPxShared(m_cells[i]), bBox)) { - mSpatialMap[i].push_back(facet); + m_spatialMap[i].push_back(facet); } } fc++; } - alreadyGotFlag.resize(facetCount, 0); + m_alreadyGotFlag.resize(facetCount, 0); } #define SWEEP_RESOLUTION 2048 @@ -484,15 +481,15 @@ void buildIndex(std::vector<SegmentToIndex>& segm, float offset, float mlt, std: SweepingAccelerator::SweepingAccelerator(Nv::Blast::Mesh* in) { - PxBounds3 bnd; + physx::PxBounds3 bnd; const Vertex* verts = in->getVertices(); const Edge* edges = in->getEdges(); - facetCount = in->getFacetCount(); + m_facetCount = in->getFacetCount(); - foundx.resize(facetCount, 0); - foundy.resize(facetCount, 0); + m_foundx.resize(m_facetCount, 0); + m_foundy.resize(m_facetCount, 0); std::vector<SegmentToIndex> xevs; @@ -506,7 +503,7 @@ SweepingAccelerator::SweepingAccelerator(Nv::Blast::Mesh* in) bnd.setEmpty(); for (uint32_t v = 0; v < fc->edgesCount; ++v) { - bnd.include(verts[edges[v + fc->firstEdgeNumber].s].p); + bnd.include(toPxShared(verts[edges[v + fc->firstEdgeNumber].s].p)); } bnd.scaleFast(1.1f); xevs.push_back(SegmentToIndex(bnd.minimum.x, i, false)); @@ -525,126 +522,126 @@ SweepingAccelerator::SweepingAccelerator(Nv::Blast::Mesh* in) std::sort(zevs.begin(), zevs.end()); - minimal.x = xevs[0].coord; - minimal.y = yevs[0].coord; - minimal.z = zevs[0].coord; + m_minimal.x = xevs[0].coord; + m_minimal.y = yevs[0].coord; + m_minimal.z = zevs[0].coord; - maximal.x = xevs.back().coord; - maximal.y = yevs.back().coord; - maximal.z = zevs.back().coord; + m_maximal.x = xevs.back().coord; + m_maximal.y = yevs.back().coord; + m_maximal.z = zevs.back().coord; - rescale = (maximal - minimal) * 1.01f; - rescale.x = 1.0f / rescale.x * SWEEP_RESOLUTION; - rescale.y = 1.0f / rescale.y * SWEEP_RESOLUTION; - rescale.z = 1.0f / rescale.z * SWEEP_RESOLUTION; + m_rescale = (m_maximal - m_minimal) * 1.01f; + m_rescale.x = 1.0f / m_rescale.x * SWEEP_RESOLUTION; + m_rescale.y = 1.0f / m_rescale.y * SWEEP_RESOLUTION; + m_rescale.z = 1.0f / m_rescale.z * SWEEP_RESOLUTION; - xSegm.resize(SWEEP_RESOLUTION); - ySegm.resize(SWEEP_RESOLUTION); - zSegm.resize(SWEEP_RESOLUTION); + m_xSegm.resize(SWEEP_RESOLUTION); + m_ySegm.resize(SWEEP_RESOLUTION); + m_zSegm.resize(SWEEP_RESOLUTION); - buildIndex(xevs, minimal.x, rescale.x, xSegm); - buildIndex(yevs, minimal.y, rescale.y, ySegm); - buildIndex(zevs, minimal.z, rescale.z, zSegm); + buildIndex(xevs, m_minimal.x, m_rescale.x, m_xSegm); + buildIndex(yevs, m_minimal.y, m_rescale.y, m_ySegm); + buildIndex(zevs, m_minimal.z, m_rescale.z, m_zSegm); - iterId = 1; - current = 0; + m_iterId = 1; + m_current = 0; } -void SweepingAccelerator::setState(const PxBounds3* facetBounds) +void SweepingAccelerator::setState(const NvcBounds3* facetBounds) { - current = 0; - indices.clear(); + m_current = 0; + m_indices.clear(); - PxBounds3 bnd = *facetBounds; + physx::PxBounds3 bnd = *toPxShared(facetBounds); bnd.scaleFast(1.1); - uint32_t start = (std::max(0.0f, bnd.minimum.x - minimal.x)) * rescale.x; - uint32_t end = (std::max(0.0f, bnd.maximum.x - minimal.x)) * rescale.x; + uint32_t start = (std::max(0.0f, bnd.minimum.x - m_minimal.x)) * m_rescale.x; + uint32_t end = (std::max(0.0f, bnd.maximum.x - m_minimal.x)) * m_rescale.x; for (uint32_t i = start; i <= end && i < SWEEP_RESOLUTION; ++i) { - for (auto id : xSegm[i]) + for (auto id : m_xSegm[i]) { - foundx[id] = iterId; + m_foundx[id] = m_iterId; } } - start = (std::max(0.0f, bnd.minimum.y - minimal.y)) * rescale.y; - end = (std::max(0.0f, bnd.maximum.y - minimal.y)) * rescale.y; + start = (std::max(0.0f, bnd.minimum.y - m_minimal.y)) * m_rescale.y; + end = (std::max(0.0f, bnd.maximum.y - m_minimal.y)) * m_rescale.y; for (uint32_t i = start; i <= end && i < SWEEP_RESOLUTION; ++i) { - for (auto id : ySegm[i]) + for (auto id : m_ySegm[i]) { - foundy[id] = iterId; + m_foundy[id] = m_iterId; } } - start = (std::max(0.0f, bnd.minimum.z - minimal.z)) * rescale.z; - end = (std::max(0.0f, bnd.maximum.z - minimal.z)) * rescale.z; + start = (std::max(0.0f, bnd.minimum.z - m_minimal.z)) * m_rescale.z; + end = (std::max(0.0f, bnd.maximum.z - m_minimal.z)) * m_rescale.z; for (uint32_t i = start; i <= end && i < SWEEP_RESOLUTION; ++i) { - for (auto id : zSegm[i]) + for (auto id : m_zSegm[i]) { - if (foundy[id] == iterId && foundx[id] == iterId) + if (m_foundy[id] == m_iterId && m_foundx[id] == m_iterId) { - foundx[id] = iterId + 1; - foundy[id] = iterId + 1; - indices.push_back(id); + m_foundx[id] = m_iterId + 1; + m_foundy[id] = m_iterId + 1; + m_indices.push_back(id); } } } - iterId += 2; + m_iterId += 2; } void SweepingAccelerator::setState(const Vertex* pos, const Edge* ed, const Facet& fc) { - physx::PxBounds3 cfc(PxBounds3::empty()); + physx::PxBounds3 cfc(physx::PxBounds3::empty()); for (uint32_t v = 0; v < fc.edgesCount; ++v) { - cfc.include(pos[ed[fc.firstEdgeNumber + v].s].p); - cfc.include(pos[ed[fc.firstEdgeNumber + v].e].p); + cfc.include(toPxShared(pos[ed[fc.firstEdgeNumber + v].s].p)); + cfc.include(toPxShared(pos[ed[fc.firstEdgeNumber + v].e].p)); } - setState(&cfc); + setState(&fromPxShared(cfc)); } -void SweepingAccelerator::setState(const physx::PxVec3& point) { +void SweepingAccelerator::setState(const NvcVec3& point) { - indices.clear(); + m_indices.clear(); /*for (uint32_t i = 0; i < facetCount; ++i) { indices.push_back(i); }*/ - uint32_t xIndex = (point.x - minimal.x) * rescale.x; - uint32_t yIndex = (point.y- minimal.y) * rescale.y; + uint32_t xIndex = (point.x - m_minimal.x) * m_rescale.x; + uint32_t yIndex = (point.y - m_minimal.y) * m_rescale.y; - for (uint32_t i = 0; i < xSegm[xIndex].size(); ++i) + for (uint32_t i = 0; i < m_xSegm[xIndex].size(); ++i) { - foundx[xSegm[xIndex][i]] = iterId; + m_foundx[m_xSegm[xIndex][i]] = m_iterId; } - for (uint32_t i = 0; i < ySegm[yIndex].size(); ++i) + for (uint32_t i = 0; i < m_ySegm[yIndex].size(); ++i) { - if (foundx[ySegm[yIndex][i]] == iterId) + if (m_foundx[m_ySegm[yIndex][i]] == m_iterId) { - indices.push_back(ySegm[yIndex][i]); + m_indices.push_back(m_ySegm[yIndex][i]); } } - iterId++; - current = 0; + m_iterId++; + m_current = 0; NV_UNUSED(point); } int32_t SweepingAccelerator::getNextFacet() { - if (static_cast<uint32_t>(current) < indices.size()) + if (static_cast<uint32_t>(m_current) < m_indices.size()) { - ++current; - return indices[current - 1]; + ++m_current; + return m_indices[m_current - 1]; } else return -1; diff --git a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringInternalCommon.h b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringInternalCommon.h index 28d3349..4a0fbd0 100644 --- a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringInternalCommon.h +++ b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringInternalCommon.h @@ -29,10 +29,13 @@ #ifndef NVBLASTINTERNALCOMMON_H #define NVBLASTINTERNALCOMMON_H #include "NvBlastExtAuthoringTypes.h" +#include <PxVec2.h> +#include <PxVec3.h> +#include <PxPlane.h> +#include <PxBounds3.h> +#include <PxMath.h> #include <algorithm> -using namespace physx; - namespace Nv { namespace Blast @@ -75,6 +78,13 @@ struct EdgeComparator } }; +inline bool operator<(const Edge& a, const Edge& b) +{ + if (a.s == b.s) + return a.e < b.e; + else + return a.s < b.s; +} /** Vertex projection direction flag. @@ -129,6 +139,11 @@ NV_FORCE_INLINE physx::PxVec2 getProjectedPoint(const physx::PxVec3& point, Proj return physx::PxVec2(point.x, point.y); } +NV_FORCE_INLINE physx::PxVec2 getProjectedPoint(const NvcVec3& point, ProjectionDirections dir) +{ + return getProjectedPoint((const physx::PxVec3&)point, dir); +} + /** Computes point projected on given axis aligned plane, this method is polygon-winding aware. */ @@ -182,10 +197,11 @@ NV_INLINE bool weakBoundingBoxIntersection(const physx::PxBounds3& aBox, const /** Test segment vs plane intersection. If segment intersects the plane true is returned. Point of intersection is written into 'result'. */ -NV_INLINE bool getPlaneSegmentIntersection(const PxPlane& pl, const PxVec3& a, const PxVec3& b, PxVec3& result) +NV_INLINE bool getPlaneSegmentIntersection(const physx::PxPlane& pl, const physx::PxVec3& a, const physx::PxVec3& b, + physx::PxVec3& result) { float div = (b - a).dot(pl.n); - if (PxAbs(div) < 0.0001f) + if (physx::PxAbs(div) < 0.0001f) { if (pl.contains(a)) { @@ -243,7 +259,7 @@ Vertex comparator for vertex welding (not accounts normal and uv parameters of v */ struct VrtPositionComparator { - bool operator()(const physx::PxVec3& a, const physx::PxVec3& b) const + bool operator()(const NvcVec3& a, const NvcVec3& b) const { if (a.x + POS_COMPARISON_OFFSET < b.x) return true; if (a.x - POS_COMPARISON_OFFSET > b.x) return false; diff --git a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp index f0c9a84..fad9184 100644 --- a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp +++ b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp @@ -31,22 +31,19 @@ #include "NvBlastExtAuthoringTypes.h" #include <NvBlastAssert.h> #include "PxMath.h" +#include <NvBlastPxSharedHelpers.h> #include <cmath> #include <string.h> #include <vector> #include <algorithm> -using physx::PxVec2; -using physx::PxVec3; -using physx::PxBounds3; - - namespace Nv { namespace Blast { -MeshImpl::MeshImpl(const PxVec3* position, const PxVec3* normals, const PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount) +MeshImpl::MeshImpl(const NvcVec3* position, const NvcVec3* normals, const NvcVec2* uv, uint32_t verticesCount, + const uint32_t* indices, uint32_t indicesCount) { mVertices.resize(verticesCount); @@ -66,7 +63,7 @@ MeshImpl::MeshImpl(const PxVec3* position, const PxVec3* normals, const PxVec2* { for (uint32_t i = 0; i < mVertices.size(); ++i) { - mVertices[i].n = PxVec3(0, 0, 0); + mVertices[i].n = {0, 0, 0}; } } if (uv != 0) @@ -80,7 +77,7 @@ MeshImpl::MeshImpl(const PxVec3* position, const PxVec3* normals, const PxVec2* { for (uint32_t i = 0; i < mVertices.size(); ++i) { - mVertices[i].uv[0] = PxVec2(0, 0); + mVertices[i].uv[0] = {0, 0}; } } mEdges.resize(indicesCount); @@ -195,9 +192,9 @@ float MeshImpl::getMeshVolume() for (uint32_t i = 0; i < mFacets.size(); ++i) { int32_t offset = mFacets[i].firstEdgeNumber; - PxVec3& a = mVertices[mEdges[offset].s].p; - PxVec3& b = mVertices[mEdges[offset + 1].s].p; - PxVec3& c = mVertices[mEdges[offset + 2].s].p; + NvcVec3& a = mVertices[mEdges[offset].s].p; + NvcVec3& b = mVertices[mEdges[offset + 1].s].p; + NvcVec3& c = mVertices[mEdges[offset + 2].s].p; 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); } @@ -264,14 +261,14 @@ void MeshImpl::release() delete this; } -const PxBounds3& MeshImpl::getBoundingBox() const +const NvcBounds3& MeshImpl::getBoundingBox() const { - return mBounds; + return fromPxShared(mBounds); } -PxBounds3& MeshImpl::getBoundingBoxWritable() +NvcBounds3& MeshImpl::getBoundingBoxWritable() { - return mBounds; + return fromPxShared(mBounds); } @@ -280,18 +277,18 @@ void MeshImpl::recalculateBoundingBox() mBounds.setEmpty(); for (uint32_t i = 0; i < mVertices.size(); ++i) { - mBounds.include(mVertices[i].p); + mBounds.include(toPxShared(mVertices[i].p)); } calcPerFacetBounds(); } -const physx::PxBounds3* MeshImpl::getFacetBound(uint32_t index) const +const NvcBounds3* MeshImpl::getFacetBound(uint32_t index) const { if (mPerFacetBounds.empty()) { return nullptr; } - return &mPerFacetBounds[index]; + return &fromPxShared(mPerFacetBounds[index]); } void MeshImpl::calcPerFacetBounds() @@ -305,8 +302,8 @@ void MeshImpl::calcPerFacetBounds() for (uint32_t v = 0; v < mFacets[i].edgesCount; ++v) { - fb.include(mVertices[mEdges[mFacets[i].firstEdgeNumber + v].s].p); - fb.include(mVertices[mEdges[mFacets[i].firstEdgeNumber + v].e].p); + fb.include(toPxShared(mVertices[mEdges[mFacets[i].firstEdgeNumber + v].s].p)); + fb.include(toPxShared(mVertices[mEdges[mFacets[i].firstEdgeNumber + v].e].p)); } } } diff --git a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.h b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.h index 0f4c339..75b8bf5 100644 --- a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.h +++ b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.h @@ -29,6 +29,7 @@ #define NVBLASTAUTHORINGMESHIMPL_H #include "NvBlastExtAuthoringMesh.h" +#include <PxBounds3.h> #include <vector> #include <map> #include <set> @@ -54,7 +55,7 @@ public: \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); + MeshImpl(const NvcVec3* position, const NvcVec3* normals, const NvcVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount); /** Constructs mesh object from array of facets. @@ -139,12 +140,12 @@ public: /** Return reference on mesh bounding box. */ - const physx::PxBounds3& getBoundingBox() const override; + const NvcBounds3& getBoundingBox() const override; /** Return writable reference on mesh bounding box. */ - physx::PxBounds3& getBoundingBoxWritable() override; + NvcBounds3& getBoundingBoxWritable() override; /** Recalculate bounding box @@ -181,18 +182,16 @@ public: /** Get pointer on facet bounding box, if not calculated return nullptr. */ - virtual const physx::PxBounds3* getFacetBound(uint32_t index) const override; + virtual const NvcBounds3* getFacetBound(uint32_t index) const override; private: std::vector<Vertex> mVertices; std::vector<Edge> mEdges; std::vector<Facet> mFacets; - physx::PxBounds3 mBounds; + physx::PxBounds3 mBounds; std::vector<physx::PxBounds3> mPerFacetBounds; }; - - } // namespace Blast } // namespace Nv diff --git a/sdk/extensions/exporter/include/NvBlastExtExporter.h b/sdk/extensions/exporter/include/NvBlastExtExporter.h index 2718f3c..0c3d564 100755 --- a/sdk/extensions/exporter/include/NvBlastExtExporter.h +++ b/sdk/extensions/exporter/include/NvBlastExtExporter.h @@ -30,15 +30,10 @@ #define NVBLASTEXTEXPORTER_H
#include "NvBlastTypes.h"
+#include "NvCTypes.h"
struct NvBlastAsset;
-namespace physx
-{
-class PxVec2;
-class PxVec3;
-}
-
namespace Nv
{
namespace Blast
@@ -62,11 +57,11 @@ struct ExporterMeshData uint32_t uvsCount; //Number of textures uv
- physx::PxVec3* positions; //Array of positions
+ NvcVec3* positions; //Array of positions
- physx::PxVec3* normals; //Array of normals
+ NvcVec3* normals; // Array of normals
- physx::PxVec2* uvs; //Array of textures uv
+ NvcVec2* uvs; // Array of textures uv
uint32_t meshCount; //Number of meshes (chunks)
@@ -129,17 +124,17 @@ public: /**
Get loaded vertex positions
*/
- virtual physx::PxVec3* getPositionArray() = 0;
+ virtual NvcVec3* getPositionArray() = 0;
/**
Get loaded vertex normals
*/
- virtual physx::PxVec3* getNormalsArray() = 0;
+ virtual NvcVec3* getNormalsArray() = 0;
/**
Get loaded vertex uv-coordinates
*/
- virtual physx::PxVec2* getUvArray() = 0;
+ virtual NvcVec2* getUvArray() = 0;
/**
Get loaded per triangle material ids.
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp index 99600fd..22503d3 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp @@ -35,12 +35,9 @@ #include <sstream>
#include <unordered_map>
-#include "PxVec3.h"
-#include "PxVec2.h"
-#include "PxPlane.h"
#include "NvBlastExtAuthoringMesh.h"
#include "NvBlastExtAuthoringBondGenerator.h"
-#include "NvBlastExtAuthoringCollisionBuilder.h"
+#include "NvBlastPxSharedHelpers.h"
using physx::PxVec3;
using physx::PxVec2;
@@ -201,15 +198,15 @@ void FbxFileReader::loadFromFile(const char* filename) bool bAllTriangles = mesh->IsTriangleMesh();
if (!bAllTriangles)
{
+ //It creates corrupted mesh and return true. Disable it to prevent crash.
//try letting the FBX SDK triangulate it
- geoConverter.Triangulate(mesh, true);
- bAllTriangles = mesh->IsTriangleMesh();
+ //bAllTriangles = geoConverter.Triangulate(mesh, true) && mesh->IsTriangleMesh();
}
int polyCount = mesh->GetPolygonCount();
if (!bAllTriangles)
{
- std::cerr << "Mesh 0 has " << polyCount << " but not all polygons are triangles. Mesh must be triangulated." << std::endl;
+ std::cerr << "Mesh 0 has " << polyCount << " polygons but not all of them are triangles. Mesh must be triangulated." << std::endl;
return;
}
@@ -219,9 +216,9 @@ void FbxFileReader::loadFromFile(const char* filename) const char * uvSetName = uvSetNames.GetStringAt(0);
- std::vector<PxVec3> positions;
- std::vector<PxVec3> normals;
- std::vector<PxVec2> uv;
+ std::vector<NvcVec3> positions;
+ std::vector<NvcVec3> normals;
+ std::vector<NvcVec2> uv;
std::vector<uint32_t> indices;
int* polyVertices = mesh->GetPolygonVertices();
@@ -259,9 +256,9 @@ void FbxFileReader::loadFromFile(const char* filename) 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]));
+ positions.push_back({(float) vert[0], (float)vert[1], (float)vert[2]});
+ normals.push_back({(float)normVec[0], (float)normVec[1], (float)normVec[2]});
+ uv.push_back({(float)uvVec[0], (float)uvVec[1]});
indices.push_back(vertIndex++);
}
if (matLayer != nullptr)
@@ -431,7 +428,7 @@ bool FbxFileReader::getCollisionInternal() vpos++;
}
- chull.points = new PxVec3[uniqueCPValues.size()];
+ chull.points = new NvcVec3[uniqueCPValues.size()];
chull.pointsCount = uint32_t(uniqueCPValues.size());
physx::PxVec3 hullCentroid(0.0f);
@@ -442,7 +439,7 @@ bool FbxFileReader::getCollisionInternal() chull.points[i].x = (float)worldVPos[0];
chull.points[i].y = (float)worldVPos[1];
chull.points[i].z = (float)worldVPos[2];
- hullCentroid += chull.points[i];
+ hullCentroid += toPxShared(chull.points[i]);
}
if (chull.pointsCount)
@@ -451,7 +448,7 @@ bool FbxFileReader::getCollisionInternal() }
uint32_t polyCount = meshNode->GetPolygonCount();
- chull.polygonData = new Nv::Blast::CollisionHull::HullPolygon[polyCount];
+ chull.polygonData = new Nv::Blast::HullPolygon[polyCount];
chull.polygonDataCount = polyCount;
chull.indicesCount = meshNode->GetPolygonVertexCount();
@@ -462,8 +459,8 @@ bool FbxFileReader::getCollisionInternal() {
int32_t vInPolyCount = meshNode->GetPolygonSize(poly);
auto& pd = chull.polygonData[poly];
- pd.mIndexBase = (uint16_t)curIndexCount;
- pd.mNbVerts = (uint16_t)vInPolyCount;
+ pd.indexBase = (uint16_t)curIndexCount;
+ pd.vertexCount = (uint16_t)vInPolyCount;
int32_t* ind = &meshNode->GetPolygonVertices()[meshNode->GetPolygonVertexIndex(poly)];
uint32_t* destInd = chull.indices + curIndexCount;
for (int32_t v = 0; v < vInPolyCount; v++)
@@ -474,9 +471,9 @@ bool FbxFileReader::getCollisionInternal() //Don't depend on the normals to create the plane normal, they could be wrong
PxVec3 lastThreeVerts[3] = {
- chull.points[chull.indices[curIndexCount - 1]],
- chull.points[chull.indices[curIndexCount - 2]],
- chull.points[chull.indices[curIndexCount - 3]]
+ toPxShared(chull.points[chull.indices[curIndexCount - 1]]),
+ toPxShared(chull.points[chull.indices[curIndexCount - 2]]),
+ toPxShared(chull.points[chull.indices[curIndexCount - 3]])
};
physx::PxPlane plane(lastThreeVerts[0], lastThreeVerts[1], lastThreeVerts[2]);
@@ -484,10 +481,10 @@ bool FbxFileReader::getCollisionInternal() const float s = plane.n.dot(lastThreeVerts[0] - hullCentroid) >= 0.0f ? 1.0f : -1.0f;
- pd.mPlane[0] = s*plane.n.x;
- pd.mPlane[1] = s*plane.n.y;
- pd.mPlane[2] = s*plane.n.z;
- pd.mPlane[3] = s*plane.d;
+ pd.plane[0] = s*plane.n.x;
+ pd.plane[1] = s*plane.n.y;
+ pd.plane[2] = s*plane.n.z;
+ pd.plane[3] = s*plane.d;
}
}
@@ -582,17 +579,17 @@ bool FbxFileReader::getBoneInfluencesInternal(FbxMesh* meshNode) return true;
};
-physx::PxVec3* FbxFileReader::getPositionArray()
+NvcVec3* FbxFileReader::getPositionArray()
{
return mVertexPositions.data();
};
-physx::PxVec3* FbxFileReader::getNormalsArray()
+NvcVec3* FbxFileReader::getNormalsArray()
{
return mVertexNormals.data();
};
-physx::PxVec2* FbxFileReader::getUvArray()
+NvcVec2* FbxFileReader::getUvArray()
{
return mVertexUv.data();
};
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h index 0509700..061e603 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h @@ -46,11 +46,6 @@ class FbxFileReader : public IFbxFileReader {
struct CollisionHullImpl : public Nv::Blast::CollisionHull
{
- void release() override
- {
- delete this;
- }
-
//copy from existing
CollisionHullImpl(const CollisionHullImpl& other) : CollisionHullImpl()
{
@@ -76,7 +71,9 @@ class FbxFileReader : public IFbxFileReader {
if (&other != this)
{
- release();
+ delete[] points;
+ delete[] indices;
+ delete[] polygonData;
copyFrom(other);
}
return *this;
@@ -116,9 +113,9 @@ class FbxFileReader : public IFbxFileReader pointsCount = other.pointsCount;
indicesCount = other.indicesCount;
polygonDataCount = other.polygonDataCount;
- points = new physx::PxVec3[pointsCount];
+ points = new NvcVec3[pointsCount];
indices = new uint32_t[indicesCount];
- polygonData = new Nv::Blast::CollisionHull::HullPolygon[polygonDataCount];
+ polygonData = new Nv::Blast::HullPolygon[polygonDataCount];
memcpy(points, other.points, sizeof(points[0]) * pointsCount);
memcpy(indices, other.indices, sizeof(indices[0]) * indicesCount);
memcpy(polygonData, other.polygonData, sizeof(polygonData[0]) * polygonDataCount);
@@ -163,15 +160,15 @@ public: /**
Get loaded vertex positions
*/
- virtual physx::PxVec3* getPositionArray() override;
+ virtual NvcVec3* getPositionArray() override;
/**
Get loaded vertex normals
*/
- virtual physx::PxVec3* getNormalsArray() override;
+ virtual NvcVec3* getNormalsArray() override;
/**
Get loaded vertex uv-coordinates
*/
- virtual physx::PxVec2* getUvArray() override;
+ virtual NvcVec2* getUvArray() override;
/**
Get loaded triangle indices
*/
@@ -203,9 +200,9 @@ private: std::vector<CollisionHullImpl> mHulls;
std::vector<uint32_t> mVertexToContainingChunkMap;
std::multimap<uint32_t, FbxNode*> mCollisionNodes;
- std::vector<physx::PxVec3> mVertexPositions;
- std::vector<physx::PxVec3> mVertexNormals;
- std::vector<physx::PxVec2> mVertexUv;
+ std::vector<NvcVec3> mVertexPositions;
+ std::vector<NvcVec3> mVertexNormals;
+ std::vector<NvcVec2> mVertexUv;
std::vector<uint32_t> mIndices;
std::vector<int32_t> mSmoothingGroups;
std::vector<int32_t> mMaterialIds;
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp index f135436..4bd996b 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp @@ -28,24 +28,18 @@ #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);
+ NvcVec3ToFbx(vert.p, outVertex);
+ NvcVec3ToFbx(vert.n, outNormal);
+ NvcVec2ToFbx(vert.uv[0], outUV);
}
-void FbxUtils::PxVec3ToFbx(const physx::PxVec3& inVector, FbxVector4& outVector)
+void FbxUtils::NvcVec3ToFbx(const NvcVec3& inVector, FbxVector4& outVector)
{
outVector[0] = inVector.x;
outVector[1] = inVector.y;
@@ -53,7 +47,7 @@ void FbxUtils::PxVec3ToFbx(const physx::PxVec3& inVector, FbxVector4& outVector) outVector[3] = 0;
}
-void FbxUtils::PxVec2ToFbx(const physx::PxVec2& inVector, FbxVector2& outVector)
+void FbxUtils::NvcVec2ToFbx(const NvcVec2& inVector, FbxVector2& outVector)
{
outVector[0] = inVector.x;
outVector[1] = inVector.y;
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h index 431d63a..ca5b3a2 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h @@ -30,8 +30,7 @@ #define NVBLASTEXTEXPORTERFBXUTILS_H
#include "fbxsdk.h"
-#include "PxVec3.h"
-#include "PxVec2.h"
+#include <NvCTypes.h>
#include <string>
namespace Nv
@@ -47,8 +46,8 @@ 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 void NvcVec3ToFbx(const NvcVec3& inVector, FbxVector4& outVector);
+ static void NvcVec2ToFbx(const NvcVec2& inVector, FbxVector2& outVector);
static FbxAxisSystem getBlastFBXAxisSystem();
static FbxSystemUnit getBlastFBXUnit();
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp index a0de9d5..540e9de 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp @@ -43,20 +43,16 @@ #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)
+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)
- {
- manager->Destroy();
- });
+ // 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) { manager->Destroy(); });
mScene = FbxScene::Create(sdkManager.get(), "Export Scene");
@@ -65,7 +61,8 @@ FbxFileWriter::FbxFileWriter(): 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
+ // 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));
@@ -75,7 +72,7 @@ FbxFileWriter::FbxFileWriter(): void FbxFileWriter::release()
{
- //sdkManager->Destroy();
+ // sdkManager->Destroy();
delete this;
}
@@ -88,11 +85,11 @@ FbxScene* FbxFileWriter::getScene() void FbxFileWriter::createMaterials(const ExporterMeshData& aResult)
{
mMaterials.clear();
-
+
for (uint32_t i = 0; i < aResult.submeshCount; ++i)
{
FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager.get(), aResult.submeshMats[i].name);
- material->Diffuse.Set(FbxDouble3(float(rand()) / RAND_MAX , float(rand()) / RAND_MAX, float(rand()) / RAND_MAX));
+ 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);
}
@@ -121,7 +118,7 @@ void FbxFileWriter::createMaterials(const AuthoringResult& aResult) material->DiffuseFactor.Set(1.0);
mMaterials.push_back(material);
}
- if (mInteriorIndex == -1) // No material setted. Create new one.
+ if (mInteriorIndex == -1) // No material setted. Create new one.
{
FbxSurfacePhong* interiorMat = FbxSurfacePhong::Create(sdkManager.get(), "Interior_Material");
interiorMat->Diffuse.Set(FbxDouble3(1.0, 0.0, 0.5));
@@ -130,10 +127,11 @@ void FbxFileWriter::createMaterials(const AuthoringResult& aResult) }
else
{
- if (mInteriorIndex < 0) mInteriorIndex = 0;
- if (static_cast<size_t>(mInteriorIndex) >= mMaterials.size()) mInteriorIndex = 0;
+ if (mInteriorIndex < 0)
+ mInteriorIndex = 0;
+ if (static_cast<size_t>(mInteriorIndex) >= mMaterials.size())
+ mInteriorIndex = 0;
}
-
}
@@ -145,7 +143,8 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset {
return appendNonSkinnedMesh(aResult, assetName);
}
- std::string meshName(assetName); meshName.append("_rendermesh");
+ std::string meshName(assetName);
+ meshName.append("_rendermesh");
FbxMesh* mesh = FbxMesh::Create(sdkManager.get(), meshName.c_str());
@@ -158,20 +157,20 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset geUV->SetReferenceMode(FbxGeometryElement::eDirect);
FbxGeometryElementSmoothing* smElement = nullptr;
- size_t triangleCount = aResult.geometryOffset[aResult.chunkCount];
+ 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
+ // Found a valid smoothing group
smElement = mesh->CreateElementSmoothing();
smElement->SetMappingMode(FbxGeometryElement::eByPolygon);
smElement->SetReferenceMode(FbxGeometryElement::eDirect);
break;
}
}
-
+
mesh->InitControlPoints((int)triangleCount * 3);
@@ -188,13 +187,14 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset 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
+ // 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");
+ // 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);
@@ -204,7 +204,7 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset 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();
@@ -214,7 +214,7 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset // 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(aResult.asset, Nv::Blast::logLL);
- auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL);
+ auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL);
uint32_t cpIdx = 0;
for (uint32_t i = 0; i < chunkCount; i++)
@@ -230,7 +230,7 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset if (!smElement)
{
- //If no smoothing groups, generate them
+ // If no smoothing groups, generate them
generateSmoothingGroups(mesh, skin);
}
@@ -249,9 +249,9 @@ bool FbxFileWriter::appendNonSkinnedMesh(const AuthoringResult& aResult, const c {
FbxNode* lRootNode = mScene->GetRootNode();
- //UE4 cannot hide the root bone, so add a dummy chunk so chunk0 is not the root
+ // 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
+ // 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);
@@ -259,7 +259,7 @@ bool FbxFileWriter::appendNonSkinnedMesh(const AuthoringResult& aResult, const c // 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(aResult.asset, Nv::Blast::logLL);
- auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL);
+ auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL);
for (uint32_t i = 0; i < chunkCount; i++)
{
@@ -284,9 +284,9 @@ bool FbxFileWriter::appendNonSkinnedMesh(const ExporterMeshData& meshData, const {
FbxNode* lRootNode = mScene->GetRootNode();
- //UE4 cannot hide the root bone, so add a dummy chunk so chunk0 is not the root
+ // 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
+ // 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);
@@ -313,10 +313,11 @@ bool FbxFileWriter::appendNonSkinnedMesh(const ExporterMeshData& meshData, const return true;
}
-bool FbxFileWriter::appendCollisionMesh(uint32_t meshCount, uint32_t* offsets, CollisionHull** hulls, const char* assetName)
+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
+ // Hide by default
displayLayer->Show.Set(false);
displayLayer->Color.Set(FbxDouble3(0.0f, 0.0f, 1.0f));
@@ -331,26 +332,27 @@ bool FbxFileWriter::appendCollisionMesh(uint32_t meshCount, uint32_t* offsets, C 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]);
+ 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.
+ 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.
+ This creates a FbxNode with an FbxCluster, and all of the geometry for this chunk.
- Returns the number of added control points
+ 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)
+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);
+ 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]);
+ NvcVec3 centroid = { chunk->centroid[0], chunk->centroid[1], chunk->centroid[2] };
- //mesh->InitTextureUV(triangles.size() * 3);
+ // mesh->InitTextureUV(triangles.size() * 3);
std::string boneName = FbxUtils::getChunkNodeName(chunkIndex);
@@ -360,7 +362,7 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu skelAttrib->SetSkeletonType(FbxSkeleton::eRoot);
// Change the centroid to origin
- centroid = physx::PxVec3(0.0f);
+ centroid = { 0, 0, 0 };
}
else
{
@@ -368,7 +370,7 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu worldChunkPivots[chunkIndex] = centroid;
}
- skelAttrib->Size.Set(1.0); // What's this for?
+ skelAttrib->Size.Set(1.0); // What's this for?
FbxNode* boneNode = FbxNode::Create(sdkManager.get(), boneName.c_str());
@@ -382,7 +384,7 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu FbxVector4 c2 = mat.MultT(vec);
boneNode->LclTranslation.Set(c2);
-
+
parentNode->AddChild(boneNode);
std::ostringstream namestream;
@@ -398,14 +400,13 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu FbxMesh* mesh = static_cast<FbxMesh*>(meshNode->GetNodeAttribute());
- FbxVector4* controlPoints = mesh->GetControlPoints();
- auto geNormal = mesh->GetElementNormal();
- auto geUV = mesh->GetElementUV("diffuseElement");
+ 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)
- {
+ auto addVert = [&](Nv::Blast::Vertex vert, int controlPointIdx) {
FbxVector4 vertex;
FbxVector4 normal;
FbxVector2 uv;
@@ -419,7 +420,7 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu cluster->AddControlPointIndex(controlPointIdx, 1.0);
};
- uint32_t cpIdx = 0;
+ uint32_t cpIdx = 0;
uint32_t polyCount = mesh->GetPolygonCount();
for (uint32_t i = aResult.geometryOffset[chunkIndex]; i < aResult.geometryOffset[chunkIndex + 1]; i++)
{
@@ -433,7 +434,9 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu 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())) ? tri.materialId : 0) : ((mInteriorIndex == -1) ? int32_t(mMaterials.size() - 1): mInteriorIndex);
+ int32_t material = (tri.materialId != kMaterialInteriorId) ?
+ ((tri.materialId < int32_t(mMaterials.size())) ? tri.materialId : 0) :
+ ((mInteriorIndex == -1) ? int32_t(mMaterials.size() - 1) : mInteriorIndex);
matElement->GetIndexArray().SetAt(polyCount, material);
if (smElement)
{
@@ -443,21 +446,22 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu }
else
{
- smElement->GetDirectArray().Add(SMOOTHING_GROUP_INTERIOR);
+ smElement->GetDirectArray().Add(kSmoothingGroupInteriorId);
}
}
-
+
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);
+ 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++)
{
@@ -469,11 +473,12 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, uint32_t chunkIndex, FbxNode* parentNode,
- const std::vector<FbxSurfaceMaterial*>& materials, const ExporterMeshData& meshData)
+ const std::vector<FbxSurfaceMaterial*>& materials,
+ const ExporterMeshData& meshData)
{
- auto chunks = NvBlastAssetGetChunks(meshData.asset, Nv::Blast::logLL);
+ 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]);
+ NvcVec3 centroid = { chunk->centroid[0], chunk->centroid[1], chunk->centroid[2] };
std::string chunkName = FbxUtils::getChunkNodeName(chunkIndex);
@@ -491,27 +496,27 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, 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
+ // 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
+ // 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();
+ 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;
+ uint32_t cpCount = *lastIdx - *firstIdx;
mesh->InitControlPoints(cpCount);
geNormal->SetMappingMode(FbxGeometryElement::eByPolygonVertex);
@@ -528,9 +533,9 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, meshNode->AddMaterial(m);
}
- uint32_t cPolygCount = 0;
+ 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)
@@ -541,14 +546,14 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, mesh->AddPolygon(tr - *firstIdx + k);
FbxVector4 temp;
- FbxUtils::PxVec3ToFbx(meshData.positions[meshData.posIndex[tr + k]], temp);
+ FbxUtils::NvcVec3ToFbx(meshData.positions[meshData.posIndex[tr + k]], temp);
mesh->SetControlPointAt(temp, tr - *firstIdx + k);
- FbxUtils::PxVec3ToFbx(meshData.normals[meshData.normIndex[tr + k]], temp);
+ FbxUtils::NvcVec3ToFbx(meshData.normals[meshData.normIndex[tr + k]], temp);
geNormal->GetDirectArray().Add(temp);
-
+
FbxVector2 temp2;
- FbxUtils::PxVec2ToFbx(meshData.uvs[meshData.texIndex[tr + k]], temp2);
+ FbxUtils::NvcVec2ToFbx(meshData.uvs[meshData.texIndex[tr + k]], temp2);
geUV->GetDirectArray().Add(temp2);
}
mesh->EndPolygon();
@@ -559,7 +564,7 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, if (!mesh->GetElementSmoothing())
{
- //If no smoothing groups, generate them
+ // If no smoothing groups, generate them
generateSmoothingGroups(mesh, nullptr);
}
@@ -572,11 +577,13 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, }
-void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, uint32_t chunkIndex, FbxNode* parentNode, const std::vector<FbxSurfaceMaterial*>& materials, const AuthoringResult& aResult)
+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);
+ 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]);
+ NvcVec3 centroid = { chunk->centroid[0], chunk->centroid[1], chunk->centroid[2] };
std::string chunkName = FbxUtils::getChunkNodeName(chunkIndex).c_str();
@@ -595,7 +602,7 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, if (chunk->parentChunkIndex != UINT32_MAX)
{
- //Don't mess with the root chunk pivot
+ // Don't mess with the root chunk pivot
meshNode->LclTranslation.Set(c2);
worldChunkPivots[chunkIndex] = centroid;
}
@@ -603,7 +610,7 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, parentNode->AddChild(meshNode);
FbxAMatrix finalXForm = meshNode->EvaluateGlobalTransform();
- //Set the geo transform to inverse so we can use the world mesh coordinates
+ // 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());
@@ -611,8 +618,8 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, auto geNormal = mesh->CreateElementNormal();
- auto geUV = mesh->CreateElementUV("diffuseElement");
- auto matr = mesh->CreateElementMaterial();
+ auto geUV = mesh->CreateElementUV("diffuseElement");
+ auto matr = mesh->CreateElementMaterial();
uint32_t firstIdx = aResult.geometryOffset[chunkIndex];
uint32_t lastIdx = aResult.geometryOffset[chunkIndex + 1];
@@ -622,7 +629,7 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, {
if (aResult.geometry[triangle].smoothingGroup >= 0)
{
- //Found a valid smoothing group
+ // Found a valid smoothing group
smElement = mesh->CreateElementSmoothing();
smElement->SetMappingMode(FbxGeometryElement::eByPolygon);
smElement->SetReferenceMode(FbxGeometryElement::eDirect);
@@ -647,10 +654,10 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, }
FbxGeometryElementMaterial* matElement = mesh->GetElementMaterial();
- int32_t polyCount = 0;
+ int32_t polyCount = 0;
for (uint32_t tr = firstIdx; tr < lastIdx; tr++)
{
- auto& geo = aResult.geometry[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)
@@ -665,7 +672,9 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, geUV->GetDirectArray().Add(uv);
}
mesh->EndPolygon();
- int32_t material = (geo.materialId != MATERIAL_INTERIOR) ? ((geo.materialId < int32_t(mMaterials.size()))? geo.materialId : 0) : ((mInteriorIndex == -1)? int32_t(mMaterials.size() - 1) : mInteriorIndex);
+ int32_t material = (geo.materialId != kMaterialInteriorId) ?
+ ((geo.materialId < int32_t(mMaterials.size())) ? geo.materialId : 0) :
+ ((mInteriorIndex == -1) ? int32_t(mMaterials.size() - 1) : mInteriorIndex);
matElement->GetIndexArray().SetAt(polyCount, material);
if (smElement)
@@ -676,19 +685,17 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, }
else
{
- smElement->GetDirectArray().Add(SMOOTHING_GROUP_INTERIOR);
+ smElement->GetDirectArray().Add(kSmoothingGroupInteriorId);
}
}
- polyCount++;
-
+ polyCount++;
}
if (!smElement)
{
- //If no smoothing groups, generate them
+ // If no smoothing groups, generate them
generateSmoothingGroups(mesh, nullptr);
-
}
removeDuplicateControlPoints(mesh, nullptr);
@@ -699,19 +706,20 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, }
}
-uint32_t FbxFileWriter::addCollisionHulls(uint32_t chunkIndex, FbxDisplayLayer* displayLayer, FbxNode* parentNode, uint32_t hullsCount, CollisionHull** hulls)
+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;
+ 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
+ // TODO: Remove this when tools are converted over
FbxProperty::Create(collisionNode, FbxIntDT, "ParentalChunkIndex");
collisionNode->FindProperty("ParentalChunkIndex").Set(chunkIndex);
//
@@ -721,20 +729,20 @@ uint32_t FbxFileWriter::addCollisionHulls(uint32_t chunkIndex, FbxDisplayLayer* FbxMesh* meshAttr = FbxMesh::Create(sdkManager.get(), namestream.str().c_str());
collisionNode->SetNodeAttribute(meshAttr);
parentNode->AddChild(collisionNode);
-
- auto mat = parentNode->EvaluateGlobalTransform().Inverse();
+
+ 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
+ // 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
+ // 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());
@@ -744,7 +752,7 @@ uint32_t FbxFileWriter::addCollisionHulls(uint32_t chunkIndex, FbxDisplayLayer* meshAttr->InitControlPoints(hulls[hullId]->pointsCount);
meshAttr->CreateElementNormal();
FbxVector4* controlPoints = meshAttr->GetControlPoints();
- auto geNormal = meshAttr->GetElementNormal();
+ auto geNormal = meshAttr->GetElementNormal();
geNormal->SetMappingMode(FbxGeometryElement::eByPolygon);
geNormal->SetReferenceMode(FbxGeometryElement::eDirect);
for (uint32_t i = 0; i < hulls[hullId]->pointsCount; ++i)
@@ -758,128 +766,128 @@ uint32_t FbxFileWriter::addCollisionHulls(uint32_t chunkIndex, FbxDisplayLayer* {
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]);
+ for (uint32_t j = 0; j < poly.vertexCount; ++j)
+ {
+ meshAttr->AddPolygon(hulls[hullId]->indices[poly.indexBase + j]);
}
meshAttr->EndPolygon();
- FbxVector4 plane(poly.mPlane[0], poly.mPlane[1], poly.mPlane[2], 0);
+ FbxVector4 plane(poly.plane[0], poly.plane[1], poly.plane[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)
+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]);
+ auto chunks = NvBlastAssetGetChunks(meshData.asset, Nv::Blast::logLL);
+ const NvBlastChunk* chunk = &chunks[chunkIndex];
+ NvcVec3 centroid = { chunk->centroid[0], chunk->centroid[1], chunk->centroid[2] };
- std::string boneName = FbxUtils::getChunkNodeName(chunkIndex).c_str();
+ 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);
+ 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;
- }
+ // Change the centroid to origin
+ centroid = { 0, 0, 0 };
+ }
+ else
+ {
+ skelAttrib->SetSkeletonType(FbxSkeleton::eLimbNode);
+ worldChunkPivots[chunkIndex] = centroid;
+ }
+
+ FbxNode* boneNode = FbxNode::Create(sdkManager.get(), boneName.c_str());
+ boneNode->SetNodeAttribute(skelAttrib);
- FbxNode* boneNode = FbxNode::Create(sdkManager.get(), boneName.c_str());
- boneNode->SetNodeAttribute(skelAttrib);
+ chunkNodes[chunkIndex] = boneNode;
- chunkNodes[chunkIndex] = boneNode;
-
- auto mat = parentNode->EvaluateGlobalTransform().Inverse();
+ auto mat = parentNode->EvaluateGlobalTransform().Inverse();
- FbxVector4 vec(0, 0, 0, 0);
- FbxVector4 c2 = mat.MultT(vec);
+ FbxVector4 vec(0, 0, 0, 0);
+ FbxVector4 c2 = mat.MultT(vec);
- boneNode->LclTranslation.Set(c2);
+ boneNode->LclTranslation.Set(c2);
- parentNode->AddChild(boneNode);
+ parentNode->AddChild(boneNode);
- std::ostringstream namestream;
- namestream << "cluster_" << std::setw(5) << std::setfill('0') << chunkIndex;
- std::string clusterName = namestream.str();
+ 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);
+ FbxCluster* cluster = FbxCluster::Create(sdkManager.get(), clusterName.c_str());
+ cluster->SetTransformMatrix(FbxAMatrix());
+ cluster->SetLink(boneNode);
+ cluster->SetLinkMode(FbxCluster::eTotalOne);
- skin->AddCluster(cluster);
+ skin->AddCluster(cluster);
- FbxMesh* mesh = static_cast<FbxMesh*>(meshNode->GetNodeAttribute());
+ FbxMesh* mesh = static_cast<FbxMesh*>(meshNode->GetNodeAttribute());
- auto geNormal = mesh->GetElementNormal();
- auto geUV = mesh->GetElementUV("diffuseElement");
- auto matr = mesh->GetElementMaterial();
+ auto geNormal = mesh->GetElementNormal();
+ auto geUV = mesh->GetElementUV("diffuseElement");
+ auto matr = mesh->GetElementMaterial();
- std::vector<bool> addedVerticesFlag(mesh->GetControlPointsCount(), false);
+ 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)
+ 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)
{
- 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)
+ 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]])
{
- if (!addedVerticesFlag[meshData.posIndex[tr + k]])
- {
- cluster->AddControlPointIndex(meshData.posIndex[tr + k], 1.0);
- addedVerticesFlag[meshData.posIndex[tr + k]] = true;
- }
+ cluster->AddControlPointIndex(meshData.posIndex[tr + k], 1.0);
+ addedVerticesFlag[meshData.posIndex[tr + k]] = true;
}
}
}
- mat = meshNode->EvaluateGlobalTransform();
- cluster->SetTransformMatrix(mat);
+ }
+ mat = meshNode->EvaluateGlobalTransform();
+ cluster->SetTransformMatrix(mat);
- mat = boneNode->EvaluateGlobalTransform();
- cluster->SetTransformLinkMatrix(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);
- }
+ for (uint32_t i = chunk->firstChildIndex; i < chunk->childIndexStop; i++)
+ {
+ addedVertices += createChunkRecursive(currentCpIdx + addedVertices, i, meshNode, boneNode, skin, meshData);
+ }
- return addedVertices;
-
+ 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);
@@ -889,7 +897,7 @@ void FbxFileWriter::addControlPoints(FbxMesh* mesh, const ExporterMeshData& mesh 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)
+ for (uint32_t pi = *first; pi < *(first + 1); ++pi)
{
uint32_t p = meshData.posIndex[pi];
if (mapping[p] == -1)
@@ -902,14 +910,14 @@ void FbxFileWriter::addControlPoints(FbxMesh* mesh, const ExporterMeshData& mesh {
meshData.posIndex[pi] = mapping[p];
}
- }
+ }
}
}
mesh->InitControlPoints((int)vertices.size());
FbxVector4* controlPoints = mesh->GetControlPoints();
for (auto v : vertices)
{
- auto& p = meshData.positions[v];
+ auto& p = meshData.positions[v];
*controlPoints = FbxVector4(p.x, p.y, p.z, 0);
++controlPoints;
}
@@ -919,14 +927,14 @@ void FbxFileWriter::addControlPoints(FbxMesh* mesh, const ExporterMeshData& mesh 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
+ // 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);
+ FbxNode* node = mScene->GetNode(i);
FbxMatrix bindMat = node->EvaluateGlobalTransform();
pose->Add(node, bindMat);
@@ -942,11 +950,11 @@ bool FbxFileWriter::saveToFile(const char* assetName, const char* outputPath) 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);
@@ -962,7 +970,7 @@ bool FbxFileWriter::saveToFile(const char* assetName, const char* outputPath) lFormat = sdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX binary (*.fbx)");
}
- auto path = std::string(outputPath) + "\\" + assetName + ".fbx";
+ auto path = std::string(outputPath) + "\\" + assetName + ".fbx";
bool exportStatus = exporter->Initialize(path.c_str(), lFormat, sdkManager->GetIOSettings());
if (!exportStatus)
@@ -986,7 +994,6 @@ bool FbxFileWriter::saveToFile(const char* assetName, const char* outputPath) }
-
bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* assetName, bool nonSkinned)
{
createMaterials(meshData);
@@ -997,7 +1004,7 @@ bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* ass }
/**
- Get polygon count
+ Get polygon count
*/
uint32_t polygCount = meshData.submeshOffsets[meshData.meshCount * meshData.submeshCount] / 3;
@@ -1031,7 +1038,7 @@ bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* ass mesh->AddDeformer(skin);
/**
- Create control points, copy data to buffers
+ Create control points, copy data to buffers
*/
addControlPoints(mesh, meshData);
@@ -1047,7 +1054,7 @@ bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* ass 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);
@@ -1060,13 +1067,14 @@ bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* ass 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
+ // 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");
+ // 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);
@@ -1076,8 +1084,8 @@ bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* ass // 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;
+ 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];
@@ -1091,7 +1099,7 @@ bool FbxFileWriter::appendMesh(const ExporterMeshData& meshData, const char* ass if (!mesh->GetElementSmoothing())
{
- //If no smoothing groups, generate them
+ // If no smoothing groups, generate them
generateSmoothingGroups(mesh, skin);
}
@@ -1108,27 +1116,28 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin {
if (mesh->GetElementSmoothing(0) || !mesh->IsTriangleMesh())
{
- //they already exist or we can't make it
+ // they already exist or we can't make it
return;
}
const FbxGeometryElementNormal* geNormal = mesh->GetElementNormal();
- if (!geNormal || geNormal->GetMappingMode() != FbxGeometryElement::eByPolygonVertex || geNormal->GetReferenceMode() != FbxGeometryElement::eDirect)
+ if (!geNormal || geNormal->GetMappingMode() != FbxGeometryElement::eByPolygonVertex ||
+ geNormal->GetReferenceMode() != FbxGeometryElement::eDirect)
{
- //We just set this up, but just incase
+ // We just set this up, but just incase
return;
}
int clusterCount = 0;
- std::vector<std::vector<int>> cpsPerCluster;
+ std::vector<std::vector<int> > cpsPerCluster;
if (skin)
{
clusterCount = skin->GetClusterCount();
cpsPerCluster.resize(clusterCount);
for (int c = 0; c < clusterCount; c++)
{
- FbxCluster* cluster = skin->GetCluster(c);
- int* clusterCPList = cluster->GetControlPointIndices();
+ FbxCluster* cluster = skin->GetCluster(c);
+ int* clusterCPList = cluster->GetControlPointIndices();
const int clusterCPListLength = cluster->GetControlPointIndicesCount();
cpsPerCluster[c].resize(clusterCPListLength);
@@ -1142,17 +1151,17 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin smElement->SetReferenceMode(FbxGeometryElement::eDirect);
FbxVector4* cpList = mesh->GetControlPoints();
- const int cpCount = mesh->GetControlPointsCount();
+ const int cpCount = mesh->GetControlPointsCount();
const int triangleCount = mesh->GetPolygonCount();
- const int cornerCount = triangleCount * 3;
+ const int cornerCount = triangleCount * 3;
- int* polygonCPList = mesh->GetPolygonVertices();
+ int* polygonCPList = mesh->GetPolygonVertices();
const auto& normalByCornerList = geNormal->GetDirectArray();
std::multimap<int, int> overlappingCorners;
- //sort them by z for faster overlap checking
- std::vector<std::pair<double, int>> cornerIndexesByZ(cornerCount);
+ // sort them by z for faster overlap checking
+ std::vector<std::pair<double, int> > cornerIndexesByZ(cornerCount);
for (int c = 0; c < cornerCount; c++)
{
cornerIndexesByZ[c] = std::pair<double, int>(cpList[polygonCPList[c]][2], c);
@@ -1162,9 +1171,9 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin for (int i = 0; i < cornerCount; i++)
{
const int cornerA = cornerIndexesByZ[i].second;
- const int cpiA = polygonCPList[cornerA];
- FbxVector4 cpA = cpList[cpiA];
- cpA[3] = 0;
+ const int cpiA = polygonCPList[cornerA];
+ FbxVector4 cpA = cpList[cpiA];
+ cpA[3] = 0;
int clusterIndexA = -1;
for (int c = 0; c < clusterCount; c++)
@@ -1180,15 +1189,15 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin {
if (std::abs(cornerIndexesByZ[j].first - cornerIndexesByZ[i].first) > FBXSDK_TOLERANCE)
{
- break; // if the z's don't match other values don't matter
+ break; // if the z's don't match other values don't matter
}
const int cornerB = cornerIndexesByZ[j].second;
- const int cpiB = polygonCPList[cornerB];
- FbxVector4 cpB = cpList[cpiB];
+ const int cpiB = polygonCPList[cornerB];
+ FbxVector4 cpB = cpList[cpiB];
cpB[3] = 0;
- //uses FBXSDK_TOLERANCE
+ // uses FBXSDK_TOLERANCE
if (cpA == cpB)
{
int clusterIndexB = -1;
@@ -1215,7 +1224,7 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin {
smoothingGroupByTri.Add(0);
}
- //first one
+ // first one
smoothingGroupByTri.SetAt(0, 1);
for (int i = 1; i < triangleCount; i++)
@@ -1223,16 +1232,16 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin int sharedMask = 0, unsharedMask = 0;
for (int c = 0; c < 3; c++)
{
- int myCorner = i * 3 + c;
+ int myCorner = i * 3 + c;
FbxVector4 myNormal = normalByCornerList.GetAt(myCorner);
myNormal.Normalize();
myNormal[3] = 0;
auto otherCornersRangeBegin = overlappingCorners.lower_bound(myCorner);
- auto otherCornersRangeEnd = overlappingCorners.upper_bound(myCorner);
+ auto otherCornersRangeEnd = overlappingCorners.upper_bound(myCorner);
for (auto it = otherCornersRangeBegin; it != otherCornersRangeEnd; it++)
{
- int otherCorner = it->second;
+ int otherCorner = it->second;
FbxVector4 otherNormal = normalByCornerList.GetAt(otherCorner);
otherNormal.Normalize();
otherNormal[3] = 0;
@@ -1247,7 +1256,7 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin }
}
- //Easy case, no overlap
+ // Easy case, no overlap
if ((sharedMask & unsharedMask) == 0 && sharedMask != 0)
{
smoothingGroupByTri.SetAt(i, sharedMask);
@@ -1265,63 +1274,62 @@ void FbxFileWriter::generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin }
}
}
-
}
namespace
{
- //These methods have different names for some reason
- inline double* getControlPointBlendWeights(FbxSkin* skin)
- {
- return skin->GetControlPointBlendWeights();
- }
+// These methods have different names for some reason
+inline double* getControlPointBlendWeights(FbxSkin* skin)
+{
+ return skin->GetControlPointBlendWeights();
+}
- inline double* getControlPointBlendWeights(FbxCluster* cluster)
- {
- return cluster->GetControlPointWeights();
- }
+inline double* getControlPointBlendWeights(FbxCluster* cluster)
+{
+ return cluster->GetControlPointWeights();
+}
- template <typename T>
- void remapCPsAndRemoveDuplicates(const int newCPCount, const std::vector<int>& oldToNewCPMapping, T* skinOrCluster)
- {
- //Need to avoid duplicate entires since UE doesn't seem to normalize this correctly
- std::vector<bool> addedCP(newCPCount, false);
- std::vector<std::pair<int, double>> newCPsAndWeights;
- newCPsAndWeights.reserve(newCPCount);
+template <typename T>
+void remapCPsAndRemoveDuplicates(const int newCPCount, const std::vector<int>& oldToNewCPMapping, T* skinOrCluster)
+{
+ // Need to avoid duplicate entires since UE doesn't seem to normalize this correctly
+ std::vector<bool> addedCP(newCPCount, false);
+ std::vector<std::pair<int, double> > newCPsAndWeights;
+ newCPsAndWeights.reserve(newCPCount);
- int* skinCPList = skinOrCluster->GetControlPointIndices();
- double* skinCPWeights = getControlPointBlendWeights(skinOrCluster);
- const int skinCPListLength = skinOrCluster->GetControlPointIndicesCount();
+ int* skinCPList = skinOrCluster->GetControlPointIndices();
+ double* skinCPWeights = getControlPointBlendWeights(skinOrCluster);
+ const int skinCPListLength = skinOrCluster->GetControlPointIndicesCount();
- for (int bw = 0; bw < skinCPListLength; bw++)
- {
- int newCPIdx = oldToNewCPMapping[skinCPList[bw]];
- if (!addedCP[newCPIdx])
- {
- addedCP[newCPIdx] = true;
- newCPsAndWeights.emplace_back(newCPIdx, skinCPWeights[bw]);
- }
- }
- skinOrCluster->SetControlPointIWCount(newCPsAndWeights.size());
- skinCPList = skinOrCluster->GetControlPointIndices();
- skinCPWeights = getControlPointBlendWeights(skinOrCluster);
- for (size_t bw = 0; bw < newCPsAndWeights.size(); bw++)
+ for (int bw = 0; bw < skinCPListLength; bw++)
+ {
+ int newCPIdx = oldToNewCPMapping[skinCPList[bw]];
+ if (!addedCP[newCPIdx])
{
- skinCPList[bw] = newCPsAndWeights[bw].first;
- skinCPWeights[bw] = newCPsAndWeights[bw].second;
+ addedCP[newCPIdx] = true;
+ newCPsAndWeights.emplace_back(newCPIdx, skinCPWeights[bw]);
}
}
+ skinOrCluster->SetControlPointIWCount(newCPsAndWeights.size());
+ skinCPList = skinOrCluster->GetControlPointIndices();
+ skinCPWeights = getControlPointBlendWeights(skinOrCluster);
+ for (size_t bw = 0; bw < newCPsAndWeights.size(); bw++)
+ {
+ skinCPList[bw] = newCPsAndWeights[bw].first;
+ skinCPWeights[bw] = newCPsAndWeights[bw].second;
+ }
}
+} // namespace
-//Do this otherwise Maya shows the mesh as faceted due to not being welded
+// Do this otherwise Maya shows the mesh as faceted due to not being welded
void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* skin)
{
FbxVector4* cpList = mesh->GetControlPoints();
- const int cpCount = mesh->GetControlPointsCount();
+ const int cpCount = mesh->GetControlPointsCount();
std::vector<int> oldToNewCPMapping(cpCount, -1);
- //sort them by z for faster overlap checking
- std::vector<std::pair<double, int>> cpIndexesByZ(cpCount);
+ // sort them by z for faster overlap checking
+ std::vector<std::pair<double, int> > cpIndexesByZ(cpCount);
for (int cp = 0; cp < cpCount; cp++)
{
cpIndexesByZ[cp] = std::pair<double, int>(cpList[cp][2], cp);
@@ -1329,15 +1337,15 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* std::sort(cpIndexesByZ.begin(), cpIndexesByZ.end());
int clusterCount = 0;
- std::vector<std::vector<int>> cpsPerCluster;
+ std::vector<std::vector<int> > cpsPerCluster;
if (skin)
{
clusterCount = skin->GetClusterCount();
cpsPerCluster.resize(clusterCount);
for (int c = 0; c < clusterCount; c++)
{
- FbxCluster* cluster = skin->GetCluster(c);
- int* clusterCPList = cluster->GetControlPointIndices();
+ FbxCluster* cluster = skin->GetCluster(c);
+ int* clusterCPList = cluster->GetControlPointIndices();
const int clusterCPListLength = cluster->GetControlPointIndicesCount();
cpsPerCluster[c].resize(clusterCPListLength);
@@ -1355,10 +1363,10 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* FbxVector4 cpA = cpList[cpiA];
if (!(oldToNewCPMapping[cpiA] < 0))
{
- //already culled this one
+ // already culled this one
continue;
}
- const int newIdx = int(uniqueCPs.size());
+ const int newIdx = int(uniqueCPs.size());
oldToNewCPMapping[cpiA] = newIdx;
uniqueCPs.push_back(cpA);
@@ -1371,18 +1379,18 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* break;
}
}
-
+
for (int j = i + 1; j < cpCount; j++)
{
if (std::abs(cpIndexesByZ[j].first - cpIndexesByZ[i].first) > FBXSDK_TOLERANCE)
{
- break; // if the z's don't match other values don't matter
+ break; // if the z's don't match other values don't matter
}
-
+
const int cpiB = cpIndexesByZ[j].second;
FbxVector4 cpB = cpList[cpiB];
- //uses FBXSDK_TOLERANCE
+ // uses FBXSDK_TOLERANCE
if (cpA == cpB)
{
int clusterIndexB = -1;
@@ -1395,7 +1403,7 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* }
}
- //don't merge unless they share the same clusters
+ // don't merge unless they share the same clusters
if (clusterIndexA == clusterIndexB)
{
oldToNewCPMapping[cpiB] = newIdx;
@@ -1405,11 +1413,11 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* }
const int originalCPCount = cpCount;
- const int newCPCount = int(uniqueCPs.size());
+ const int newCPCount = int(uniqueCPs.size());
if (newCPCount == cpCount)
{
- //don't bother, it will just scramble it for no reason
+ // don't bother, it will just scramble it for no reason
return;
}
@@ -1421,7 +1429,7 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* cpList[cp] = uniqueCPs[cp];
}
- int* polygonCPList = mesh->GetPolygonVertices();
+ int* polygonCPList = mesh->GetPolygonVertices();
const int polygonCPListLength = mesh->GetPolygonVertexCount();
for (int pv = 0; pv < polygonCPListLength; pv++)
{
@@ -1436,6 +1444,5 @@ void FbxFileWriter::removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* FbxCluster* cluster = skin->GetCluster(c);
remapCPsAndRemoveDuplicates(newCPCount, oldToNewCPMapping, cluster);
}
-
}
}
\ No newline at end of file diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h index 75b4843..ad61fd5 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h @@ -106,7 +106,7 @@ private: //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;
+ std::map<uint32_t, NvcVec3> worldChunkPivots;
bool appendNonSkinnedMesh(const AuthoringResult& aResult, const char* assetName);
bool appendNonSkinnedMesh(const ExporterMeshData& meshData, const char* assetName);
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp index 7b63461..a9da985 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterJsonCollision.cpp @@ -39,14 +39,14 @@ using namespace Nv::Blast;
-void serializaHullPolygon(std::ofstream& stream, const CollisionHull::HullPolygon& p, uint32_t indent)
+void serializaHullPolygon(std::ofstream& stream, const 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" <<
+ bindent << JS_NAME("mIndexBase") << p.indexBase << ",\n" <<
+ bindent << JS_NAME("mPlane") << "[" << p.plane[0] << ", " << p.plane[1] << ", " << p.plane[2] << ", " << p.plane[3] << "],\n" <<
+ bindent << JS_NAME("mNbVerts") << p.vertexCount << "\n" <<
sindent << "}";
}
void serializeCollisionHull(std::ofstream& stream, const CollisionHull& hl, uint32_t indent)
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp index d43c1ae..9d44947 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp @@ -106,17 +106,17 @@ void ObjFileReader::loadFromFile(const char* filename) 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]));
+ mVertexPositions.push_back({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]));
+ mVertexNormals.push_back({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]));
+ mVertexUv.push_back({txVec[i * 2], txVec[i * 2 + 1]});
}
mIndices = shapes[0].mesh.indices;
@@ -145,17 +145,17 @@ uint32_t ObjFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::Collisio return 0;
};
-physx::PxVec3* ObjFileReader::getPositionArray()
+NvcVec3* ObjFileReader::getPositionArray()
{
return mVertexPositions.data();
};
-physx::PxVec3* ObjFileReader::getNormalsArray()
+NvcVec3* ObjFileReader::getNormalsArray()
{
return mVertexNormals.data();
};
-physx::PxVec2* ObjFileReader::getUvArray()
+NvcVec2* ObjFileReader::getUvArray()
{
return mVertexUv.data();
};
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h index 7657be3..0f3e843 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h @@ -75,15 +75,15 @@ public: /**
Get loaded vertex positions
*/
- virtual physx::PxVec3* getPositionArray() override;
+ virtual NvcVec3* getPositionArray() override;
/**
Get loaded vertex normals
*/
- virtual physx::PxVec3* getNormalsArray() override;
+ virtual NvcVec3* getNormalsArray() override;
/**
Get loaded vertex uv-coordinates
*/
- virtual physx::PxVec2* getUvArray() override;
+ virtual NvcVec2* getUvArray() override;
/**
Get loaded triangle indices
*/
@@ -110,9 +110,9 @@ public: int32_t getMaterialCount() { return mMaterialNames.size(); };
private:
- std::vector<physx::PxVec3> mVertexPositions;
- std::vector<physx::PxVec3> mVertexNormals;
- std::vector<physx::PxVec2> mVertexUv;
+ std::vector<NvcVec3> mVertexPositions;
+ std::vector<NvcVec3> mVertexNormals;
+ std::vector<NvcVec2> mVertexUv;
std::vector<uint32_t> mIndices;
std::vector<std::string> mMaterialNames;
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp index e6ec276..3cd8c62 100755 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp @@ -103,9 +103,9 @@ bool ObjFileWriter::appendMesh(const AuthoringResult& aResult, const char* /*ass 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.positions = new NvcVec3[md.positionsCount];
+ md.normals = new NvcVec3[md.normalsCount];
+ md.uvs = new NvcVec2[md.uvsCount];
md.posIndex = new uint32_t[triCount * 3];
md.normIndex = md.posIndex;
@@ -132,7 +132,7 @@ bool ObjFileWriter::appendMesh(const AuthoringResult& aResult, const char* /*ass {
sorted.push_back(aResult.geometry[t]);
int32_t cmat = sorted.back().materialId;
- if (cmat == MATERIAL_INTERIOR)
+ if (cmat == kMaterialInteriorId)
{
cmat = mIntSurfaceMatIndex;
}
diff --git a/sdk/extensions/import/include/NvBlastExtApexImportTool.h b/sdk/extensions/import/include/NvBlastExtApexImportTool.h index 3eb4f71..e2c815f 100755 --- a/sdk/extensions/import/include/NvBlastExtApexImportTool.h +++ b/sdk/extensions/import/include/NvBlastExtApexImportTool.h @@ -33,6 +33,7 @@ #include <vector>
#include <string>
#include "NvBlastExtPxAsset.h"
+#include "NvBlastExtPxCollisionBuilder.h"
#include <nvparameterized\NvSerializer.h>
#include <NvBlastExtExporter.h>
@@ -179,6 +180,11 @@ public: const std::vector<uint32_t>& apexChunkFlags, std::vector<ExtPxAssetDesc::ChunkDesc>& physicsChunks,
std::vector<ExtPxAssetDesc::SubchunkDesc>& physicsSubchunks, std::vector<std::vector<CollisionHull*> >& hullsDesc);
+ const ExtPxCollisionBuilder* getCollisionBuilder() const
+ {
+ return m_collisionBuilder;
+ }
+
//////////////////////////////////////////////////////////////////////////////
bool isValid();
@@ -199,6 +205,7 @@ protected: physx::PxPhysics* m_PhysxSDK;
physx::PxCooking* m_Cooking;
+ ExtPxCollisionBuilder* m_collisionBuilder;
};
} // namespace ApexImporter
diff --git a/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp b/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp index fad9ade..44566f5 100755 --- a/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp +++ b/sdk/extensions/import/source/NvBlastExtApexImportTool.cpp @@ -30,7 +30,7 @@ #if NV_VC
#pragma warning(push)
-#pragma warning(disable: 4996) // 'fopen' unsafe warning, from NxFileBuffer.h
+#pragma warning(disable : 4996) // 'fopen' unsafe warning, from NxFileBuffer.h
#endif
#include "PxFoundation.h"
@@ -40,7 +40,9 @@ #include <NvBlastExtExporter.h>
#include <PxConvexMesh.h>
#include "PxPhysics.h"
-#include "NvBlastExtAuthoringCollisionBuilder.h"
+#include "NvBlastExtAuthoringConvexMeshBuilder.h"
+#include "NvBlastExtPxManager.h"
+#include "NvBlastExtPxCollisionBuilder.h"
#include "NvBlastExtPxAsset.h"
#include "NvBlastExtAuthoring.h"
#include "NvBlastExtAuthoringBondGenerator.h"
@@ -74,6 +76,7 @@ #include <PxPhysicsAPI.h>
#include "NvBlastPxCallbacks.h"
+#include "NvBlastPxSharedHelpers.h"
using namespace nvidia;
using namespace physx;
@@ -88,26 +91,26 @@ namespace Blast namespace ApexImporter
{
- /**
- Should be consistent with IntPair in APEX
- */
- struct IntPair
+/**
+ Should be consistent with IntPair in APEX
+*/
+struct IntPair
+{
+ void set(int32_t _i0, int32_t _i1)
{
- void set(int32_t _i0, int32_t _i1)
- {
- i0 = _i0;
- i1 = _i1;
- }
+ i0 = _i0;
+ i1 = _i1;
+ }
- int32_t i0, i1;
+ int32_t i0, i1;
+
+ static int compare(const void* a, const void* b)
+ {
+ const int32_t diff0 = ((IntPair*)a)->i0 - ((IntPair*)b)->i0;
+ return diff0 ? diff0 : (((IntPair*)a)->i1 - ((IntPair*)b)->i1);
+ }
+};
- static int compare(const void* a, const void* b)
- {
- const int32_t diff0 = ((IntPair*)a)->i0 - ((IntPair*)b)->i0;
- return diff0 ? diff0 : (((IntPair*)a)->i1 - ((IntPair*)b)->i1);
- }
- };
-
bool ApexImportTool::loadAssetFromFile(physx::PxFileBuf* stream, NvParameterized::Serializer::DeserializedData& data)
{
if (stream && stream->isOpen())
@@ -115,7 +118,8 @@ bool ApexImportTool::loadAssetFromFile(physx::PxFileBuf* stream, NvParameterized NvParameterized::Serializer::SerializeType serType = NvParameterized::Serializer::peekSerializeType(*stream);
NvParameterized::Serializer::ErrorType serError;
- NvParameterized::Traits* traits = new NvParameterized::DefaultTraits(NvParameterized::DefaultTraits::BehaviourFlags::DEFAULT_POLICY);
+ NvParameterized::Traits* traits =
+ new NvParameterized::DefaultTraits(NvParameterized::DefaultTraits::BehaviourFlags::DEFAULT_POLICY);
nvidia::destructible::ModuleDestructibleRegistration::invokeRegistration(traits);
ModuleDestructibleLegacyRegistration::invokeRegistration(traits);
@@ -157,25 +161,27 @@ bool ApexImportTool::isValid() enum ChunkFlags
{
- SupportChunk = (1 << 0),
- UnfracturableChunk = (1 << 1),
+ SupportChunk = (1 << 0),
+ UnfracturableChunk = (1 << 1),
DescendantUnfractureable = (1 << 2),
- UndamageableChunk = (1 << 3),
- UncrumbleableChunk = (1 << 4),
- RuntimeFracturableChunk = (1 << 5),
- Instanced = (1 << 8),
+ UndamageableChunk = (1 << 3),
+ UncrumbleableChunk = (1 << 4),
+ RuntimeFracturableChunk = (1 << 5),
+ Instanced = (1 << 8),
};
uint32_t getPartIndex(const DestructibleAssetParameters* prm, uint32_t id)
{
auto& sch = prm->chunks.buf[id];
- return (sch.flags & ChunkFlags::Instanced) == 0 ? sch.meshPartIndex : prm->chunkInstanceInfo.buf[sch.meshPartIndex].partIndex;
+ return (sch.flags & ChunkFlags::Instanced) == 0 ? sch.meshPartIndex :
+ prm->chunkInstanceInfo.buf[sch.meshPartIndex].partIndex;
}
ApexImportTool::ApexImportTool()
{
- m_Foundation = PxCreateFoundation(PX_FOUNDATION_VERSION, NvBlastGetPxAllocatorCallback(), NvBlastGetPxErrorCallback());
+ m_Foundation =
+ PxCreateFoundation(PX_FOUNDATION_VERSION, NvBlastGetPxAllocatorCallback(), NvBlastGetPxErrorCallback());
if (!m_Foundation)
{
NVBLAST_LOG_ERROR("Error: failed to create Foundation\n");
@@ -186,46 +192,47 @@ ApexImportTool::ApexImportTool() if (!m_PhysxSDK)
{
NVBLAST_LOG_ERROR("Error: failed to create PhysX\n");
-
+
return;
}
-
+
physx::PxCookingParams cookingParams(scale);
cookingParams.buildGPUData = true;
- m_Cooking = PxCreateCooking(PX_PHYSICS_VERSION, m_PhysxSDK->getFoundation(), cookingParams);
+ m_Cooking = PxCreateCooking(PX_PHYSICS_VERSION, m_PhysxSDK->getFoundation(), cookingParams);
if (!m_Cooking)
{
NVBLAST_LOG_ERROR("Error: failed to create PhysX Cooking\n");
return;
}
-
+ m_collisionBuilder = ExtPxManager::createCollisionBuilder(*m_PhysxSDK, *m_Cooking);
}
-bool ApexImportTool::getCollisionGeometry(const NvParameterized::Interface* assetPrm, 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<std::vector<CollisionHull*> >& hullsDesc)
+bool ApexImportTool::getCollisionGeometry(const NvParameterized::Interface* assetPrm, 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<std::vector<CollisionHull*> >& hullsDesc)
{
physicsChunks.clear();
physicsChunks.resize(chunkCount);
// prepare physics asset desc (convexes, transforms)
- std::shared_ptr<ConvexMeshBuilder> collisionBuilder(
- NvBlastExtAuthoringCreateConvexMeshBuilder(m_Cooking, &m_PhysxSDK->getPhysicsInsertionCallback()),
- [](ConvexMeshBuilder* cmb) { cmb->release(); });
const DestructibleAssetParameters* params = static_cast<const DestructibleAssetParameters*>(assetPrm);
- int32_t apexHullCount = 0;
+ int32_t apexHullCount = 0;
const uint32_t apexChunkCount = params->chunks.arraySizes[0];
-
+
for (uint32_t chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
{
uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
if (apexChunkIndex < apexChunkCount)
{
- uint32_t partIndex = getPartIndex(params, apexChunkIndex);
- uint32_t partConvexHullCount = params->chunkConvexHullStartIndices.buf[partIndex + 1] - params->chunkConvexHullStartIndices.buf[partIndex];
+ uint32_t partIndex = getPartIndex(params, apexChunkIndex);
+ uint32_t partConvexHullCount = params->chunkConvexHullStartIndices.buf[partIndex + 1] -
+ params->chunkConvexHullStartIndices.buf[partIndex];
apexHullCount += partConvexHullCount;
}
}
@@ -238,9 +245,11 @@ bool ApexImportTool::getCollisionGeometry(const NvParameterized::Interface* asse uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
if (apexChunkIndex < apexChunkCount)
{
- uint32_t partIndex = getPartIndex(params, apexChunkIndex);
- uint32_t partConvexHullCount = params->chunkConvexHullStartIndices.buf[partIndex + 1] - params->chunkConvexHullStartIndices.buf[partIndex];
- NvParameterized::Interface** cxInterfaceArray = params->chunkConvexHulls.buf + params->chunkConvexHullStartIndices.buf[partIndex];
+ uint32_t partIndex = getPartIndex(params, apexChunkIndex);
+ uint32_t partConvexHullCount = params->chunkConvexHullStartIndices.buf[partIndex + 1] -
+ params->chunkConvexHullStartIndices.buf[partIndex];
+ NvParameterized::Interface** cxInterfaceArray =
+ params->chunkConvexHulls.buf + params->chunkConvexHullStartIndices.buf[partIndex];
physicsChunks[chunkIndex].subchunkCount = partConvexHullCount;
for (uint32_t hull = 0; hull < partConvexHullCount; ++hull)
{
@@ -248,20 +257,21 @@ bool ApexImportTool::getCollisionGeometry(const NvParameterized::Interface* asse int32_t verticesCount = 0;
paramHandle.getParameter("vertices");
paramHandle.getArraySize(verticesCount);
- std::vector<PxVec3> vertexData(verticesCount);
- paramHandle.getParamVec3Array(vertexData.data(), verticesCount);
+ std::vector<NvcVec3> vertexData(verticesCount);
+ paramHandle.getParamVec3Array(toPxShared(vertexData.data()), verticesCount);
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),
- PxConvexMeshGeometry(convexMesh)
- };
+ hullsDesc[chunkIndex].back() =
+ m_collisionBuilder->buildCollisionGeometry(verticesCount, vertexData.data());
+ auto collisionHull = m_collisionBuilder->buildCollisionGeometry(verticesCount, vertexData.data());
+ auto convexMesh = m_collisionBuilder->buildConvexMesh(*collisionHull);
+ m_collisionBuilder->releaseCollisionHull(collisionHull);
+
+ const ExtPxAssetDesc::SubchunkDesc subchunk = { PxTransform(PxIdentity),
+ PxConvexMeshGeometry(convexMesh) };
physicsSubchunks.push_back(subchunk);
}
- physicsChunks[chunkIndex].subchunks = partConvexHullCount ? (&physicsSubchunks.back() + 1 - partConvexHullCount) : nullptr;
+ physicsChunks[chunkIndex].subchunks =
+ partConvexHullCount ? (&physicsSubchunks.back() + 1 - partConvexHullCount) : nullptr;
// static flag set
physicsChunks[chunkIndex].isStatic = (apexChunkFlags[apexChunkIndex] & (1 << 1)) != 0;
@@ -282,7 +292,10 @@ bool ApexImportTool::getCollisionGeometry(const NvParameterized::Interface* asse return true;
}
-PxBounds3 gatherChunkTriangles(std::vector<uint32_t>& chunkToPartMp, const nvidia::apex::RenderMeshAssetParameters* rmAsset, std::vector<uint32_t>& chunkTrianglesOffsets, std::vector<Nv::Blast::Triangle>& chunkTriangles, int32_t posBufferIndex, float scale, PxVec3 offset )
+PxBounds3
+gatherChunkTriangles(std::vector<uint32_t>& chunkToPartMp, const nvidia::apex::RenderMeshAssetParameters* rmAsset,
+ std::vector<uint32_t>& chunkTrianglesOffsets, std::vector<Nv::Blast::Triangle>& chunkTriangles,
+ int32_t posBufferIndex, float scale, PxVec3 offset)
{
PxBounds3 bnd;
@@ -293,16 +306,18 @@ PxBounds3 gatherChunkTriangles(std::vector<uint32_t>& chunkToPartMp, const nvidi chunkTrianglesOffsets[0] = 0;
for (uint32_t chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex)
{
- uint32_t part = chunkToPartMp[chunkIndex];
+ uint32_t part = chunkToPartMp[chunkIndex];
uint32_t submeshCount = rmAsset->submeshes.arraySizes[0];
for (uint32_t submeshIndex = 0; submeshIndex < submeshCount; ++submeshIndex)
{
- nvidia::apex::SubmeshParameters* submeshPrm = static_cast<nvidia::apex::SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
+ nvidia::apex::SubmeshParameters* submeshPrm =
+ static_cast<nvidia::apex::SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
const uint32_t* indexArray = submeshPrm->indexBuffer.buf + submeshPrm->indexPartition.buf[part];
uint32_t indexCount = submeshPrm->indexPartition.buf[part + 1] - submeshPrm->indexPartition.buf[part];
- nvidia::apex::VertexBufferParameters* vbuf = static_cast<nvidia::apex::VertexBufferParameters*>(submeshPrm->vertexBuffer);
+ nvidia::apex::VertexBufferParameters* vbuf =
+ static_cast<nvidia::apex::VertexBufferParameters*>(submeshPrm->vertexBuffer);
nvidia::apex::BufferF32x3* pbuf = static_cast<nvidia::apex::BufferF32x3*>(vbuf->buffers.buf[posBufferIndex]);
@@ -317,13 +332,10 @@ PxBounds3 gatherChunkTriangles(std::vector<uint32_t>& chunkToPartMp, const nvidi bnd.include(positions[indexArray[i + 1]]);
bnd.include(positions[indexArray[i + 2]]);
- a.p = positions[indexArray[i]] - offset;
- b.p = positions[indexArray[i + 1]] - offset;
- c.p = positions[indexArray[i + 2]] - offset;
- a.p *= scale;
- b.p *= scale;
- c.p *= scale;
- chunkTriangles.push_back(Nv::Blast::Triangle(a, b, c));
+ a.p = fromPxShared(positions[indexArray[i]] - offset) * scale;
+ b.p = fromPxShared(positions[indexArray[i + 1]] - offset) * scale;
+ c.p = fromPxShared(positions[indexArray[i + 2]] - offset) * scale;
+ chunkTriangles.push_back({a, b, c});
}
}
chunkTrianglesOffsets[chunkIndex + 1] = chunkTriangles.size();
@@ -332,7 +344,8 @@ PxBounds3 gatherChunkTriangles(std::vector<uint32_t>& chunkToPartMp, const nvidi }
bool ApexImportTool::importApexAsset(std::vector<uint32_t>& chunkReorderInvMap, NvParameterized::Interface* assetNvIfc,
- std::vector<NvBlastChunkDesc>& chunkDescriptors, std::vector<NvBlastBondDesc>& bondDescriptors, std::vector<uint32_t>& apexChunkFlags)
+ std::vector<NvBlastChunkDesc>& chunkDescriptors,
+ std::vector<NvBlastBondDesc>& bondDescriptors, std::vector<uint32_t>& apexChunkFlags)
{
ApexImporterConfig configDesc;
configDesc.setDefaults();
@@ -341,17 +354,20 @@ bool ApexImportTool::importApexAsset(std::vector<uint32_t>& chunkReorderInvMap, bool ApexImportTool::importApexAsset(std::vector<uint32_t>& chunkReorderInvMap, NvParameterized::Interface* assetNvIfc,
- std::vector<NvBlastChunkDesc>& chunkDescriptors, std::vector<NvBlastBondDesc>& bondDescriptors, std::vector<uint32_t>& apexChunkFlags, const ApexImporterConfig& configDesc)
+ std::vector<NvBlastChunkDesc>& chunkDescriptors,
+ std::vector<NvBlastBondDesc>& bondDescriptors,
+ std::vector<uint32_t>& apexChunkFlags, const ApexImporterConfig& configDesc)
{
- return importApexAssetInternal(chunkReorderInvMap, assetNvIfc, chunkDescriptors, bondDescriptors, apexChunkFlags, configDesc);
+ return importApexAssetInternal(chunkReorderInvMap, assetNvIfc, chunkDescriptors, bondDescriptors, apexChunkFlags,
+ configDesc);
}
-
-
-
-bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorderInvMap, NvParameterized::Interface* assetNvIfc,
- std::vector<NvBlastChunkDesc>& chunkDescriptors, std::vector<NvBlastBondDesc>& bondsDescriptors, std::vector<uint32_t>& apexChunkFlags, const ApexImporterConfig& configDesc)
+bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorderInvMap,
+ NvParameterized::Interface* assetNvIfc,
+ std::vector<NvBlastChunkDesc>& chunkDescriptors,
+ std::vector<NvBlastBondDesc>& bondsDescriptors,
+ std::vector<uint32_t>& apexChunkFlags, const ApexImporterConfig& configDesc)
{
if (!assetNvIfc)
{
@@ -360,14 +376,15 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder }
DestructibleAssetParameters* params = static_cast<nvidia::destructible::DestructibleAssetParameters*>(assetNvIfc);
- int32_t apexChunkCount = params->chunks.arraySizes[0];
+ int32_t apexChunkCount = params->chunks.arraySizes[0];
uint32_t rootChunkIndex = 0;
std::vector<uint32_t> chunkToPartMapping(apexChunkCount);
chunkDescriptors.resize(apexChunkCount);
- nvidia::apex::RenderMeshAssetParameters* rmParam = static_cast<nvidia::apex::RenderMeshAssetParameters*>(params->renderMeshAsset);
+ nvidia::apex::RenderMeshAssetParameters* rmParam =
+ static_cast<nvidia::apex::RenderMeshAssetParameters*>(params->renderMeshAsset);
std::vector<PxBounds3> perChunkBounds(apexChunkCount);
PxBounds3 allRmBound;
@@ -376,19 +393,21 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder for (uint32_t i = 0; i < (uint32_t)apexChunkCount; ++i)
{
// Use bounds center for centroid
- uint32_t partIndex = getPartIndex(params, i);
- chunkToPartMapping[i] = partIndex;
+ uint32_t partIndex = getPartIndex(params, i);
+ chunkToPartMapping[i] = partIndex;
const PxBounds3 bounds = rmParam->partBounds.buf[partIndex];
perChunkBounds[i] = bounds;
allRmBound.include(bounds);
-
+
const PxVec3 center = bounds.getCenter();
memcpy(chunkDescriptors[i].centroid, ¢er.x, 3 * sizeof(float));
// Find chunk volume
- uint32_t partConvexHullCount = params->chunkConvexHullStartIndices.buf[partIndex + 1] - params->chunkConvexHullStartIndices.buf[partIndex];
- NvParameterized::Interface** cxInterfaceArray = params->chunkConvexHulls.buf + params->chunkConvexHullStartIndices.buf[partIndex];
+ uint32_t partConvexHullCount =
+ params->chunkConvexHullStartIndices.buf[partIndex + 1] - params->chunkConvexHullStartIndices.buf[partIndex];
+ NvParameterized::Interface** cxInterfaceArray =
+ params->chunkConvexHulls.buf + params->chunkConvexHullStartIndices.buf[partIndex];
chunkDescriptors[i].volume = 0.0f;
for (uint32_t hull = 0; hull < partConvexHullCount; ++hull)
{
@@ -402,7 +421,7 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder int16_t parent = params->chunks.buf[i].parentIndex;
if (parent == -1)
{
- rootChunkIndex = i;
+ rootChunkIndex = i;
chunkDescriptors[i].parentChunkIndex = UINT32_MAX;
}
else
@@ -410,19 +429,20 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder chunkDescriptors[i].parentChunkIndex = parent;
}
- chunkDescriptors[i].flags = 0;
+ chunkDescriptors[i].flags = 0;
chunkDescriptors[i].userData = i;
}
// Get support graph data from Apex asset //
const NvParameterized::Interface* assetParameterized = assetNvIfc;
- uint32_t maximumSupportDepth = 0;
+ uint32_t maximumSupportDepth = 0;
NvParameterized::Handle parameterHandle(*assetParameterized);
parameterHandle.getParameter("supportDepth");
parameterHandle.getParamU32(maximumSupportDepth);
std::vector<std::pair<uint32_t, uint32_t> > overlapsBuffer;
- nvidia::destructible::CachedOverlaps* overlapsArray = static_cast<nvidia::destructible::CachedOverlaps*>(params->overlapsAtDepth.buf[maximumSupportDepth]);
+ nvidia::destructible::CachedOverlaps* overlapsArray =
+ static_cast<nvidia::destructible::CachedOverlaps*>(params->overlapsAtDepth.buf[maximumSupportDepth]);
uint32_t overlapsCount = overlapsArray->overlaps.arraySizes[0];
if (overlapsCount != 0)
{
@@ -437,7 +457,7 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder }
}
- // Format all connections as (chunk with lower index) -> (chunk with higher index) //
+ // Format all connections as (chunk with lower index) -> (chunk with higher index) //
for (uint32_t i = 0; i < overlapsBuffer.size(); ++i)
{
@@ -456,14 +476,14 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder bondsDescriptors.resize(overlapsBuffer.size());
std::shared_ptr<Nv::Blast::BlastBondGenerator> bondGenTool(
- NvBlastExtAuthoringCreateBondGenerator(m_Cooking, &m_PhysxSDK->getPhysicsInsertionCallback()),
- [](Nv::Blast::BlastBondGenerator* bg) {bg->release(); });
+ NvBlastExtAuthoringCreateBondGenerator(m_collisionBuilder),
+ [](Nv::Blast::BlastBondGenerator* bg) { bg->release(); });
std::vector<uint32_t> chunkTrianglesOffsets;
std::vector<Nv::Blast::Triangle> chunkTriangles;
-
+
PxBounds3 bnds = allRmBound;
- PxVec3 offset = bnds.getCenter();
+ PxVec3 offset = bnds.getCenter();
float scale = 1.0f / PxMax(PxAbs(bnds.getExtents(0)), PxMax(PxAbs(bnds.getExtents(1)), PxAbs(bnds.getExtents(2))));
bnds = gatherChunkTriangles(chunkToPartMapping, rmParam, chunkTrianglesOffsets, chunkTriangles, 0, scale, offset);
@@ -482,8 +502,9 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder 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);
+ 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());
NVBLAST_FREE(bondsDesc);
@@ -499,9 +520,8 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder bondsDescriptors[i].bond.centroid[0] += offset.x;
bondsDescriptors[i].bond.centroid[1] += offset.y;
bondsDescriptors[i].bond.centroid[2] += offset.z;
-
}
-
+
/// Delete all bonds with zero area ///
for (uint32_t i = 0; i < bondsDescriptors.size(); ++i)
{
@@ -509,7 +529,7 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder {
bondsDescriptors[i].chunkIndices[0] = bondsDescriptors.back().chunkIndices[0];
bondsDescriptors[i].chunkIndices[1] = bondsDescriptors.back().chunkIndices[1];
- bondsDescriptors[i].bond = bondsDescriptors.back().bond;
+ bondsDescriptors[i].bond = bondsDescriptors.back().bond;
bondsDescriptors.pop_back();
--i;
}
@@ -521,7 +541,7 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder {
for (uint32_t i = 0; i < chunkDescriptors.size(); i++)
{
- uint32_t chunkID = i;
+ uint32_t chunkID = i;
const NvParameterized::Interface* assetInterface = assetNvIfc;
NvParameterized::Handle chunksHandle(*assetInterface, "chunks");
chunksHandle.set(chunkID);
@@ -537,9 +557,9 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder {
NvBlastBondDesc bond;
bond.chunkIndices[0] = i;
- bond.chunkIndices[1] = UINT32_MAX; // invalid index for "world"
- bond.bond.area = 0.1f; // ???
- PxVec3 center = perChunkBounds[i].getCenter();
+ bond.chunkIndices[1] = UINT32_MAX; // invalid index for "world"
+ bond.bond.area = 0.1f; // ???
+ PxVec3 center = perChunkBounds[i].getCenter();
memcpy(&bond.bond.centroid, ¢er.x, sizeof(PxVec3));
PxVec3 normal = PxVec3(0, 0, 1);
memcpy(&bond.bond.normal, &normal.x, sizeof(PxVec3));
@@ -549,14 +569,17 @@ bool ApexImportTool::importApexAssetInternal(std::vector<uint32_t>& chunkReorder }
const uint32_t chunkCount = static_cast<uint32_t>(chunkDescriptors.size());
- const uint32_t bondCount = static_cast<uint32_t>(bondsDescriptors.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(), logLL);
- NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDescriptors.data(), chunkCount, scratch.data(), logLL);
- NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDescriptors.data(), chunkCount, bondsDescriptors.data(), bondCount, chunkReorderMap.data(), true, 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()));
+ Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(),
+ static_cast<uint32_t>(chunkReorderMap.size()));
return true;
}
@@ -564,10 +587,10 @@ const float VEC_EPS = 1e-4f; class MaterialXmlParser : public physx::shdfnd::FastXml::Callback
{
-public:
+ public:
std::string textureFile;
-protected:
+ protected:
// encountered a comment in the XML
virtual bool processComment(const char* /*comment*/)
{
@@ -580,10 +603,11 @@ protected: }
// return true to continue processing the XML document, false to skip.
- virtual bool processElement(const char* elementName, // name of the element
- const char* elementData, // element data, null if none
- const physx::shdfnd::FastXml::AttributePairs& attr,
- int /*lineno*/) // line number in the source XML file
+ virtual bool processElement(const char* elementName, // name of the element
+ const char* elementData, // element data, null if none
+ const physx::shdfnd::FastXml::AttributePairs& attr, int /*lineno*/) // line number in
+ // the source XML
+ // file
{
PX_UNUSED(attr);
if (::strcmp(elementName, "sampler2D") == 0)
@@ -610,21 +634,21 @@ protected: class PxInputDataFromPxFileBuf : public physx::PxInputData
{
-public:
+ public:
PxInputDataFromPxFileBuf(physx::PxFileBuf& fileBuf) : mFileBuf(fileBuf) {}
// physx::PxInputData interface
- virtual uint32_t getLength() const
+ virtual uint32_t getLength() const
{
return mFileBuf.getFileLength();
}
- virtual void seek(uint32_t offset)
+ virtual void seek(uint32_t offset)
{
mFileBuf.seekRead(offset);
}
- virtual uint32_t tell() const
+ virtual uint32_t tell() const
{
return mFileBuf.tellRead();
}
@@ -636,7 +660,7 @@ public: }
PX_NOCOPY(PxInputDataFromPxFileBuf)
-private:
+ private:
physx::PxFileBuf& mFileBuf;
};
@@ -659,14 +683,18 @@ std::string getTextureFromMaterial(const char* materialPath) #define MAX_PATH_LEN 260
-bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderInvMap, const NvParameterized::Interface* assetNvIfc, ExporterMeshData* outputData, const char* materialsDir)
+bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderInvMap,
+ const NvParameterized::Interface* assetNvIfc, ExporterMeshData* outputData,
+ const char* materialsDir)
{
- const nvidia::destructible::DestructibleAssetParameters* dasset = static_cast<const nvidia::destructible::DestructibleAssetParameters*>(assetNvIfc);
- const nvidia::apex::RenderMeshAssetParameters* rmAsset = static_cast<const nvidia::apex::RenderMeshAssetParameters*>(dasset->renderMeshAsset);
+ const nvidia::destructible::DestructibleAssetParameters* dasset =
+ static_cast<const nvidia::destructible::DestructibleAssetParameters*>(assetNvIfc);
+ const nvidia::apex::RenderMeshAssetParameters* rmAsset =
+ static_cast<const nvidia::apex::RenderMeshAssetParameters*>(dasset->renderMeshAsset);
outputData->submeshCount = rmAsset->submeshes.arraySizes[0];
- outputData->submeshMats = new Material[outputData->submeshCount];
+ outputData->submeshMats = new Material[outputData->submeshCount];
std::vector<Material> materialArray(outputData->submeshCount);
std::vector<std::string> materialPathes;
materialPathes.reserve(outputData->submeshCount);
@@ -680,19 +708,19 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI std::ostringstream materialPath;
materialPath << materialsDir << "\\" << materialName;
std::string texturePath = getTextureFromMaterial(materialPath.str().c_str());
- int32_t bfs = texturePath.length();
- char* texPath = new char[bfs + 1];
- char* matName = new char[bfs + 1];
+ int32_t bfs = texturePath.length();
+ char* texPath = new char[bfs + 1];
+ char* matName = new char[bfs + 1];
memset(texPath, 0, sizeof(char) * (bfs + 1));
memset(matName, 0, sizeof(char) * (bfs + 1));
memcpy(texPath, texturePath.data(), sizeof(char) * bfs);
- memcpy(matName, texturePath.data(), sizeof(char) * bfs);
+ memcpy(matName, texturePath.data(), sizeof(char) * bfs);
outputData->submeshMats[submeshIndex].diffuse_tex = texPath;
- outputData->submeshMats[submeshIndex].name = matName;
+ outputData->submeshMats[submeshIndex].name = matName;
}
else
{
- int32_t bfs = strnlen(materialName, MAX_PATH_LEN);
+ int32_t bfs = strnlen(materialName, MAX_PATH_LEN);
char* texPath = new char[bfs];
char* matName = new char[bfs];
memset(texPath, 0, sizeof(char) * (bfs + 1));
@@ -700,7 +728,7 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI memcpy(texPath, materialName, sizeof(char) * bfs);
memcpy(matName, materialName, sizeof(char) * bfs);
outputData->submeshMats[submeshIndex].diffuse_tex = texPath;
- outputData->submeshMats[submeshIndex].name = matName;
+ outputData->submeshMats[submeshIndex].name = matName;
}
}
}
@@ -708,11 +736,16 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI {
bool operator()(const PxVec3& a, const PxVec3& b) const
{
- if (a.x + VEC_EPS < b.x) return true;
- if (a.x - VEC_EPS > b.x) return false;
- if (a.y + VEC_EPS < b.y) return true;
- if (a.y - VEC_EPS > b.y) return false;
- if (a.z + VEC_EPS < b.z) return true;
+ if (a.x + VEC_EPS < b.x)
+ return true;
+ if (a.x - VEC_EPS > b.x)
+ return false;
+ if (a.y + VEC_EPS < b.y)
+ return true;
+ if (a.y - VEC_EPS > b.y)
+ return false;
+ if (a.z + VEC_EPS < b.z)
+ return true;
return false;
}
};
@@ -720,9 +753,12 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI {
bool operator()(const PxVec2& a, const PxVec2& b) const
{
- if (a.x + VEC_EPS < b.x) return true;
- if (a.x - VEC_EPS > b.x) return false;
- if (a.y + VEC_EPS < b.y) return true;
+ if (a.x + VEC_EPS < b.x)
+ return true;
+ if (a.x - VEC_EPS > b.x)
+ return false;
+ if (a.y + VEC_EPS < b.y)
+ return true;
return false;
}
};
@@ -744,12 +780,15 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI {
for (uint32_t submeshIndex = 0; submeshIndex < outputData->submeshCount; ++submeshIndex)
{
- nvidia::apex::SubmeshParameters* currentSubmesh = static_cast<nvidia::apex::SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
- nvidia::apex::VertexBufferParameters* vbuf = static_cast<nvidia::apex::VertexBufferParameters*>(currentSubmesh->vertexBuffer);
- nvidia::apex::VertexFormatParameters* vbufFormat = static_cast<nvidia::apex::VertexFormatParameters*>(vbuf->vertexFormat);
+ nvidia::apex::SubmeshParameters* currentSubmesh =
+ static_cast<nvidia::apex::SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
+ nvidia::apex::VertexBufferParameters* vbuf =
+ static_cast<nvidia::apex::VertexBufferParameters*>(currentSubmesh->vertexBuffer);
+ nvidia::apex::VertexFormatParameters* vbufFormat =
+ static_cast<nvidia::apex::VertexFormatParameters*>(vbuf->vertexFormat);
uint32_t indexCount = vbuf->vertexCount;
// Find position buffer index
- int32_t vbufIds[3]; // 0 - pos, 1 - normals, 2 - t-coord
+ int32_t vbufIds[3]; // 0 - pos, 1 - normals, 2 - t-coord
vbufIds[0] = vbufIds[1] = vbufIds[2] = -1;
{
for (int32_t bid = 0; bid < vbufFormat->bufferFormats.arraySizes[0]; ++bid)
@@ -770,9 +809,9 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI }
if (vbufIds[0] != -1)
{
- BufferF32x3* pbuf = static_cast<BufferF32x3*>(vbuf->buffers.buf[vbufIds[0]]);
+ BufferF32x3* pbuf = static_cast<BufferF32x3*>(vbuf->buffers.buf[vbufIds[0]]);
const PxVec3* posistions = pbuf->data.buf;
- uint32_t oldSize = (uint32_t)positionsMapping.size();
+ uint32_t oldSize = (uint32_t)positionsMapping.size();
positionsMapping.resize(oldSize + indexCount);
for (uint32_t i = 0; i < indexCount; ++i)
@@ -780,7 +819,7 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI auto it = posMap.find(posistions[i]);
if (it == posMap.end())
{
- posMap[posistions[i]] = (uint32_t)compressedPositions.size();
+ posMap[posistions[i]] = (uint32_t)compressedPositions.size();
positionsMapping[oldSize + i] = (uint32_t)compressedPositions.size();
compressedPositions.push_back(posistions[i]);
}
@@ -793,16 +832,16 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI if (vbufIds[1] != -1)
{
- BufferF32x3* pbuf = static_cast<BufferF32x3*>(vbuf->buffers.buf[vbufIds[1]]);
+ BufferF32x3* pbuf = static_cast<BufferF32x3*>(vbuf->buffers.buf[vbufIds[1]]);
const PxVec3* normals = pbuf->data.buf;
- uint32_t oldSize = (uint32_t)normalsMapping.size();
+ uint32_t oldSize = (uint32_t)normalsMapping.size();
normalsMapping.resize(oldSize + indexCount);
for (uint32_t i = 0; i < indexCount; ++i)
{
auto it = normMap.find(normals[i]);
if (it == normMap.end())
{
- normMap[normals[i]] = (uint32_t)compressedNormals.size();
+ normMap[normals[i]] = (uint32_t)compressedNormals.size();
normalsMapping[oldSize + i] = (uint32_t)compressedNormals.size();
compressedNormals.push_back(normals[i]);
}
@@ -814,16 +853,16 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI }
if (vbufIds[2] != -1)
{
- BufferF32x2* pbuf = static_cast<BufferF32x2*>(vbuf->buffers.buf[vbufIds[2]]);
+ BufferF32x2* pbuf = static_cast<BufferF32x2*>(vbuf->buffers.buf[vbufIds[2]]);
const PxVec2* texCoord = reinterpret_cast<PxVec2*>(pbuf->data.buf);
- uint32_t oldSize = (uint32_t)texturesMapping.size();
+ uint32_t oldSize = (uint32_t)texturesMapping.size();
texturesMapping.resize(oldSize + indexCount);
for (uint32_t i = 0; i < indexCount; ++i)
{
auto it = texMap.find(texCoord[i]);
if (it == texMap.end())
{
- texMap[texCoord[i]] = (uint32_t)compressedTextures.size();
+ texMap[texCoord[i]] = (uint32_t)compressedTextures.size();
texturesMapping[oldSize + i] = (uint32_t)compressedTextures.size();
compressedTextures.push_back(texCoord[i]);
}
@@ -835,84 +874,84 @@ bool ApexImportTool::importRendermesh(const std::vector<uint32_t>& chunkReorderI }
}
}
- for (uint32_t i = 0; i < compressedTextures.size(); ++i)
+ for (uint32_t i = 0; i < compressedTextures.size(); ++i)
+ {
+ std::swap(compressedTextures[i].x, compressedTextures[i].y);
+ }
+
+ outputData->positionsCount = (uint32_t)compressedPositions.size();
+ // meshData.positions = compressedPositions.data();
+ outputData->positions = new NvcVec3[outputData->positionsCount];
+ memcpy(outputData->positions, compressedPositions.data(), sizeof(NvcVec3) * outputData->positionsCount);
+ outputData->normalsCount = (uint32_t)compressedNormals.size();
+ // meshData.normals = compressedNormals.data();
+ outputData->normals = new NvcVec3[outputData->normalsCount];
+ memcpy(outputData->normals, compressedNormals.data(), sizeof(NvcVec3) * outputData->normalsCount);
+ outputData->uvsCount = (uint32_t)compressedTextures.size();
+ // meshData.uvs = compressedTextures.data();
+ outputData->uvs = new NvcVec2[outputData->uvsCount];
+ memcpy(outputData->uvs, compressedTextures.data(), sizeof(NvcVec2) * outputData->uvsCount);
+
+ uint32_t apexChunkCount = dasset->chunks.arraySizes[0];
+ outputData->meshCount = (uint32_t)chunkReorderInvMap.size();
+ outputData->submeshOffsets = new uint32_t[outputData->meshCount * outputData->submeshCount + 1]{ 0 };
+
+ // count total number of indices
+ for (uint32_t chunkIndex = 0; chunkIndex < apexChunkCount; ++chunkIndex)
+ {
+ uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
+ if (apexChunkIndex >= apexChunkCount)
{
- std::swap(compressedTextures[i].x, compressedTextures[i].y);
+ PX_ALWAYS_ASSERT();
+ continue;
}
+ uint32_t part = getPartIndex(dasset, chunkIndex);
+ for (uint32_t submeshIndex = 0; submeshIndex < outputData->submeshCount; ++submeshIndex)
+ {
+ SubmeshParameters* sm = static_cast<SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
- outputData->positionsCount = (uint32_t)compressedPositions.size();
- //meshData.positions = compressedPositions.data();
- outputData->positions = new PxVec3[outputData->positionsCount];
- memcpy(outputData->positions, compressedPositions.data(), sizeof(PxVec3) * outputData->positionsCount);
- outputData->normalsCount = (uint32_t)compressedNormals.size();
- //meshData.normals = compressedNormals.data();
- outputData->normals = new PxVec3[outputData->normalsCount];
- memcpy(outputData->normals, compressedNormals.data(), sizeof(PxVec3) * outputData->normalsCount);
- outputData->uvsCount = (uint32_t)compressedTextures.size();
- //meshData.uvs = compressedTextures.data();
- outputData->uvs = new PxVec2[outputData->uvsCount];
- memcpy(outputData->uvs, compressedTextures.data(), sizeof(PxVec2) * outputData->uvsCount);
-
- uint32_t apexChunkCount = dasset->chunks.arraySizes[0];
- outputData->meshCount = (uint32_t)chunkReorderInvMap.size();
- outputData->submeshOffsets = new uint32_t[outputData->meshCount * outputData->submeshCount + 1]{ 0 };
-
- //count total number of indices
- for (uint32_t chunkIndex = 0; chunkIndex < apexChunkCount; ++chunkIndex)
+ uint32_t indexCount = sm->indexPartition.buf[part + 1] - sm->indexPartition.buf[part];
+ uint32_t* firstIdx = outputData->submeshOffsets + chunkIndex * outputData->submeshCount + submeshIndex;
+ *(firstIdx + 1) = *firstIdx + indexCount;
+ }
+ }
+ outputData->posIndex = new uint32_t[outputData->submeshOffsets[outputData->meshCount * outputData->submeshCount]];
+ outputData->normIndex = new uint32_t[outputData->submeshOffsets[outputData->meshCount * outputData->submeshCount]];
+ outputData->texIndex = new uint32_t[outputData->submeshOffsets[outputData->meshCount * outputData->submeshCount]];
+ // copy indices
+ for (uint32_t chunkIndex = 0; chunkIndex < outputData->meshCount; ++chunkIndex)
+ {
+ uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
+ if (apexChunkIndex >= apexChunkCount)
{
- uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
- if (apexChunkIndex >= apexChunkCount)
- {
- PX_ALWAYS_ASSERT();
- continue;
- }
- uint32_t part = getPartIndex(dasset, chunkIndex);
- for (uint32_t submeshIndex = 0; submeshIndex < outputData->submeshCount; ++submeshIndex)
- {
- SubmeshParameters* sm = static_cast<SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
-
- uint32_t indexCount = sm->indexPartition.buf[part + 1] - sm->indexPartition.buf[part];
- uint32_t* firstIdx = outputData->submeshOffsets + chunkIndex * outputData->submeshCount + submeshIndex;
- *(firstIdx + 1) = *firstIdx + indexCount;
- }
+ PX_ALWAYS_ASSERT();
+ continue;
}
- outputData->posIndex = new uint32_t[outputData->submeshOffsets[outputData->meshCount * outputData->submeshCount]];
- outputData->normIndex = new uint32_t[outputData->submeshOffsets[outputData->meshCount * outputData->submeshCount]];
- outputData->texIndex = new uint32_t[outputData->submeshOffsets[outputData->meshCount * outputData->submeshCount]];
- //copy indices
- for (uint32_t chunkIndex = 0; chunkIndex < outputData->meshCount; ++chunkIndex)
+ uint32_t part = getPartIndex(dasset, chunkIndex);
+ uint32_t offset = 0;
+ for (uint32_t submeshIndex = 0; submeshIndex < outputData->submeshCount; ++submeshIndex)
{
- uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
- if (apexChunkIndex >= apexChunkCount)
- {
- PX_ALWAYS_ASSERT();
- continue;
- }
- uint32_t part = getPartIndex(dasset, chunkIndex);
- uint32_t offset = 0;
- for (uint32_t submeshIndex = 0; submeshIndex < outputData->submeshCount; ++submeshIndex)
- {
- SubmeshParameters* sm = static_cast<SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
- const uint32_t* indexArray = sm->indexBuffer.buf + sm->indexPartition.buf[part];
- uint32_t indexCount = sm->indexPartition.buf[part + 1] - sm->indexPartition.buf[part];
+ SubmeshParameters* sm = static_cast<SubmeshParameters*>(rmAsset->submeshes.buf[submeshIndex]);
+ const uint32_t* indexArray = sm->indexBuffer.buf + sm->indexPartition.buf[part];
+ uint32_t indexCount = sm->indexPartition.buf[part + 1] - sm->indexPartition.buf[part];
- uint32_t firstIdx = outputData->submeshOffsets[chunkIndex * outputData->submeshCount + submeshIndex];
+ uint32_t firstIdx = outputData->submeshOffsets[chunkIndex * outputData->submeshCount + submeshIndex];
- for (uint32_t i = 0; i < indexCount; ++i)
- {
- outputData->posIndex[firstIdx + i] = positionsMapping[indexArray[i] + offset];
- outputData->normIndex[firstIdx + i] = normalsMapping[indexArray[i] + offset];
- outputData->texIndex[firstIdx + i] = texturesMapping[indexArray[i] + offset];
- }
- nvidia::apex::VertexBufferParameters* vbuf = static_cast<nvidia::apex::VertexBufferParameters*>(sm->vertexBuffer);
- offset += vbuf->vertexCount;
+ for (uint32_t i = 0; i < indexCount; ++i)
+ {
+ outputData->posIndex[firstIdx + i] = positionsMapping[indexArray[i] + offset];
+ outputData->normIndex[firstIdx + i] = normalsMapping[indexArray[i] + offset];
+ outputData->texIndex[firstIdx + i] = texturesMapping[indexArray[i] + offset];
}
+ nvidia::apex::VertexBufferParameters* vbuf =
+ static_cast<nvidia::apex::VertexBufferParameters*>(sm->vertexBuffer);
+ offset += vbuf->vertexCount;
}
- return true;
+ }
+ return true;
}
-
bool ApexImportTool::saveAsset(const NvBlastAsset* asset, PxFileBuf* stream)
{
if (!asset)
@@ -925,7 +964,7 @@ bool ApexImportTool::saveAsset(const NvBlastAsset* asset, PxFileBuf* stream) NVBLAST_LOG_ERROR("Error: bad output stream.");
return false;
}
- const void* assetData = asset;
+ const void* assetData = asset;
uint32_t assetDataSize = NvBlastAssetGetSize(asset, logLL);
stream->write(assetData, assetDataSize);
stream->close();
@@ -936,9 +975,14 @@ bool ApexImportTool::saveAsset(const NvBlastAsset* asset, PxFileBuf* stream) ApexImportTool::~ApexImportTool()
{
+ m_collisionBuilder->release();
+ m_Cooking->release();
+ m_PhysxSDK->release();
+ m_Foundation->release();
+
}
-} // namespace ApexImporter
+} // namespace ApexImporter
-} // namespace Blast
-} // namespace Nv
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/physx/include/NvBlastExtPxCollisionBuilder.h b/sdk/extensions/physx/include/NvBlastExtPxCollisionBuilder.h new file mode 100644 index 0000000..b7a2f14 --- /dev/null +++ b/sdk/extensions/physx/include/NvBlastExtPxCollisionBuilder.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-2018 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTPXCOLLISIONBUILDER_H +#define NVBLASTEXTPXCOLLISIONBUILDER_H + +#include "NvBlastExtAuthoringConvexMeshBuilder.h" + +namespace physx +{ + class PxConvexMesh; +} +namespace Nv +{ +namespace Blast +{ +struct AuthoringResult; +struct ExtPxChunk; +struct ExtPxSubchunk; + +/** +ConvexMeshBuilder provides routine to build collision hulls from array of vertices. +Collision hull is built as convex hull of provided point set. +If due to some reason building of convex hull is failed, collision hull is built as bounding box of vertex set. +PhysX implementation can be found in NvBlastExtPx. +*/ +class ExtPxCollisionBuilder : public ConvexMeshBuilder +{ + public: + /** + Method creates user defined collision mesh from provided array of vertices. + ConvexMeshBuilder from ExtPhysX returns PxConvexMesh pointer. + \param[in] hull Collision hull. + */ + virtual physx::PxConvexMesh* buildConvexMesh(const CollisionHull& hull) = 0; + + /** + Build physics chunks and subchunks from collision hulls + */ + virtual void buildPhysicsChunks(uint32_t chunkCount, uint32_t* hullOffsets, CollisionHull** hulls, + ExtPxChunk* physicsChunks, ExtPxSubchunk* physicsSubchunks) = 0; +}; + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTPXCOLLISIONBUILDER_H diff --git a/sdk/extensions/physx/include/NvBlastExtPxManager.h b/sdk/extensions/physx/include/NvBlastExtPxManager.h index 1a6e5e3..690ab90 100755 --- a/sdk/extensions/physx/include/NvBlastExtPxManager.h +++ b/sdk/extensions/physx/include/NvBlastExtPxManager.h @@ -39,6 +39,7 @@ namespace physx
{
class PxPhysics;
+class PxCooking;
class PxRigidDynamic;
class PxJoint;
@@ -46,7 +47,7 @@ namespace general_PxIOStream2 {
class PxFileBuf;
}
-}
+} // namespace physx
namespace Nv
@@ -63,6 +64,7 @@ class TkFamily; class TkFramework;
class TkGroup;
class TkJoint;
+class ExtPxCollisionBuilder;
/**
@@ -72,9 +74,10 @@ Used to create Physics Family. */
struct ExtPxFamilyDesc
{
- 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
+ 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
};
@@ -83,7 +86,9 @@ Function pointer for PxJoint creation. It will be called when new joints are being created. It should return valid PxJoint pointer or nullptr.
*/
-typedef physx::PxJoint*(*ExtPxCreateJointFunction)(ExtPxActor* actor0, const physx::PxTransform& localFrame0, ExtPxActor* actor1, const physx::PxTransform& localFrame1, physx::PxPhysics& physics, TkJoint& joint);
+typedef physx::PxJoint* (*ExtPxCreateJointFunction)(ExtPxActor* actor0, const physx::PxTransform& localFrame0,
+ ExtPxActor* actor1, const physx::PxTransform& localFrame1,
+ physx::PxPhysics& physics, TkJoint& joint);
/**
@@ -93,7 +98,7 @@ Used to create and manage Physics Families. */
class NV_DLL_EXPORT ExtPxManager
{
-public:
+ public:
//////// manager creation ////////
/**
@@ -101,18 +106,25 @@ public: \param[in] physics The PxPhysics instance to be used by ExtPxManager.
\param[in] framework The TkFramework instance to be used by ExtPxManager.
+ \param[in] cooking The optional PxCooking. Required for collision builder.
\param[in] createFn The function to be used when creating joints, can be nullptr.
- \param[in] useUserData Flag if ExtPxManager is allowed to override PxActor's userData, it will store pointer to PxActor there.
- It is recommended as fastest way. If set to 'false' HashMap will be used.
+ \param[in] useUserData Flag if ExtPxManager is allowed to override PxActor's userData, it will store pointer to
+ PxActor there. It is recommended as fastest way. If set to 'false' HashMap will be used.
\return the new ExtPxManager if successful, NULL otherwise.
*/
- static ExtPxManager* create(physx::PxPhysics& physics, TkFramework& framework, ExtPxCreateJointFunction createFn = nullptr, bool useUserData = true);
+ static ExtPxManager* create(physx::PxPhysics& physics, TkFramework& framework,
+ ExtPxCreateJointFunction createFn = nullptr, bool useUserData = true);
+
+ /**
+ Create PhysX based convex mesh builder.
+ */
+ static ExtPxCollisionBuilder* createCollisionBuilder(physx::PxPhysics& physics, physx::PxCooking& cooking);
/**
Release this manager.
*/
- virtual void release() = 0;
+ virtual void release() = 0;
//////// impact ////////
@@ -133,9 +145,10 @@ public: \param[in] desc The family descriptor (see ExtPxFamilyDesc).
- \return the created family, if the descriptor was valid and memory was available for the operation. Otherwise, returns NULL.
+ \return the created family, if the descriptor was valid and memory was available for the operation. Otherwise,
+ returns NULL.
*/
- virtual ExtPxFamily* createFamily(const ExtPxFamilyDesc& desc) = 0;
+ virtual ExtPxFamily* createFamily(const ExtPxFamilyDesc& desc) = 0;
/**
Create a px joint associated with TkJoint.
@@ -147,28 +160,28 @@ public: \return true iff Joint was created.
*/
- virtual bool createJoint(TkJoint& joint) = 0;
+ virtual bool createJoint(TkJoint& joint) = 0;
/**
Destroy a px joint associated with TkJoint.
\param[in] joint TkJoint to be used to destroy px joint.
*/
- virtual void destroyJoint(TkJoint& joint) = 0;
+ virtual void destroyJoint(TkJoint& joint) = 0;
/**
Set ExtPxCreateJointFunction to be used when new joints are being created.\
\param[in] createFn Create function pointer to set, can be nullptr.
*/
- virtual void setCreateJointFunction(ExtPxCreateJointFunction createFn) = 0;
+ virtual void setCreateJointFunction(ExtPxCreateJointFunction createFn) = 0;
/**
The number of families currently in this manager.
\return the number of ExtPxFamily that currently exist in this manger.
*/
- virtual uint32_t getFamilyCount() const = 0;
+ virtual uint32_t getFamilyCount() const = 0;
/**
Retrieve an array of pointers (into the user-supplied buffer) to families.
@@ -178,7 +191,7 @@ public: \return the number of ExtPxFamily pointers written to the buffer.
*/
- virtual uint32_t getFamilies(ExtPxFamily** buffer, uint32_t bufferSize) const = 0;
+ virtual uint32_t getFamilies(ExtPxFamily** buffer, uint32_t bufferSize) const = 0;
/**
Look up an associated ExtPxFamily by TkFamily pointer.
@@ -187,7 +200,7 @@ public: \return pointer to the ExtPxFamily object if it exists, NULL otherwise.
*/
- virtual ExtPxFamily* getFamilyFromTkFamily(TkFamily& family) const = 0;
+ virtual ExtPxFamily* getFamilyFromTkFamily(TkFamily& family) const = 0;
/**
Look up an associated ExtPxActor by PxRigidDynamic pointer.
@@ -196,68 +209,69 @@ public: \return pointer to the ExtPxActor object if it exists, NULL otherwise.
*/
- virtual ExtPxActor* getActorFromPhysXActor(const physx::PxRigidDynamic& pxActor) const = 0;
+ virtual ExtPxActor* getActorFromPhysXActor(const physx::PxRigidDynamic& pxActor) const = 0;
/**
Get a PxPhysics object pointer used upon manager creation.
\return a pointer to the (const) PxPhysics object.
*/
- virtual physx::PxPhysics& getPhysics() const = 0;
+ virtual physx::PxPhysics& getPhysics() const = 0;
/**
Get a TkFramework object pointer used upon manager creation.
\return a pointer to the TkFramework object.
*/
- virtual TkFramework& getFramework() const = 0;
+ virtual TkFramework& getFramework() const = 0;
/**
Get if useUserData was set upon manager creation.
\return true iff PxActor userData is used by manager.
*/
- virtual bool isPxUserDataUsed() const = 0;
+ virtual bool isPxUserDataUsed() const = 0;
/**
Limits the total number of actors that can exist at a given time. A value of zero disables this (gives no limit).
\param[in] limit If not zero, the maximum number of actors that will be allowed to exist.
*/
- virtual void setActorCountLimit(uint32_t limit) = 0;
+ virtual void setActorCountLimit(uint32_t limit) = 0;
/**
- Retrieve the limit to the total number of actors that can exist at a given time. A value of zero disables this (gives no limit).
+ Retrieve the limit to the total number of actors that can exist at a given time. A value of zero disables this
+ (gives no limit).
\return the limit to the total number of actors that can exist at a given time (or zero if there is no limit).
*/
- virtual uint32_t getActorCountLimit() = 0;
+ virtual uint32_t getActorCountLimit() = 0;
/**
The total number of PxActors generated by Blast.
\return the total number of PxActors generated by Blast.
*/
- virtual uint32_t getPxActorCount() const = 0;
+ virtual uint32_t getPxActorCount() const = 0;
/**
Add a user implementation of ExtPxListener to this family's list of listeners.
\param[in] listener The event listener to add.
*/
- virtual void subscribe(ExtPxListener& listener) = 0;
+ virtual void subscribe(ExtPxListener& listener) = 0;
/**
Remove a user implementation of ExtPxListener from this family's list of listeners.
\param[in] listener The event listener to remove.
*/
- virtual void unsubscribe(ExtPxListener& listener) = 0;
+ virtual void unsubscribe(ExtPxListener& listener) = 0;
};
-} // namespace Blast
-} // namespace Nv
+} // namespace Blast
+} // namespace Nv
-#endif // ifndef NVBLASTEXTPXMANAGER_H
+#endif // ifndef NVBLASTEXTPXMANAGER_H
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxCollisionBuilderImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxCollisionBuilderImpl.cpp new file mode 100644 index 0000000..4f653a7 --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxCollisionBuilderImpl.cpp @@ -0,0 +1,232 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation 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-2018 NVIDIA Corporation. All rights reserved. + +#include <NvBlastGlobals.h> +#include "NvBlastExtPxCollisionBuilderImpl.h" +#include "NvBlastExtAuthoringTypes.h" +#include "NvBlastExtPxAsset.h" +#include <PxConvexMesh.h> +#include "PxPhysics.h" +#include "cooking/PxCooking.h" +#include <NvBlastPxSharedHelpers.h> +#include <vector> +#include <set> + +using namespace physx; + +#define SAFE_ARRAY_NEW(T, x) ((x) > 0) ? reinterpret_cast<T*>(NVBLAST_ALLOC(sizeof(T) * (x))) : nullptr; +#define SAFE_ARRAY_DELETE(x) \ + if (x != nullptr) \ + { \ + NVBLAST_FREE(x); \ + x = nullptr; \ + } + +namespace Nv +{ +namespace Blast +{ + +CollisionHullImpl::~CollisionHullImpl() +{ + SAFE_ARRAY_DELETE(points); + SAFE_ARRAY_DELETE(indices); + SAFE_ARRAY_DELETE(polygonData); +} + +CollisionHullImpl::CollisionHullImpl(const CollisionHull& hullToCopy) +{ + pointsCount = hullToCopy.pointsCount; + indicesCount = hullToCopy.indicesCount; + polygonDataCount = hullToCopy.polygonDataCount; + + points = SAFE_ARRAY_NEW(NvcVec3, pointsCount); + indices = SAFE_ARRAY_NEW(uint32_t, indicesCount); + polygonData = SAFE_ARRAY_NEW(HullPolygon, polygonDataCount); + memcpy(points, hullToCopy.points, sizeof(points[0]) * pointsCount); + memcpy(indices, hullToCopy.indices, sizeof(indices[0]) * indicesCount); + memcpy(polygonData, hullToCopy.polygonData, sizeof(polygonData[0]) * polygonDataCount); +} + +CollisionHull* ExtPxCollisionBuilderImpl::buildCollisionGeometry(uint32_t verticesCount, const NvcVec3* vData) +{ + CollisionHull* output = new CollisionHullImpl(); + std::vector<physx::PxVec3> vertexData(verticesCount); + memcpy(vertexData.data(), vData, sizeof(physx::PxVec3) * verticesCount); + + PxConvexMeshDesc convexMeshDescr; + PxConvexMesh* resultConvexMesh; + PxBounds3 bounds; + // Scale chunk to unit cube size, to avoid numerical errors + bounds.setEmpty(); + for (uint32_t i = 0; i < vertexData.size(); ++i) + { + bounds.include(vertexData[i]); + } + PxVec3 bbCenter = bounds.getCenter(); + float scale = PxMax(PxAbs(bounds.getExtents(0)), PxMax(PxAbs(bounds.getExtents(1)), PxAbs(bounds.getExtents(2)))); + for (uint32_t i = 0; i < vertexData.size(); ++i) + { + vertexData[i] = vertexData[i] - bbCenter; + vertexData[i] *= (1.0f / scale); + } + bounds.setEmpty(); + for (uint32_t i = 0; i < vertexData.size(); ++i) + { + bounds.include(vertexData[i]); + } + convexMeshDescr.points.data = vertexData.data(); + convexMeshDescr.points.stride = sizeof(PxVec3); + convexMeshDescr.points.count = (uint32_t)vertexData.size(); + convexMeshDescr.flags = PxConvexFlag::eCOMPUTE_CONVEX; + resultConvexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback); + if (!resultConvexMesh) + { + vertexData.clear(); + vertexData.push_back(bounds.minimum); + vertexData.push_back(PxVec3(bounds.minimum.x, bounds.maximum.y, bounds.minimum.z)); + vertexData.push_back(PxVec3(bounds.maximum.x, bounds.maximum.y, bounds.minimum.z)); + vertexData.push_back(PxVec3(bounds.maximum.x, bounds.minimum.y, bounds.minimum.z)); + vertexData.push_back(PxVec3(bounds.minimum.x, bounds.minimum.y, bounds.maximum.z)); + vertexData.push_back(PxVec3(bounds.minimum.x, bounds.maximum.y, bounds.maximum.z)); + vertexData.push_back(PxVec3(bounds.maximum.x, bounds.maximum.y, bounds.maximum.z)); + vertexData.push_back(PxVec3(bounds.maximum.x, bounds.minimum.y, bounds.maximum.z)); + convexMeshDescr.points.data = vertexData.data(); + convexMeshDescr.points.count = (uint32_t)vertexData.size(); + resultConvexMesh = mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback); + } + output->polygonDataCount = resultConvexMesh->getNbPolygons(); + if (output->polygonDataCount) + output->polygonData = SAFE_ARRAY_NEW(HullPolygon, output->polygonDataCount); + output->pointsCount = resultConvexMesh->getNbVertices(); + output->points = SAFE_ARRAY_NEW(NvcVec3, output->pointsCount); + int32_t indicesCount = 0; + PxHullPolygon hPoly; + for (uint32_t i = 0; i < resultConvexMesh->getNbPolygons(); ++i) + { + HullPolygon& pd = output->polygonData[i]; + resultConvexMesh->getPolygonData(i, hPoly); + pd.indexBase = hPoly.mIndexBase; + pd.vertexCount = hPoly.mNbVerts; + pd.plane[0] = hPoly.mPlane[0]; + pd.plane[1] = hPoly.mPlane[1]; + pd.plane[2] = hPoly.mPlane[2]; + pd.plane[3] = hPoly.mPlane[3]; + + pd.plane[0] /= scale; + pd.plane[1] /= scale; + pd.plane[2] /= scale; + pd.plane[3] -= (pd.plane[0] * bbCenter.x + pd.plane[1] * bbCenter.y + pd.plane[2] * bbCenter.z); + float length = sqrt(pd.plane[0] * pd.plane[0] + pd.plane[1] * pd.plane[1] + pd.plane[2] * pd.plane[2]); + pd.plane[0] /= length; + pd.plane[1] /= length; + pd.plane[2] /= length; + pd.plane[3] /= length; + indicesCount = PxMax(indicesCount, pd.indexBase + pd.vertexCount); + } + 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] = fromPxShared(p); + } + for (int32_t i = 0; i < indicesCount; ++i) + { + output->indices[i] = resultConvexMesh->getIndexBuffer()[i]; + } + resultConvexMesh->release(); + return output; +} + +void ExtPxCollisionBuilderImpl::releaseCollisionHull(Nv::Blast::CollisionHull* ch) const +{ + if (ch) + { + SAFE_ARRAY_DELETE(ch->indices); + SAFE_ARRAY_DELETE(ch->points); + SAFE_ARRAY_DELETE(ch->polygonData); + delete ch; + } +} + +physx::PxConvexMesh* ExtPxCollisionBuilderImpl::buildConvexMesh(const CollisionHull& hull) +{ + /* PxCooking::createConvexMesh expects PxHullPolygon input, which matches HullPolygon */ + static_assert(sizeof(PxHullPolygon) == sizeof(HullPolygon), "HullPolygon size mismatch"); + static_assert(offsetof(PxHullPolygon, mPlane) == offsetof(HullPolygon, plane), "HullPolygon layout mismatch"); + static_assert(offsetof(PxHullPolygon, mNbVerts) == offsetof(HullPolygon, vertexCount), "HullPolygon layout mismatch"); + static_assert(offsetof(PxHullPolygon, mIndexBase) == offsetof(HullPolygon, indexBase), + "HullPolygon layout mismatch"); + + PxConvexMeshDesc convexMeshDescr; + convexMeshDescr.indices.data = hull.indices; + convexMeshDescr.indices.count = (uint32_t)hull.indicesCount; + convexMeshDescr.indices.stride = sizeof(uint32_t); + + convexMeshDescr.points.data = hull.points; + convexMeshDescr.points.count = (uint32_t)hull.pointsCount; + convexMeshDescr.points.stride = sizeof(PxVec3); + + convexMeshDescr.polygons.data = hull.polygonData; + convexMeshDescr.polygons.count = (uint32_t)hull.polygonDataCount; + convexMeshDescr.polygons.stride = sizeof(PxHullPolygon); + + return mCooking->createConvexMesh(convexMeshDescr, *mInsertionCallback); +} + +void ExtPxCollisionBuilderImpl::buildPhysicsChunks(uint32_t chunkCount, uint32_t* hullOffsets, + CollisionHull** hulls, ExtPxChunk* physicsChunks, + ExtPxSubchunk* physicsSubchunks) +{ + //Nv::Blast::AuthoringResult& result = *ar; + //uint32_t chunkCount = (uint32_t)result.chunkCount; + //uint32_t* hullOffsets = result.collisionHullOffset; + //CollisionHull** hulls = result.collisionHull; + for (uint32_t i = 0; i < chunkCount; ++i) + { + int32_t beg = hullOffsets[i]; + int32_t end = hullOffsets[i + 1]; + for (int32_t subhull = beg; subhull < end; ++subhull) + { + physicsSubchunks[subhull].transform = physx::PxTransform(physx::PxIdentity); + physicsSubchunks[subhull].geometry = physx::PxConvexMeshGeometry( + reinterpret_cast<physx::PxConvexMesh*>(buildConvexMesh(*hulls[subhull]))); + } + physicsChunks[i].isStatic = false; + physicsChunks[i].subchunkCount = static_cast<uint32_t>(end - beg); + physicsChunks[i].firstSubchunkIndex = beg; + } +} + +void ExtPxCollisionBuilderImpl::release() +{ + NVBLAST_DELETE(this, ExtPxCollisionBuilderImpl); +} + +} // namespace Blast +} // namespace Nv diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxCollisionBuilderImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxCollisionBuilderImpl.h new file mode 100644 index 0000000..9fb5c5e --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxCollisionBuilderImpl.h @@ -0,0 +1,74 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation 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-2018 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTPXCOLLISIONBUILDERIMPL_H +#define NVBLASTEXTPXCOLLISIONBUILDERIMPL_H + +#include "NvBlastExtPxCollisionBuilder.h" +#include "NvBlastExtAuthoringTypes.h" + +namespace physx +{ + class PxCooking; + class PxPhysicsInsertionCallback; +} +namespace Nv +{ + namespace Blast + { + + struct CollisionHullImpl : public CollisionHull + { + CollisionHullImpl() {}; + CollisionHullImpl(const CollisionHull& hullToCopy); + ~CollisionHullImpl(); + }; + + class ExtPxCollisionBuilderImpl : public ExtPxCollisionBuilder + { + public: + ExtPxCollisionBuilderImpl(physx::PxCooking* cooking, + physx::PxPhysicsInsertionCallback* insertionCallback) : mCooking(cooking), mInsertionCallback(insertionCallback) {} + virtual ~ExtPxCollisionBuilderImpl() {}; + void release() override; + CollisionHull* buildCollisionGeometry(uint32_t verticesCount, const NvcVec3* vertexData) override; + void releaseCollisionHull(CollisionHull* hull) const override; + + physx::PxConvexMesh* buildConvexMesh(const CollisionHull& hull) override; + void buildPhysicsChunks(uint32_t chunkCount, uint32_t* hullOffsets, CollisionHull** hulls, + ExtPxChunk* physicsChunks, ExtPxSubchunk* physicsSubchunks) override; + private: + physx::PxCooking* mCooking; + physx::PxPhysicsInsertionCallback* mInsertionCallback; + }; + + } // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTPXCOLLISIONBUILDERIMPL_H diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp index 018ff74..223d5f3 100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp @@ -29,6 +29,7 @@ #include "NvBlastExtPxManagerImpl.h"
#include "NvBlastExtPxAssetImpl.h"
#include "NvBlastExtPxActorImpl.h"
+#include "NvBlastExtPxCollisionBuilderImpl.h"
#include "NvBlastExtPxFamilyImpl.h"
#include "NvBlastAssert.h"
@@ -38,6 +39,7 @@ #include "NvBlastTkGroup.h"
#include "NvBlastTkJoint.h"
+#include "PxPhysics.h"
#include "PxRigidDynamic.h"
#include "PxJoint.h"
@@ -53,6 +55,11 @@ ExtPxManager* ExtPxManager::create(PxPhysics& physics, TkFramework& framework, E return NVBLAST_NEW(ExtPxManagerImpl)(physics, framework, createFn, useUserData);
}
+ExtPxCollisionBuilder* ExtPxManager::createCollisionBuilder(PxPhysics& physics, PxCooking& cooking)
+{
+ return NVBLAST_NEW(ExtPxCollisionBuilderImpl(&cooking, &physics.getPhysicsInsertionCallback()));
+}
+
void ExtPxManagerImpl::release()
{
NVBLAST_DELETE(this, ExtPxManagerImpl);
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp index b18df25..308c4ae 100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp @@ -37,6 +37,8 @@ #include "NvBlastTkActor.h"
#include "NvBlastTkFamily.h"
+#include "NvBlastPxSharedHelpers.h"
+
#include "PxScene.h"
#include "PxRigidDynamic.h"
@@ -130,7 +132,7 @@ ExtPxStressSolverImpl::ExtPxStressSolverImpl(ExtPxFamily& family, ExtStressSolve localPos = PxVec3(PxZero);
isChunkStatic = true;
}
- m_solver->setNodeInfo(node0, mass, volume, localPos, isChunkStatic);
+ m_solver->setNodeInfo(node0, mass, volume, fromPxShared(localPos), isChunkStatic);
}
#else
m_solver->setAllNodesInfoFromLL();
@@ -182,13 +184,13 @@ void ExtPxStressSolverImpl::update(bool doDamage) PxVec3 gravity = rigidDynamic.getScene()->getGravity();
PxVec3 localGravity = rigidDynamic.getGlobalPose().rotateInv(gravity);
- m_solver->addGravityForce(*actor->getTkActor().getActorLL(), localGravity);
+ m_solver->addGravityForce(*actor->getTkActor().getActorLL(), fromPxShared(localGravity));
}
else
{
PxVec3 localCenterMass = rigidDynamic.getCMassLocalPose().p;
PxVec3 localAngularVelocity = rigidDynamic.getGlobalPose().rotateInv(rigidDynamic.getAngularVelocity());
- m_solver->addAngularVelocity(*actor->getTkActor().getActorLL(), localCenterMass, localAngularVelocity);
+ m_solver->addAngularVelocity(*actor->getTkActor().getActorLL(), fromPxShared(localCenterMass), fromPxShared(localAngularVelocity));
}
}
diff --git a/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp b/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp index 3554240..04bec8a 100755 --- a/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/ExtPxAssetDTO.cpp @@ -148,7 +148,7 @@ Nv::Blast::ExtPxAsset* ExtPxAssetDTO::deserialize(Nv::Blast::Serialization::ExtP bool ExtPxAssetDTO::deserializeInto(Nv::Blast::Serialization::ExtPxAsset::Reader reader, Nv::Blast::ExtPxAsset * poco)
{
- reader = reader;
+ NV_UNUSED(reader);
poco = nullptr;
//NOTE: Because of the way this is structured, can't do this.
return false;
diff --git a/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp b/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp index f91a9a6..bff19c8 100755 --- a/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/ExtPxChunkDTO.cpp @@ -45,8 +45,8 @@ bool ExtPxChunkDTO::serialize(Nv::Blast::Serialization::ExtPxChunk::Builder buil Nv::Blast::ExtPxChunk* ExtPxChunkDTO::deserialize(Nv::Blast::Serialization::ExtPxChunk::Reader reader)
{
- reader = reader;
- //TODO: Allocate with ExtContext and return
+ NV_UNUSED(reader);
+ // TODO: Allocate with ExtContext and return
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp b/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp index a346bf0..a6d9a14 100755 --- a/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/ExtPxSubchunkDTO.cpp @@ -47,8 +47,8 @@ bool ExtPxSubchunkDTO::serialize(Nv::Blast::Serialization::ExtPxSubchunk::Builde Nv::Blast::ExtPxSubchunk* ExtPxSubchunkDTO::deserialize(Nv::Blast::Serialization::ExtPxSubchunk::Reader reader)
{
- reader = reader;
- //TODO: Allocate with ExtContext and return
+ NV_UNUSED(reader);
+ // TODO: Allocate with ExtContext and return
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp b/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp index c078b0d..0758c96 100755 --- a/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/NvBlastBondDTO.cpp @@ -57,7 +57,7 @@ bool NvBlastBondDTO::serialize(Nv::Blast::Serialization::NvBlastBond::Builder bu NvBlastBond* NvBlastBondDTO::deserialize(Nv::Blast::Serialization::NvBlastBond::Reader reader)
{
//FIXME
- reader = reader;
+ NV_UNUSED(reader);
//TODO: Allocate with ExtContext and return
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp b/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp index 7b57368..a76780c 100755 --- a/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/NvBlastChunkDTO.cpp @@ -55,7 +55,7 @@ bool NvBlastChunkDTO::serialize(Nv::Blast::Serialization::NvBlastChunk::Builder NvBlastChunk* NvBlastChunkDTO::deserialize(Nv::Blast::Serialization::NvBlastChunk::Reader reader)
{
//FIXME
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp b/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp index 55c2a71..d48963f 100755 --- a/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/NvBlastIDDTO.cpp @@ -50,7 +50,7 @@ bool NvBlastIDDTO::serialize(Nv::Blast::Serialization::UUID::Builder builder, co NvBlastID* NvBlastIDDTO::deserialize(Nv::Blast::Serialization::UUID::Reader reader)
{
//FIXME
- reader = reader;
+ NV_UNUSED(reader);
//TODO: Allocate with ExtContext and return
return nullptr;
diff --git a/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp b/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp index 67bb934..c1fb372 100755 --- a/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxConvexMeshGeometryDTO.cpp @@ -118,7 +118,7 @@ physx::PxConvexMeshGeometry* PxConvexMeshGeometryDTO::deserialize(Nv::Blast::Ser {
NVBLAST_ASSERT(sExtPxSerializerCooking != nullptr);
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp b/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp index d7c705a..56765ad 100755 --- a/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxMeshScaleDTO.cpp @@ -26,6 +26,7 @@ // Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
+#include "NvPreprocessor.h"
#include "PxMeshScaleDTO.h"
#include "PxVec3DTO.h"
#include "PxQuatDTO.h"
@@ -47,7 +48,7 @@ bool PxMeshScaleDTO::serialize(Nv::Blast::Serialization::PxMeshScale::Builder bu physx::PxMeshScale* PxMeshScaleDTO::deserialize(Nv::Blast::Serialization::PxMeshScale::Reader reader)
{
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp b/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp index 3847e82..dddfbac 100755 --- a/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxQuatDTO.cpp @@ -26,6 +26,7 @@ // Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
+#include "NvPreprocessor.h"
#include "PxQuatDTO.h"
namespace Nv
@@ -46,7 +47,7 @@ bool PxQuatDTO::serialize(Nv::Blast::Serialization::PxQuat::Builder builder, con physx::PxQuat* PxQuatDTO::deserialize(Nv::Blast::Serialization::PxQuat::Reader reader)
{
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp b/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp index 32f6684..f28af10 100755 --- a/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxTransformDTO.cpp @@ -26,6 +26,7 @@ // Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
+#include "NvPreprocessor.h"
#include "PxTransformDTO.h"
#include "PxQuatDTO.h"
#include "PxVec3DTO.h"
@@ -46,7 +47,7 @@ bool PxTransformDTO::serialize(Nv::Blast::Serialization::PxTransform::Builder bu physx::PxTransform* PxTransformDTO::deserialize(Nv::Blast::Serialization::PxTransform::Reader reader)
{
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp b/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp index 57a33ac..efa668e 100755 --- a/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp +++ b/sdk/extensions/serialization/source/DTO/PxVec3DTO.cpp @@ -48,7 +48,7 @@ bool PxVec3DTO::serialize(Nv::Blast::Serialization::PxVec3::Builder builder, con physx::PxVec3* PxVec3DTO::deserialize(Nv::Blast::Serialization::PxVec3::Reader reader)
{
//TODO: Allocate using ExtContext and return
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp b/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp index ab02085..acc0fe0 100755 --- a/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/TkAssetDTO.cpp @@ -84,7 +84,7 @@ Nv::Blast::TkAsset* TkAssetDTO::deserialize(Nv::Blast::Serialization::TkAsset::R bool TkAssetDTO::deserializeInto(Nv::Blast::Serialization::TkAsset::Reader reader, Nv::Blast::TkAsset * poco)
{
- reader = reader;
+ NV_UNUSED(reader);
poco = nullptr;
// NOTE: Because of the way TkAsset is currently structured, this won't work.
return false;
diff --git a/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp b/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp index 7e772c7..4212281 100755 --- a/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp +++ b/sdk/extensions/serialization/source/DTO/TkAssetJointDescDTO.cpp @@ -53,7 +53,7 @@ Nv::Blast::TkAssetJointDesc* TkAssetJointDescDTO::deserialize(Nv::Blast::Seriali {
//TODO: Allocate with ExtContent and return
- reader = reader;
+ NV_UNUSED(reader);
return nullptr;
}
diff --git a/sdk/extensions/stress/include/NvBlastExtStressSolver.h b/sdk/extensions/stress/include/NvBlastExtStressSolver.h index 50b4870..ef13259 100755 --- a/sdk/extensions/stress/include/NvBlastExtStressSolver.h +++ b/sdk/extensions/stress/include/NvBlastExtStressSolver.h @@ -30,8 +30,7 @@ #define NVBLASTEXTSTRESSSOLVER_H
#include "NvBlastTypes.h"
-#include "PxVec3.h"
-#include <vector>
+#include "NvCTypes.h"
namespace Nv
@@ -136,7 +135,7 @@ public: \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;
+ virtual void setNodeInfo(uint32_t graphNodeIndex, float mass, float volume, NvcVec3 localPosition, bool isStatic) = 0;
/**
Set all nodes info using low level NvBlastAsset data.
@@ -193,7 +192,7 @@ public: \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;
+ virtual bool addForce(const NvBlastActor& actor, NvcVec3 localPosition, NvcVec3 localForce, ExtForceMode::Enum mode = ExtForceMode::IMPULSE) = 0;
/**
Apply external impulse on particular node.
@@ -202,7 +201,7 @@ public: \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;
+ virtual void addForce(uint32_t graphNodeIndex, NvcVec3 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.
@@ -212,7 +211,7 @@ public: \return true iff force was applied on at least one node.
*/
- virtual bool addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity) = 0;
+ virtual bool addGravityForce(const NvBlastActor& actor, NvcVec3 localGravity) = 0;
/**
Apply centrifugal force produced by actor's angular movement.
@@ -223,7 +222,7 @@ public: \return true iff force was applied on at least one node.
*/
- virtual bool addAngularVelocity(const NvBlastActor& actor, physx::PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity) = 0;
+ virtual bool addAngularVelocity(const NvBlastActor& actor, NvcVec3 localCenterMass, NvcVec3 localAngularVelocity) = 0;
/**
Update stress solver.
@@ -337,12 +336,12 @@ public: */
struct DebugLine
{
- DebugLine(const physx::PxVec3& p0, const physx::PxVec3& p1, const uint32_t& c)
+ DebugLine(const NvcVec3& p0, const NvcVec3& p1, const uint32_t& c)
: pos0(p0), color0(c), pos1(p1), color1(c) {}
- physx::PxVec3 pos0;
+ NvcVec3 pos0;
uint32_t color0;
- physx::PxVec3 pos1;
+ NvcVec3 pos1;
uint32_t color1;
};
diff --git a/sdk/extensions/stress/source/NvBlastExtStressSolver.cpp b/sdk/extensions/stress/source/NvBlastExtStressSolver.cpp index c8918b6..f410003 100755 --- a/sdk/extensions/stress/source/NvBlastExtStressSolver.cpp +++ b/sdk/extensions/stress/source/NvBlastExtStressSolver.cpp @@ -37,6 +37,7 @@ #include <PsVecMath.h>
#include "PsFPU.h"
+#include "NvBlastPxSharedHelpers.h"
#include <algorithm>
@@ -950,7 +951,7 @@ public: 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 setNodeInfo(uint32_t graphNode, float mass, float volume, NvcVec3 localPos, bool isStatic) override;
virtual void setSettings(const ExtStressSolverSettings& settings) override
{
@@ -962,12 +963,14 @@ public: return m_settings;
}
- virtual bool addForce(const NvBlastActor& actor, physx::PxVec3 localPosition, physx::PxVec3 localForce, ExtForceMode::Enum mode) override;
+ virtual bool
+ addForce(const NvBlastActor& actor, NvcVec3 localPosition, NvcVec3 localForce,
+ ExtForceMode::Enum mode) override;
- virtual void addForce(uint32_t graphNode, physx::PxVec3 localForce, ExtForceMode::Enum mode) override;
+ virtual void addForce(uint32_t graphNode, NvcVec3 localForce, ExtForceMode::Enum mode) override;
- virtual bool addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity) override;
- virtual bool addAngularVelocity(const NvBlastActor& actor, PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity) override;
+ virtual bool addGravityForce(const NvBlastActor& actor, NvcVec3 localGravity) override;
+ virtual bool addAngularVelocity(const NvBlastActor& actor, NvcVec3 localCenterMass, NvcVec3 localAngularVelocity) override;
virtual void update() override;
@@ -1178,9 +1181,9 @@ void ExtStressSolverImpl::setAllNodesInfoFromLL(float density) }
}
-void ExtStressSolverImpl::setNodeInfo(uint32_t graphNode, float mass, float volume, PxVec3 localPos, bool isStatic)
+void ExtStressSolverImpl::setNodeInfo(uint32_t graphNode, float mass, float volume, NvcVec3 localPos, bool isStatic)
{
- m_graphProcessor->setNodeInfo(graphNode, mass, volume, localPos, isStatic);
+ m_graphProcessor->setNodeInfo(graphNode, mass, volume, toPxShared(localPos), isStatic);
}
bool ExtStressSolverImpl::notifyActorCreated(const NvBlastActor& actor)
@@ -1254,7 +1257,7 @@ void ExtStressSolverImpl::initialize() }
}
-bool ExtStressSolverImpl::addForce(const NvBlastActor& actor, physx::PxVec3 localPosition, physx::PxVec3 localForce, ExtForceMode::Enum mode)
+bool ExtStressSolverImpl::addForce(const NvBlastActor& actor, NvcVec3 localPosition, NvcVec3 localForce, ExtForceMode::Enum mode)
{
float bestDist = FLT_MAX;
uint32_t bestNode = invalidIndex<uint32_t>();
@@ -1268,7 +1271,7 @@ bool ExtStressSolverImpl::addForce(const NvBlastActor& actor, physx::PxVec3 loca for (uint32_t i = 0; i < nodeCount; ++i)
{
const uint32_t node = graphNodeIndices[i];
- const float sqrDist = (localPosition - m_graphProcessor->getNodeData(node).localPos).magnitudeSquared();
+ const float sqrDist = (toPxShared(localPosition) - m_graphProcessor->getNodeData(node).localPos).magnitudeSquared();
if (sqrDist < bestDist)
{
bestDist = sqrDist;
@@ -1278,19 +1281,19 @@ bool ExtStressSolverImpl::addForce(const NvBlastActor& actor, physx::PxVec3 loca if (!isInvalidIndex(bestNode))
{
- m_graphProcessor->addNodeForce(bestNode, localForce, mode);
+ m_graphProcessor->addNodeForce(bestNode, toPxShared(localForce), mode);
return true;
}
}
return false;
}
-void ExtStressSolverImpl::addForce(uint32_t graphNode, physx::PxVec3 localForce, ExtForceMode::Enum mode)
+void ExtStressSolverImpl::addForce(uint32_t graphNode, NvcVec3 localForce, ExtForceMode::Enum mode)
{
- m_graphProcessor->addNodeForce(graphNode, localForce, mode);
+ m_graphProcessor->addNodeForce(graphNode, toPxShared(localForce), mode);
}
-bool ExtStressSolverImpl::addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity)
+bool ExtStressSolverImpl::addGravityForce(const NvBlastActor& actor, NvcVec3 localGravity)
{
const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL);
if (graphNodeCount > 1)
@@ -1301,14 +1304,14 @@ bool ExtStressSolverImpl::addGravityForce(const NvBlastActor& actor, physx::PxVe for (uint32_t i = 0; i < nodeCount; ++i)
{
const uint32_t node = graphNodeIndices[i];
- m_graphProcessor->addNodeVelocity(node, localGravity);
+ m_graphProcessor->addNodeVelocity(node, toPxShared(localGravity));
}
return true;
}
return false;
}
-bool ExtStressSolverImpl::addAngularVelocity(const NvBlastActor& actor, PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity)
+bool ExtStressSolverImpl::addAngularVelocity(const NvBlastActor& actor, NvcVec3 localCenterMass, NvcVec3 localAngularVelocity)
{
const uint32_t graphNodeCount = NvBlastActorGetGraphNodeCount(&actor, logLL);
if (graphNodeCount > 1)
@@ -1322,7 +1325,9 @@ bool ExtStressSolverImpl::addAngularVelocity(const NvBlastActor& actor, PxVec3 l 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));
+ const PxVec3 centrifugalAcceleration =
+ toPxShared(localAngularVelocity)
+ .cross(toPxShared(localAngularVelocity).cross(localPos - toPxShared(localCenterMass)));
m_graphProcessor->addNodeVelocity(node, centrifugalAcceleration);
}
return true;
@@ -1534,9 +1539,9 @@ const ExtStressSolver::DebugBuffer ExtStressSolverImpl::fillDebugRender(const ui const auto& solverNode0 = m_graphProcessor->getSolverNodeData(solverInternalBondData.node0);
const auto& solverNode1 = m_graphProcessor->getSolverNodeData(solverInternalBondData.node1);
- PxVec3 p0 = solverNode0.localPos;
- PxVec3 p1 = solverNode1.localPos;
- PxVec3 center = (p0 + p1) * 0.5f;
+ NvcVec3 p0 = fromPxShared(solverNode0.localPos);
+ NvcVec3 p1 = fromPxShared(solverNode1.localPos);
+ NvcVec3 center = (p0 + p1) * 0.5f;
const float stress = std::min<float>(m_graphProcessor->getSolverBondStressHealth(i, m_settings), 1.0f);
PxVec4 color = bondHealthColor(1.0f - stress);
@@ -1547,15 +1552,15 @@ const ExtStressSolver::DebugBuffer ExtStressSolverImpl::fillDebugRender(const ui if (mode == DebugRenderMode::STRESS_GRAPH_NODES_IMPULSES)
{
- 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)));
+ m_debugLineBuffer.pushBack(DebugLine(p0, p0 + fromPxShared(solverInternalNode0.velocityLinear) * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR)));
+ m_debugLineBuffer.pushBack(DebugLine(p0, p0 + fromPxShared(solverInternalNode0.velocityAngular) * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR)));
+ m_debugLineBuffer.pushBack(DebugLine(p1, p1 + fromPxShared(solverInternalNode1.velocityLinear) * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR)));
+ m_debugLineBuffer.pushBack(DebugLine(p1, p1 + fromPxShared(solverInternalNode1.velocityAngular) * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR)));
}
else if (mode == DebugRenderMode::STRESS_GRAPH_BONDS_IMPULSES)
{
- 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)));
+ m_debugLineBuffer.pushBack(DebugLine(center, center + fromPxShared(solverInternalBondData.impulseLinear) * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_LINEAR_COLOR)));
+ m_debugLineBuffer.pushBack(DebugLine(center, center + fromPxShared(solverInternalBondData.impulseAngular) * impulseScale, PxVec4ToU32Color(BOND_IMPULSE_ANGULAR_COLOR)));
}
}
}
|