aboutsummaryrefslogtreecommitdiff
path: root/sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2019-05-03 00:25:46 -0700
committerBryan Galdrikian <[email protected]>2019-05-03 00:25:46 -0700
commit74b64a27f8e07b1b0b47b809b1a060518fa11a97 (patch)
tree34cca01711be56892c149706f02ba7358d87ec54 /sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp
parentFixing chunk reorder bug in BlastTool, when importing a prefractured mesh (diff)
downloadblast-1.1.5_pre1.tar.xz
blast-1.1.5_pre1.zip
Blast SDK 1.1.5 prerelease #1v1.1.5_pre1
Diffstat (limited to 'sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp')
-rw-r--r--sdk/extensions/authoring/source/NvBlastExtAuthoringMeshUtils.cpp1608
1 files changed, 820 insertions, 788 deletions
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