aboutsummaryrefslogtreecommitdiff
path: root/sdk/extensions/authoring/source
diff options
context:
space:
mode:
Diffstat (limited to 'sdk/extensions/authoring/source')
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtApexSharedParts.cpp1
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoring.cpp187
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.cpp2279
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringBondGeneratorImpl.h11
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp137
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.h8
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.cpp227
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringCollisionBuilderImpl.h54
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.cpp20
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringCutoutImpl.h14
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.cpp825
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringFractureToolImpl.h36
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringMeshCleanerImpl.cpp528
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.cpp413
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringMeshNoiser.h4
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp1608
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.h3
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp24
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.h4
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringPerlinNoise.h3
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtAuthoringTriangulator.cpp144
-rwxr-xr-xsdk/extensions/authoring/source/NvBlastExtTriangleProcessor.h101
22 files changed, 3369 insertions, 3262 deletions
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, &params) == 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, &params) == 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