diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp')
| -rw-r--r-- | sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp | 1510 |
1 files changed, 0 insertions, 1510 deletions
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp deleted file mode 100644 index 48830fe..0000000 --- a/sdk/extensions/authoring/source/NvBlastExtAuthoringFractureTool.cpp +++ /dev/null @@ -1,1510 +0,0 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NvBlastExtAuthoringFractureTool.h" -// This warning arises when using some stl containers with older versions of VC -// c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1826): warning C4702: unreachable code -#if NV_VC && NV_VC < 14 -#pragma warning(disable : 4702) -#endif -#include <queue> -#include <vector> -#include "NvBlastExtAuthoringVSA.h" -#include <float.h> -#include "NvBlastExtAuthoringTriangulator.h" -#include "NvBlastExtAuthoringBooleanTool.h" -#include "NvBlastExtAuthoringAccelerator.h" -#include "NvBlast.h" -#include "NvBlastExtAuthoringPerlinNoise.h" -#include <NvBlastAssert.h> -using namespace physx; - -#define DEFAULT_BB_ACCELARATOR_RES 10 - -namespace Nv -{ -namespace Blast -{ - -struct Halfspace_partitioning : public VSA::VS3D_Halfspace_Set -{ - std::vector<physx::PxPlane> 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]; - 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; - } - } - return biggest_d; - }; -}; - - -void findCellBasePlanes(const std::vector<PxVec3>& sites, std::vector<std::vector<int32_t> >& neighboors) -{ - Halfspace_partitioning prt; - std::vector<physx::PxPlane>& 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); - 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); - midpoints[collected] = midpoint; - ++collected; - } - for (uint32_t i = 0; i < planes.size(); ++i) - { - planes[i].n = -planes[i].n; - planes[i].d = -planes[i].d; - - if (VSA::vs3d_test(prt)) - { - neighboors[cellId].push_back(i + cellId + 1); - neighboors[i + cellId + 1].push_back(cellId); - }; - planes[i].n = -planes[i].n; - planes[i].d = -planes[i].d; - } - } -} - - -#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) -{ - Mesh* cell = getBigBox(sites[cellId], SITE_BOX_SIZE); - Mesh* cuttingMesh = getCuttingBox(PxVec3(0, 0, 0), PxVec3(1, 1, 1), CUTTING_BOX_SIZE, 0); - - 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; - if (nCell < cellId) - planeIndex = -planeIndex; - setCuttingBox(midpoint, -direction, cuttingMesh, CUTTING_BOX_SIZE, planeIndex); - eval.performFastCutting(cell, cuttingMesh, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* newCell = eval.createNewMesh(); - delete cell; - cell = newCell; - if (cell == nullptr) - break; - } - return cell; -} - - -bool blastBondComparator(const NvBlastBondDesc& a, const NvBlastBondDesc& b) -{ - if (a.chunkIndices[0] == b.chunkIndices[0]) - return a.chunkIndices[1] < b.chunkIndices[1]; - else - return a.chunkIndices[0] < b.chunkIndices[0]; -} - - -#define MAX_VORONOI_ATTEMPT_NUMBER 450 - -VoronoiSitesGenerator::VoronoiSitesGenerator(Mesh* mesh, RandomGeneratorBase* rnd) -{ - mMesh = mesh; - mRnd = rnd; - mAccelerator = new BBoxBasedAccelerator(mMesh, DEFAULT_BB_ACCELARATOR_RES); - mStencil = nullptr; -} - -void VoronoiSitesGenerator::setBaseMesh(Mesh* m) -{ - mGeneratedSites.clear(); - delete mAccelerator; - mMesh = m; - mAccelerator = new BBoxBasedAccelerator(mMesh, DEFAULT_BB_ACCELARATOR_RES); -} - -VoronoiSitesGenerator::~VoronoiSitesGenerator() -{ - delete mAccelerator; - mAccelerator = nullptr; -} - - -void VoronoiSitesGenerator::setStencil(Mesh* stencil) -{ - mStencil = stencil; -} - - -void VoronoiSitesGenerator::clearStencil() -{ - mStencil = nullptr; -} - - -void VoronoiSitesGenerator::uniformlyGenerateSitesInMesh(const uint32_t sitesCount) -{ - BooleanEvaluator voronoiMeshEval(nullptr); - PxVec3 mn = mMesh->getBoundingBox().minimum; - PxVec3 mx = mMesh->getBoundingBox().maximum; - PxVec3 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))) - { - generatedSites++; - mGeneratedSites.push_back(PxVec3(rn1, rn2, rn3) + mn); - attemptNumber = 0; - } - else - { - attemptNumber++; - if (attemptNumber > MAX_VORONOI_ATTEMPT_NUMBER) - break; - } - } -} - - -void VoronoiSitesGenerator::clusteredSitesGeneration(const uint32_t numberOfClusters, const uint32_t sitesPerCluster, float clusterRadius) -{ - BooleanEvaluator voronoiMeshEval(nullptr); - 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; - uint32_t generatedSites = 0; - std::vector<PxVec3> 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); - - if (voronoiMeshEval.isPointContainedInMesh(mMesh, p) && (mStencil == nullptr - || voronoiMeshEval.isPointContainedInMesh(mStencil, p))) - { - generatedSites++; - tempPoints.push_back(p); - attemptNumber = 0; - } - else - { - attemptNumber++; - if (attemptNumber > MAX_VORONOI_ATTEMPT_NUMBER) - break; - } - } - int32_t totalCount = 0; - for (; tempPoints.size() > 0; tempPoints.pop_back()) - { - 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))) - { - totalCount++; - generatedSites++; - mGeneratedSites.push_back(p); - attemptNumber = 0; - } - else - { - attemptNumber++; - if (attemptNumber > MAX_VORONOI_ATTEMPT_NUMBER) - break; - } - } - - } - -} - - -#define IN_SPHERE_ATTEMPT_NUMBER 20 - -void VoronoiSitesGenerator::addSite(const physx::PxVec3& site) -{ - mGeneratedSites.push_back(site); -} - - -void VoronoiSitesGenerator::generateInSphere(const uint32_t count, const float radius, const physx::PxVec3& center) -{ - BooleanEvaluator voronoiMeshEval(nullptr); - uint32_t attemptNumber = 0; - uint32_t generatedSites = 0; - std::vector<PxVec3> tempPoints; - - while (generatedSites < count && attemptNumber < MAX_VORONOI_ATTEMPT_NUMBER) - { - float rn1 = mRnd->getRandomValue() * radius; - float rn2 = mRnd->getRandomValue() * radius; - float rn3 = mRnd->getRandomValue() * radius; - if (voronoiMeshEval.isPointContainedInMesh(mMesh, PxVec3(rn1, rn2, rn3) + center) && (mStencil == nullptr - || voronoiMeshEval.isPointContainedInMesh(mStencil, PxVec3(rn1, rn2, rn3) + center))) - { - generatedSites++; - mGeneratedSites.push_back(PxVec3(rn1, rn2, rn3) + center); - attemptNumber = 0; - } - else - { - attemptNumber++; - if (attemptNumber > MAX_VORONOI_ATTEMPT_NUMBER) - break; - } - } -} - - -void VoronoiSitesGenerator::deleteInSphere(const float radius, const physx::PxVec3& 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) - { - std::swap(mGeneratedSites[i], mGeneratedSites.back()); - mGeneratedSites.pop_back(); - --i; - } - } -} - - -void VoronoiSitesGenerator::radialPattern(const physx::PxVec3& center, const physx::PxVec3& normal, float radius, int32_t angularSteps, int32_t radialSteps, float angleOffset, float variability) -{ -// mGeneratedSites.push_back(center); - physx::PxVec3 t1, t2; - if (abs(normal.z) < 0.9) - { - t1 = normal.cross(PxVec3(0, 0, 1)); - } - else - { - t1 = normal.cross(PxVec3(1, 0, 0)); - } - t2 = t1.cross(normal); - t1.normalize(); - t2.normalize(); - - float radStep = radius / radialSteps; - int32_t cCr = 0; - - float angleStep = PxPi * 2 / angularSteps; - for (float cRadius = radStep; cRadius < radius; cRadius += radStep) - { - float cAngle = angleOffset * cCr; - for (int32_t i = 0; i < angularSteps; ++i) - { - 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; - mGeneratedSites.push_back(nPos); - cAngle += angleStep; - } - ++cCr; - } -} - - -std::vector<PxVec3>& VoronoiSitesGenerator::getVoronoiSites() -{ - return mGeneratedSites; -} - - -int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<physx::PxVec3>& cellPointsIn, bool replaceChunk) -{ - if (chunkId == 0 && replaceChunk) - { - return 1; - } - - int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1 || cellPointsIn.size() < 2) - { - return 1; - } - if (!mChunkData[chunkIndex].isLeaf) - { - deleteAllChildsOfChunk(chunkId); - } - chunkIndex = getChunkIndex(chunkId); - - Mesh* mesh = mChunkData[chunkIndex].meshData; - - std::vector<PxVec3> cellPoints(cellPointsIn.size()); - for (uint32_t i = 0; i < cellPointsIn.size(); ++i) - { - cellPoints[i] = (cellPointsIn[i] - mOffset) * (1.0f / mScaleFactor); - } - - /** - Prebuild accelerator structure - */ - BooleanEvaluator eval(mLoggingCallback); - BooleanEvaluator voronoiMeshEval(mLoggingCallback); - - BBoxBasedAccelerator spAccel = BBoxBasedAccelerator(mesh, DEFAULT_BB_ACCELARATOR_RES); - - std::vector<std::vector<int32_t> > neighboors; - findCellBasePlanes(cellPoints, neighboors); - - /** - Fracture - */ - int32_t parentChunk = replaceChunk ? mChunkData[chunkIndex].parent : chunkId; - std::vector<uint32_t> newlyCreatedChunksIds; - for (uint32_t i = 0; i < cellPoints.size(); ++i) - { - Mesh* cell = getCellMesh(eval, mPlaneIndexerOffset, i, cellPoints, neighboors); - - if (cell == nullptr) - { - continue; - } - DummyAccelerator dmAccel(cell->getFacetCount()); - voronoiMeshEval.performBoolean(mesh, cell, &spAccel, &dmAccel, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* resultMesh = voronoiMeshEval.createNewMesh(); - if (resultMesh) - { - mChunkData.push_back(ChunkInfo()); - mChunkData.back().isLeaf = true; - mChunkData.back().meshData = resultMesh; - mChunkData.back().parent = parentChunk; - mChunkData.back().chunkId = mChunkIdCounter++; - newlyCreatedChunksIds.push_back(mChunkData.back().chunkId); - } - eval.reset(); - delete cell; - } - mChunkData[chunkIndex].isLeaf = false; - if (replaceChunk) - { - eraseChunk(chunkId); - } - mPlaneIndexerOffset += static_cast<int32_t>(cellPoints.size() * cellPoints.size()); - - - if (mRemoveIslands) - { - for (auto chunkToCheck : newlyCreatedChunksIds) - { - islandDetectionAndRemoving(chunkToCheck); - } - } - return 0; -} - -Mesh FractureTool::getChunkMesh(int32_t chunkId) -{ - Mesh temp = *mChunkData[getChunkIndex(chunkId)].meshData; - for (uint32_t i = 0; i < temp.getVerticesCount(); ++i) - { - temp.getVertices()[i].p = temp.getVertices()[i].p * mScaleFactor + mOffset; - } - temp.recalculateBoundingBox(); - - return temp; -} - - -int32_t FractureTool::voronoiFracturing(uint32_t chunkId, const std::vector<physx::PxVec3>& cellPointsIn, const physx::PxVec3& scale, bool replaceChunk) -{ - if (chunkId == 0 && replaceChunk) - { - return 1; - } - - int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1 || cellPointsIn.size() < 2) - { - return 1; - } - if (!mChunkData[chunkIndex].isLeaf) - { - deleteAllChildsOfChunk(chunkId); - } - chunkIndex = getChunkIndex(chunkId); - - Mesh* mesh = mChunkData[chunkIndex].meshData; - - std::vector<PxVec3> cellPoints(cellPointsIn.size()); - for (uint32_t i = 0; i < cellPointsIn.size(); ++i) - { - cellPoints[i] = (cellPointsIn[i] - mOffset) * (1.0f / mScaleFactor); - - cellPoints[i].x *= (1.0f / scale.x); - cellPoints[i].y *= (1.0f / scale.y); - cellPoints[i].z *= (1.0f / scale.z); - } - - /** - Prebuild accelerator structure - */ - BooleanEvaluator eval(mLoggingCallback); - BooleanEvaluator voronoiMeshEval(mLoggingCallback); - - BBoxBasedAccelerator spAccel = BBoxBasedAccelerator(mesh, DEFAULT_BB_ACCELARATOR_RES); - - std::vector<std::vector<int32_t> > neighboors; - findCellBasePlanes(cellPoints, neighboors); - - /** - Fracture - */ - int32_t parentChunk = replaceChunk ? mChunkData[chunkIndex].parent : chunkId; - std::vector<uint32_t> newlyCreatedChunksIds; - - for (uint32_t i = 0; i < cellPoints.size(); ++i) - { - Mesh* cell = getCellMesh(eval, mPlaneIndexerOffset, i, cellPoints, neighboors); - - if (cell == nullptr) - { - continue; - } - - for (uint32_t v = 0; v < cell->getVerticesCount(); ++v) - { - cell->getVertices()[v].p.x *= scale.x; - cell->getVertices()[v].p.y *= scale.y; - cell->getVertices()[v].p.z *= scale.z; - } - cell->recalculateBoundingBox(); - DummyAccelerator dmAccel(cell->getFacetCount()); - voronoiMeshEval.performBoolean(mesh, cell, &spAccel, &dmAccel, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* resultMesh = voronoiMeshEval.createNewMesh(); - if (resultMesh) - { - mChunkData.push_back(ChunkInfo()); - mChunkData.back().isLeaf = true; - mChunkData.back().meshData = resultMesh; - mChunkData.back().parent = parentChunk; - mChunkData.back().chunkId = mChunkIdCounter++; - newlyCreatedChunksIds.push_back(mChunkData.back().chunkId); - } - eval.reset(); - delete cell; - } - mChunkData[chunkIndex].isLeaf = false; - if (replaceChunk) - { - eraseChunk(chunkId); - } - mPlaneIndexerOffset += static_cast<int32_t>(cellPoints.size() * cellPoints.size()); - - if (mRemoveIslands) - { - for (auto chunkToCheck : newlyCreatedChunksIds) - { - islandDetectionAndRemoving(chunkToCheck); - } - } - - return 0; -} - - -int32_t FractureTool::slicing(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) -{ - if (conf.noiseAmplitude != 0) - { - return slicingNoisy(chunkId, conf, replaceChunk, rnd); - } - - if (replaceChunk && chunkId == 0) - { - return 1; - } - - int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1) - { - return 1; - } - if (!mChunkData[chunkIndex].isLeaf) - { - deleteAllChildsOfChunk(chunkId); - } - chunkIndex = getChunkIndex(chunkId); - - - Mesh* mesh = new Mesh(*mChunkData[chunkIndex].meshData); - - BooleanEvaluator bTool(mLoggingCallback); - - 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(); - - PxVec3 center = PxVec3(mesh->getBoundingBox().minimum.x, 0, 0); - - - float x_offset = (sourceBBox.maximum.x - sourceBBox.minimum.x) * (1.0f / (x_slices + 1)); - 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)); - - center.x += x_offset; - - PxVec3 dir(1, 0, 0); - - Mesh* slBox = getCuttingBox(center, dir, 20, 0); - - ChunkInfo ch; - ch.isLeaf = true; - ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId; - std::vector<ChunkInfo> xSlicedChunks; - std::vector<ChunkInfo> ySlicedChunks; - std::vector<uint32_t> newlyCreatedChunksIds; - /** - 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 lDir = dir + randVect * conf.angle_variations; - - setCuttingBox(center, lDir, slBox, 20, mPlaneIndexerOffset); - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); - ch.meshData = bTool.createNewMesh(); - - if (ch.meshData != 0) - { - xSlicedChunks.push_back(ch); - } - inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); - ++mPlaneIndexerOffset; - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - delete mesh; - mesh = result; - if (mesh == nullptr) - { - break; - } - center.x += x_offset + (rnd->getRandomValue()) * conf.offset_variations * x_offset; - } - if (mesh != 0) - { - ch.meshData = mesh; - xSlicedChunks.push_back(ch); - } - - - for (uint32_t chunk = 0; chunk < xSlicedChunks.size(); ++chunk) - { - center = PxVec3(0, sourceBBox.minimum.y, 0); - center.y += y_offset; - 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 lDir = dir + randVect * conf.angle_variations; - - - setCuttingBox(center, lDir, slBox, 20, mPlaneIndexerOffset); - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); - ch.meshData = bTool.createNewMesh(); - if (ch.meshData != 0) - { - ySlicedChunks.push_back(ch); - } - inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); - ++mPlaneIndexerOffset; - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - delete mesh; - mesh = result; - if (mesh == nullptr) - { - break; - } - center.y += y_offset + (rnd->getRandomValue()) * conf.offset_variations * y_offset; - } - if (mesh != 0) - { - ch.meshData = mesh; - ySlicedChunks.push_back(ch); - } - } - - - for (uint32_t chunk = 0; chunk < ySlicedChunks.size(); ++chunk) - { - center = PxVec3(0, 0, sourceBBox.minimum.z); - center.z += z_offset; - 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 lDir = dir + randVect * conf.angle_variations; - setCuttingBox(center, lDir, slBox, 20, mPlaneIndexerOffset); - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_DIFFERENCE()); - ch.meshData = bTool.createNewMesh(); - if (ch.meshData != 0) - { - ch.chunkId = mChunkIdCounter++; - newlyCreatedChunksIds.push_back(ch.chunkId); - mChunkData.push_back(ch); - } - inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); - ++mPlaneIndexerOffset; - bTool.performFastCutting(mesh, slBox, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - delete mesh; - mesh = result; - if (mesh == nullptr) - { - break; - } - center.z += z_offset + (rnd->getRandomValue()) * conf.offset_variations * z_offset; - } - if (mesh != 0) - { - ch.chunkId = mChunkIdCounter++; - ch.meshData = mesh; - mChunkData.push_back(ch); - newlyCreatedChunksIds.push_back(ch.chunkId); - } - } - - - delete slBox; - - mChunkData[chunkIndex].isLeaf = false; - if (replaceChunk) - { - eraseChunk(chunkId); - } - - if (mRemoveIslands) - { - for (auto chunkToCheck : newlyCreatedChunksIds) - { - islandDetectionAndRemoving(chunkToCheck); - } - } - - return 0; -} - -int32_t FractureTool::slicingNoisy(uint32_t chunkId, SlicingConfiguration conf, bool replaceChunk, RandomGeneratorBase* rnd) -{ - if (replaceChunk && chunkId == 0) - { - return 1; - } - - int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1) - { - return 1; - } - if (!mChunkData[chunkIndex].isLeaf) - { - deleteAllChildsOfChunk(chunkId); - } - chunkIndex = getChunkIndex(chunkId); - - - Mesh* mesh = new Mesh(*mChunkData[chunkIndex].meshData); - - BooleanEvaluator bTool(mLoggingCallback); - - 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(); - - PxVec3 center = PxVec3(mesh->getBoundingBox().minimum.x, 0, 0); - - - float x_offset = (sourceBBox.maximum.x - sourceBBox.minimum.x) * (1.0f / (x_slices + 1)); - 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)); - - center.x += x_offset; - - PxVec3 dir(1, 0, 0); - - Mesh* slBox = nullptr; - - ChunkInfo ch; - ch.isLeaf = true; - ch.parent = replaceChunk ? mChunkData[chunkIndex].parent : chunkId; - std::vector<ChunkInfo> xSlicedChunks; - std::vector<ChunkInfo> ySlicedChunks; - std::vector<uint32_t> newlyCreatedChunksIds; - float noisyPartSize = 1.8f; - int32_t acceleratorRes = 5; - /** - 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 lDir = dir + randVect * conf.angle_variations; - slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, conf.surfaceResolution, mPlaneIndexerOffset, conf.noiseAmplitude, conf.noiseFrequency, conf.noiseOctaveNumber, rnd->getRandomValue()); - // DummyAccelerator accel(mesh->getFacetCount()); - IntersectionTestingAccelerator accel(mesh, acceleratorRes); - DummyAccelerator dummy(slBox->getFacetCount()); - bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE()); - ch.meshData = bTool.createNewMesh(); - if (ch.meshData != 0) - { - xSlicedChunks.push_back(ch); - } - inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); - ++mPlaneIndexerOffset; - bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - delete slBox; - delete mesh; - mesh = result; - if (mesh == nullptr) - { - break; - } - center.x += x_offset + (rnd->getRandomValue()) * conf.offset_variations * x_offset; - } - if (mesh != 0) - { - ch.meshData = mesh; - xSlicedChunks.push_back(ch); - } - slBox = getCuttingBox(center, dir, 20, 0); - 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); - 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 lDir = dir + randVect * conf.angle_variations; - - slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, conf.surfaceResolution, mPlaneIndexerOffset, conf.noiseAmplitude, conf.noiseFrequency, conf.noiseOctaveNumber, rnd->getRandomValue()); - // DummyAccelerator accel(mesh->getFacetCount()); - IntersectionTestingAccelerator accel(mesh, acceleratorRes); - DummyAccelerator dummy(slBox->getFacetCount()); - bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE()); - ch.meshData = bTool.createNewMesh(); - if (ch.meshData != 0) - { - ySlicedChunks.push_back(ch); - } - inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); - ++mPlaneIndexerOffset; - bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - delete slBox; - delete mesh; - mesh = result; - if (mesh == nullptr) - { - break; - } - center.y += y_offset + (rnd->getRandomValue()) * conf.offset_variations * y_offset; - } - if (mesh != 0) - { - ch.meshData = mesh; - ySlicedChunks.push_back(ch); - } - } - - for (uint32_t chunk = 0; chunk < ySlicedChunks.size(); ++chunk) - { - center = PxVec3(0, 0, sourceBBox.minimum.z); - center.z += z_offset; - 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 lDir = dir + randVect * conf.angle_variations; - slBox = getNoisyCuttingBoxPair(center, lDir, 40, noisyPartSize, conf.surfaceResolution, mPlaneIndexerOffset, conf.noiseAmplitude, conf.noiseFrequency, conf.noiseOctaveNumber, rnd->getRandomValue()); - // DummyAccelerator accel(mesh->getFacetCount()); - IntersectionTestingAccelerator accel(mesh, acceleratorRes); - DummyAccelerator dummy(slBox->getFacetCount()); - bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_DIFFERENCE()); - ch.meshData = bTool.createNewMesh(); - if (ch.meshData != 0) - { - ch.chunkId = mChunkIdCounter++; - mChunkData.push_back(ch); - newlyCreatedChunksIds.push_back(ch.chunkId); - } - inverseNormalAndSetIndices(slBox, -mPlaneIndexerOffset); - ++mPlaneIndexerOffset; - bTool.performBoolean(mesh, slBox, &accel, &dummy, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - delete mesh; - delete slBox; - mesh = result; - if (mesh == nullptr) - { - break; - } - center.z += z_offset + (rnd->getRandomValue()) * conf.offset_variations * z_offset; - } - if (mesh != 0) - { - ch.chunkId = mChunkIdCounter++; - ch.meshData = mesh; - mChunkData.push_back(ch); - newlyCreatedChunksIds.push_back(ch.chunkId); - } - } - -// delete slBox; - - mChunkData[chunkIndex].isLeaf = false; - if (replaceChunk) - { - eraseChunk(chunkId); - } - - if (mRemoveIslands) - { - for (auto chunkToCheck : newlyCreatedChunksIds) - { - islandDetectionAndRemoving(chunkToCheck); - } - } - - return 0; -} - - - -int32_t FractureTool::getChunkIndex(int32_t chunkId) -{ - for (uint32_t i = 0; i < mChunkData.size(); ++i) - { - if (mChunkData[i].chunkId == chunkId) - { - return i; - } - } - return -1; -} - -int32_t FractureTool::getChunkDepth(int32_t chunkId) -{ - int32_t chunkIndex = getChunkIndex(chunkId); - if (chunkIndex == -1) - { - return -1; - } - - int32_t depth = 0; - - while (mChunkData[chunkIndex].parent != -1) - { - ++depth; - chunkIndex = getChunkIndex(mChunkData[chunkIndex].parent); - } - return depth; -} - -std::vector<int32_t> FractureTool::getChunksIdAtDepth(uint32_t depth) -{ - std::vector<int32_t> chunkIds; - - for (uint32_t i = 0; i < mChunkData.size(); ++i) - { - if (getChunkDepth(mChunkData[i].chunkId) == (int32_t)depth) - { - chunkIds.push_back(mChunkData[i].chunkId); - } - } - return chunkIds; -} - - -void FractureTool::getTransformation(PxVec3& offset, float& scale) -{ - offset = mOffset; - scale = mScaleFactor; -} - -void FractureTool::setSourceMesh(Mesh* mesh) -{ - if (mesh == nullptr) - { - return; - } - reset(); - - mChunkData.resize(1); - mChunkData[0].meshData = new Mesh(*mesh); - mChunkData[0].parent = -1; - mChunkData[0].isLeaf = true; - mChunkData[0].chunkId = mChunkIdCounter++; - mesh = mChunkData[0].meshData; - - /** - Move to origin and scale to unit cube - */ - - mOffset = (mesh->getBoundingBox().maximum + mesh->getBoundingBox().minimum) * 0.5f; - PxVec3 bbSizes = (mesh->getBoundingBox().maximum - mesh->getBoundingBox().minimum); - - mScaleFactor = std::max(bbSizes.x, std::max(bbSizes.y, bbSizes.z)); - - Vertex* verticesBuffer = mesh->getVertices(); - for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i) - { - verticesBuffer[i].p = (verticesBuffer[i].p - mOffset) * (1.0f / mScaleFactor); - } - - mesh->getBoundingBox().minimum = (mesh->getBoundingBox().minimum - mOffset) * (1.0f / mScaleFactor); - mesh->getBoundingBox().maximum = (mesh->getBoundingBox().maximum - mOffset) * (1.0f / mScaleFactor); - - - for (uint32_t i = 0; i < mesh->getFacetCount(); ++i) - { - mesh->getFacet(i)->userData = 0; // Mark facet as initial boundary facet - } -} - - -void FractureTool::reset() -{ - mChunkPostprocessors.clear(); - for (uint32_t i = 0; i < mChunkData.size(); ++i) - { - delete mChunkData[i].meshData; - } - mChunkData.clear(); - mPlaneIndexerOffset = 1; - mChunkIdCounter = 0; -} - - - - -bool FractureTool::isAncestorForChunk(int32_t ancestorId, int32_t chunkId) -{ - if (ancestorId == chunkId) - { - return false; - } - while (chunkId != -1) - { - if (ancestorId == chunkId) - { - return true; - } - chunkId = getChunkIndex(chunkId); - if (chunkId == -1) - { - return false; - } - chunkId = mChunkData[chunkId].parent; - } - return false; -} - -void FractureTool::eraseChunk(int32_t chunkId) -{ - deleteAllChildsOfChunk(chunkId); - int32_t index = getChunkIndex(chunkId); - if (index != -1) - { - delete mChunkData[index].meshData; - std::swap(mChunkData.back(), mChunkData[index]); - mChunkData.pop_back(); - } -} - - -void FractureTool::deleteAllChildsOfChunk(int32_t chunkId) -{ - std::vector<int32_t> chunkToDelete; - for (uint32_t i = 0; i < mChunkData.size(); ++i) - { - if (isAncestorForChunk(chunkId, mChunkData[i].chunkId)) - { - chunkToDelete.push_back(i); - } - } - for (int32_t i = (int32_t)chunkToDelete.size() - 1; i >= 0; --i) - { - int32_t m = chunkToDelete[i]; - delete mChunkData[m].meshData; - std::swap(mChunkData.back(), mChunkData[m]); - mChunkData.pop_back(); - } -} - -void FractureTool::finalizeFracturing() -{ - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - delete mChunkPostprocessors[i]; - } - mChunkPostprocessors.resize(mChunkData.size()); - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - mChunkPostprocessors[i] = new ChunkPostProcessor(); - } - - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - mChunkPostprocessors[i]->triangulate(mChunkData[i].meshData); - } - std::vector<int32_t> badOnes; - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - if (mChunkPostprocessors[i]->getBaseMesh().empty()) - { - badOnes.push_back(i); - } - } - for (int32_t i = (int32_t)badOnes.size() - 1; i >= 0; --i) - { - int32_t chunkId = mChunkData[badOnes[i]].chunkId; - for (uint32_t j = 0; j < mChunkData.size(); ++j) - { - if (mChunkData[j].parent == chunkId) - mChunkData[j].parent = mChunkData[badOnes[i]].parent; - } - std::swap(mChunkPostprocessors[badOnes[i]], mChunkPostprocessors.back()); - mChunkPostprocessors.pop_back(); - std::swap(mChunkData[badOnes[i]], mChunkData.back()); - mChunkData.pop_back(); - } - -} - -const std::vector<ChunkInfo>& FractureTool::getChunkList() -{ - return mChunkData; -} - -void FractureTool::getBaseMesh(int32_t chunkIndex, std::vector<Triangle>& output) -{ - NVBLAST_ASSERT(mChunkPostprocessors.size() > 0); - if (mChunkPostprocessors.size() == 0) - { - return; // finalizeFracturing() should be called before getting mesh! - } - output = mChunkPostprocessors[chunkIndex]->getBaseMesh(); - - /* Scale mesh back */ - - for (uint32_t i = 0; i < output.size(); ++i) - { - output[i].a.p = output[i].a.p * mScaleFactor + mOffset; - output[i].b.p = output[i].b.p * mScaleFactor + mOffset; - output[i].c.p = output[i].c.p * mScaleFactor + mOffset; - } -} - -void FractureTool::getNoisedMesh(int32_t chunkIndex, std::vector<Triangle>& output) -{ - NVBLAST_ASSERT(mChunkPostprocessors.size() > 0); - if (mChunkPostprocessors.size() == 0) - { - return; // finalizeFracturing() should be called before getting mesh! - } - - if (mChunkData[chunkIndex].chunkId == 0) - { - output = mChunkPostprocessors[chunkIndex]->getBaseMesh(); - } - else - { - output = mChunkPostprocessors[chunkIndex]->getNoisyMesh(); - } - - for (uint32_t i = 0; i < output.size(); ++i) - { - output[i].a.p = output[i].a.p * mScaleFactor + mOffset; - output[i].b.p = output[i].b.p * mScaleFactor + mOffset; - output[i].c.p = output[i].c.p * mScaleFactor + mOffset; - } -} - -void FractureTool::tesselate(float averateEdgeLength) -{ - NVBLAST_ASSERT(mChunkPostprocessors.size() > 0); - if (mChunkPostprocessors.size() == 0) - { - return; // finalizeFracturing() should be called before tesselation! - } - - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - if (mChunkData[i].chunkId == 0) // skip source mesh - { - continue; - } - mChunkPostprocessors[i]->tesselateInternalSurface(averateEdgeLength / mScaleFactor); - } -} - -void FractureTool::applyNoise(float amplitude, float frequency, int32_t octaves, float falloff, int32_t relaxIterations, float relaxFactor, int32_t seed) -{ - octaves = octaves <= 0 ? 1 : octaves; - if (mChunkPostprocessors.empty()) - { - return; - } - SimplexNoise noise(amplitude / mScaleFactor, frequency * mScaleFactor, octaves, seed); - for (uint32_t i = 0; i < mChunkPostprocessors.size(); ++i) - { - if (mChunkData[i].chunkId == 0) // skip source mesh - { - continue; - } - mChunkPostprocessors[i]->applyNoise(noise, falloff, relaxIterations, relaxFactor); - } -} - -float getVolume(std::vector<Triangle>& triangles) -{ - float volume = 0.0f; - - 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); - } - return (1.0f / 6.0f) * PxAbs(volume); -} - -float FractureTool::getMeshOverlap(Mesh& meshA, Mesh& meshB) -{ - BooleanEvaluator bTool; - bTool.performBoolean(&meshA, &meshB, BooleanConfigurations::BOOLEAN_INTERSECION()); - Mesh* result = bTool.createNewMesh(); - if (result == nullptr) - { - return 0.0f; - } - - ChunkPostProcessor postProcessor; - postProcessor.triangulate(&meshA); - - float baseVolume = getVolume(postProcessor.getBaseMesh()); - if (baseVolume == 0) - { - return 0.0f; - } - postProcessor.triangulate(result); - float intrsVolume = getVolume(postProcessor.getBaseMesh()); - - delete result; - - 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) -{ - for (uint32_t i = 0; i < trb.size(); ++i) - { - auto it = vertexMapping.find(trb[i].a); - if (it == vertexMapping.end()) - { - indexBuffer.push_back(static_cast<uint32_t>(vertexBuffer.size())); - vertexMapping[trb[i].a] = static_cast<uint32_t>(vertexBuffer.size()); - vertexBuffer.push_back(trb[i].a); - } - else - { - indexBuffer.push_back(it->second); - } - it = vertexMapping.find(trb[i].b); - if (it == vertexMapping.end()) - { - indexBuffer.push_back(static_cast<uint32_t>(vertexBuffer.size())); - vertexMapping[trb[i].b] = static_cast<uint32_t>(vertexBuffer.size()); - vertexBuffer.push_back(trb[i].b); - } - else - { - indexBuffer.push_back(it->second); - } - it = vertexMapping.find(trb[i].c); - if (it == vertexMapping.end()) - { - indexBuffer.push_back(static_cast<uint32_t>(vertexBuffer.size())); - vertexMapping[trb[i].c] = static_cast<uint32_t>(vertexBuffer.size()); - vertexBuffer.push_back(trb[i].c); - } - else - { - indexBuffer.push_back(it->second); - } - } - -} - -void FractureTool::setRemoveIslands(bool isRemoveIslands) -{ - mRemoveIslands = isRemoveIslands; -} - -int32_t FractureTool::islandDetectionAndRemoving(int32_t chunkId) -{ - if (chunkId == 0) - { - return 0; - } - int32_t chunkIndex = getChunkIndex(chunkId); - ChunkPostProcessor prc; - prc.triangulate(mChunkData[chunkIndex].meshData); - - Mesh* chunk = mChunkData[chunkIndex].meshData; - - std::vector<uint32_t>& mapping = prc.getBaseMapping(); - std::vector<TriangleIndexed>& trs = prc.getBaseMeshIndexed(); - - std::vector<std::vector<uint32_t> > graph(prc.getWeldedVerticesCount()); - std::vector<int32_t>& pm = prc.getPositionedMapping(); - if (pm.size() == 0) - { - return 0; - } - - /** - Chunk graph - */ - for (uint32_t i = 0; i < trs.size(); ++i) - { - graph[pm[trs[i].ea]].push_back(pm[trs[i].eb]); - graph[pm[trs[i].ea]].push_back(pm[trs[i].ec]); - - graph[pm[trs[i].ec]].push_back(pm[trs[i].eb]); - graph[pm[trs[i].ec]].push_back(pm[trs[i].ea]); - - graph[pm[trs[i].eb]].push_back(pm[trs[i].ea]); - graph[pm[trs[i].eb]].push_back(pm[trs[i].ec]); - } - for (uint32_t i = 0; i < chunk->getEdgesCount(); ++i) - { - int v1 = chunk->getEdges()[i].s; - int v2 = chunk->getEdges()[i].e; - - v1 = pm[mapping[v1]]; - v2 = pm[mapping[v2]]; - - graph[v1].push_back(v2); - graph[v2].push_back(v1); - - } - - - /** - 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; - que.push(to); - comps[to] = cComp; - - while (!que.empty()) - { - int32_t c = que.front(); - que.pop(); - - for (uint32_t j = 0; j < graph[c].size(); ++j) - { - if (comps[graph[c][j]] == -1) - { - que.push(graph[c][j]); - comps[graph[c][j]] = cComp; - } - } - } - cComp++; - } - for (uint32_t i = 0; i < prc.getWeldedVerticesCount(); ++i) - { - int32_t to = pm[i]; - 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]; - 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<uint32_t> compVertexMapping(chunk->getVerticesCount(), 0); - Vertex* vrts = chunk->getVertices(); - for (uint32_t v = 0; v < chunk->getVerticesCount(); ++v) - { - int32_t vComp = comps[mapping[v]]; - compVertexMapping[v] = static_cast<uint32_t>(compVertices[vComp].size()); - compVertices[vComp].push_back(vrts[v]); - } - - Facet* fcb = chunk->getFacetsBuffer(); - Edge* edb = chunk->getEdges(); - - for (uint32_t fc = 0; fc < chunk->getFacetCount(); ++fc) - { - std::vector<uint32_t> edgesPerComp(cComp, 0); - for (uint32_t ep = fcb[fc].firstEdgeNumber; ep < fcb[fc].firstEdgeNumber + fcb[fc].edgesCount; ++ep) - { - int32_t vComp = comps[mapping[edb[ep].s]]; - edgesPerComp[vComp]++; - compEdges[vComp].push_back(Edge(compVertexMapping[edb[ep].s], compVertexMapping[edb[ep].e])); - } - for (int32_t c = 0; c < cComp; ++c) - { - if (edgesPerComp[c] == 0) - { - continue; - } - compFacets[c].push_back(*chunk->getFacet(fc)); - compFacets[c].back().edgesCount = edgesPerComp[c]; - compFacets[c].back().firstEdgeNumber = static_cast<int32_t>(compEdges[c].size()) - edgesPerComp[c]; - } - } - - delete mChunkData[chunkIndex].meshData; - mChunkData[chunkIndex].meshData = new Mesh(compVertices[0].data(), compEdges[0].data(), compFacets[0].data(), static_cast<uint32_t>(compVertices[0].size()), - static_cast<uint32_t>(compEdges[0].size()), static_cast<uint32_t>(compFacets[0].size()));; - for (int32_t i = 1; i < cComp; ++i) - { - mChunkData.push_back(ChunkInfo(mChunkData[chunkIndex])); - mChunkData.back().chunkId = mChunkIdCounter++; - mChunkData.back().meshData = new Mesh(compVertices[i].data(), compEdges[i].data(), compFacets[i].data(), static_cast<uint32_t>(compVertices[i].size()), - static_cast<uint32_t>(compEdges[i].size()), static_cast<uint32_t>(compFacets[i].size())); - } - - return cComp; - } - return 0; -} - -void FractureTool::getBufferedBaseMeshes(std::vector<Vertex>& vertexBuffer, std::vector<std::vector<uint32_t> >& indexBuffer) -{ - std::map<Vertex, uint32_t, VrtComp> vertexMapping; - vertexBuffer.clear(); - indexBuffer.clear(); - indexBuffer.resize(mChunkPostprocessors.size()); - - for (uint32_t ch = 0; ch < mChunkPostprocessors.size(); ++ch) - { - std::vector<Triangle>& trb = mChunkPostprocessors[ch]->getBaseMesh(); - weldVertices(vertexMapping, vertexBuffer, indexBuffer[ch], trb); - } - for (uint32_t i = 0; i < vertexBuffer.size(); ++i) - { - vertexBuffer[i].p = vertexBuffer[i].p * mScaleFactor + mOffset; - } -} - -int32_t FractureTool::getChunkId(int32_t chunkIndex) -{ - if (chunkIndex < 0 || static_cast<uint32_t>(chunkIndex) >= mChunkData.size()) - { - return -1; - } - return mChunkData[chunkIndex].chunkId; -} - -void FractureTool::getBufferedNoiseMeshes(std::vector<Vertex>& vertexBuffer, std::vector<std::vector<uint32_t> >& indexBuffer) -{ - std::map<Vertex, uint32_t, VrtComp> vertexMapping; - vertexBuffer.clear(); - indexBuffer.clear(); - indexBuffer.resize(mChunkPostprocessors.size()); - - for (uint32_t ch = 0; ch < mChunkPostprocessors.size(); ++ch) - { - if (ch == 0) - { - std::vector<Triangle>& trb = mChunkPostprocessors[ch]->getBaseMesh(); - weldVertices(vertexMapping, vertexBuffer, indexBuffer[ch], trb); - } - else - { - std::vector<Triangle>& trb = mChunkPostprocessors[ch]->getNoisyMesh(); - weldVertices(vertexMapping, vertexBuffer, indexBuffer[ch], trb); - } - } - for (uint32_t i = 0; i < vertexBuffer.size(); ++i) - { - vertexBuffer[i].p = vertexBuffer[i].p * mScaleFactor + mOffset; - } -} - - -} // namespace Blast -} // namespace Nv - |