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/authoring | |
| 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/authoring')
27 files changed, 3739 insertions, 3736 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
|