diff options
| author | bgaldrikian <[email protected]> | 2018-10-03 17:51:20 -0700 |
|---|---|---|
| committer | bgaldrikian <[email protected]> | 2018-10-03 17:51:20 -0700 |
| commit | 6f51c0ad55f3ed33597b8b12391d426fe28a0923 (patch) | |
| tree | b132a8cb2485820ff9556dafc8e874bc9d41f255 /sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp | |
| parent | Fixes to UnitySample to make it build & run. ( In Unity 2018.2 ) (diff) | |
| download | blast-6f51c0ad55f3ed33597b8b12391d426fe28a0923.tar.xz blast-6f51c0ad55f3ed33597b8b12391d426fe28a0923.zip | |
Blast 1.1.4. See docs/release_notes.txt.v1.1.4_rc1
Diffstat (limited to 'sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp')
| -rw-r--r-- | sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp new file mode 100644 index 0000000..f12c931 --- /dev/null +++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringPatternGeneratorImpl.cpp @@ -0,0 +1,311 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. + +#include "NvBlastGlobals.h" +#include "NvBlastAssert.h" +#include "NvBlastExtAuthoringTypes.h" +#include "NvBlastExtAuthoringPatternGeneratorImpl.h" +#include "NvBlastExtAuthoringMeshUtils.h" +#include "NvBlastExtAuthoringMeshImpl.h" +#include "NvBlastExtAuthoringFractureToolImpl.h" +#include "NvBlastExtAuthoringBooleanTool.h" +#include "NvBlastExtAuthoringTriangulator.h" +#include "NvBlastExtAuthoringPerlinNoise.h" + +#include <vector> +#include "PxVec3.h" + +using namespace Nv::Blast; +using namespace physx; + +struct DamagePatternImpl : public DamagePattern +{ + virtual void release() override; +}; + +DamagePattern* PatternGeneratorImpl::generateUniformPattern(const UniformPatternDesc* desc) +{ + std::vector<PxVec3> points; + float radiusDelta = desc->radiusMax - desc->radiusMin; + for (uint32_t i = 0; i < desc->cellsCount; ++i) + { + float rd = desc->RNG() * radiusDelta + desc->radiusMin; + + if (desc->radiusDistr != 1.0f) + { + rd = std::pow(rd / desc->radiusMax, desc->radiusDistr) * desc->radiusMax; + } + + float phi = desc->RNG() * 6.28f; + float theta = (desc->RNG()) * 6.28f; + + float x = rd * cos(phi) * sin(theta); + float y = rd * sin(phi) * sin(theta); + float z = rd * cos(theta); + + points.push_back(PxVec3(x, y, z)); + } + + + auto pattern = generateVoronoiPattern((uint32_t)points.size(), points.data(), desc->interiorMaterialId); + pattern->activationRadius = desc->radiusMax * desc->debrisRadiusMult; + return pattern; +} + +DamagePattern* PatternGeneratorImpl::generateVoronoiPattern(uint32_t cellCount, const physx::PxVec3* inPoints, int32_t interiorMaterialId) +{ + return generateVoronoiPatternInternal(cellCount, inPoints, interiorMaterialId); +} + +DamagePattern* PatternGeneratorImpl::generateVoronoiPatternInternal(uint32_t cellCount, const physx::PxVec3* inPoints, int32_t interiorMaterialId, float angle) +{ + DamagePatternImpl* pattern = NVBLAST_NEW(DamagePatternImpl); + + std::vector<PxVec3> points(cellCount); + physx::PxVec3 orig(0.f); + for (uint32_t i = 0; i < cellCount; ++i) + { + points[i] = inPoints[i]; + orig += points[i]; + } + orig /= cellCount; + + std::vector<std::vector<int32_t> > neighboors; + findCellBasePlanes(points, neighboors); + + Mesh** patterns = (Mesh**)NVBLAST_ALLOC(sizeof(Mesh*) * cellCount); + + //PreparedMesh** prepMeshes = (PreparedMesh**)NVBLAST_ALLOC(sizeof(PreparedMesh*) * cellCount); + + BooleanEvaluator evl; + for (uint32_t i = 0; i < cellCount; ++i) + { + patterns[i] = getCellMesh(evl, 0, i, points, neighboors, interiorMaterialId, orig); + if (patterns[i] == nullptr) + { + continue; + } + if (angle != 0) + { + auto* vr = patterns[i]->getVerticesWritable(); + for (uint32_t j = 0; j < patterns[i]->getVerticesCount(); ++j) + { + float& z = vr[j].p.z; + z -= 3.8f; + if (z < -2) // we presume that this vertex has infinite -z position (everything scaled to unit cube). + { + if (angle > 0) + { + float d = sqrt(vr[j].p.x * vr[j].p.x + vr[j].p.y * vr[j].p.y); + + vr[j].p.x *= (d + 4 * tan(angle * physx::PxPi / 180.f)) / d; + vr[j].p.y *= (d + 4 * tan(angle * physx::PxPi / 180.f)) / d; + } + } + } + patterns[i]->recalculateBoundingBox(); + } + } + for (int32_t i = cellCount - 1; i >= 0; i--) + { + if (patterns[i] == nullptr) + { + cellCount--; + std::swap(patterns[i], patterns[cellCount]); + //std::swap(prepMeshes[i], prepMeshes[cellCount]); + } + } + pattern->cellsCount = cellCount; + pattern->cellsMeshes = patterns; + //pattern->preparedMeshes = prepMeshes; + +#ifdef USE_MERGED_MESH + pattern->outputEdges = NVBLAST_ALLOC(sizeof(BooleanResultEdge) * (cellCount * BLASTRT_MAX_EDGES_PER_CHUNK)); + pattern->outputEdgesCount = (uint32_t*)NVBLAST_ALLOC(sizeof(uint32_t) * cellCount); +#endif + + return pattern; +} + +DamagePattern* PatternGeneratorImpl::generateBeamPattern(const BeamPatternDesc* desc) +{ + std::vector<PxVec3> points; + + float radiusDelta = desc->radiusMax - desc->radiusMin; + + for (uint32_t i = 0; i < desc->cellsCount; ++i) + { + float rd = desc->RNG() * radiusDelta + desc->radiusMin; + float phi = desc->RNG() * 6.28f; + + float x = rd * cos(phi); + float y = rd * sin(phi); + float z = desc->RNG() - 1; + points.push_back(PxVec3(x, y, z)); + } + auto pattern = generateVoronoiPattern((uint32_t)points.size(), points.data(), desc->interiorMaterialId); + pattern->activationType = DamagePattern::Line; + return pattern; +} + +DamagePattern* PatternGeneratorImpl::generateRegularRadialPattern(const RegularRadialPatternDesc* desc) +{ + SimplexNoise noise(desc->radialNoiseAmplitude, desc->radialNoiseFrequency, 3, desc->RNG() * 999999); + std::vector<PxVec3> points; + + float radialDelta = (desc->radiusMax - desc->radiusMin) / desc->radialSteps; + float angularDelta = 2 * acos(-1.0f) / desc->angularSteps; + + + for (uint32_t i = 0; i < desc->radialSteps; ++i) + { + for (uint32_t j = 0; j < desc->angularSteps; ++j) + { + float angle = j * angularDelta + desc->RNG() * desc->angularNoiseAmplitude; + float rd = ((i + noise.sample(PxVec3(angle, 0, 0))) * radialDelta + desc->radiusMin); + float x = rd * cos(angle); + float y = rd * sin(angle); + float z = 0; + points.push_back(PxVec3(x, y, z)); + } + } + float mrd = 0.0; + for (uint32_t i = 0; i < points.size(); ++i) + { + mrd = std::max(mrd, points[i].magnitude()); + } + for (uint32_t i = 0; i < points.size(); ++i) + { + points[i] *= desc->radiusMax / mrd; + } + + float ap = std::max(0.0f, desc->aperture); + + auto pattern = generateVoronoiPatternInternal((uint32_t)points.size(), points.data(), desc->interiorMaterialId, ap); + + pattern->activationRadius = desc->radiusMax * desc->debrisRadiusMult; + pattern->activationType = (ap == 0) ? DamagePattern::Line : DamagePattern::Cone; + pattern->angle = ap; + return pattern; +} + + + +void PatternGeneratorImpl::release() +{ + NVBLAST_DELETE(this, PatternGeneratorImpl); +} + +void DamagePatternImpl::release() +{ + if (cellsMeshes) + { + for (uint32_t i = 0; i < cellsCount; i++) + { + cellsMeshes[i]->release(); + } + NVBLAST_FREE(cellsMeshes); + } +#ifdef USE_MERGED_MESH + if (outputEdges) + { + NVBLAST_FREE(outputEdges); + } + if (outputEdgesCount) + { + NVBLAST_FREE(outputEdgesCount); + } + if (mergedMesh) + { + mergedMesh->release(); + } + if (preparedMergedMesh) + { + preparedMergedMesh->release(); + } + if (validFacetsForChunk) + { + for (uint32_t i = 0; i < cellsCount; i++) + { + if (validFacetsForChunk[i]) + { + NVBLAST_FREE(validFacetsForChunk[i]); + } + } + NVBLAST_FREE(validFacetsForChunk); + } +#endif + NVBLAST_DELETE(this, DamagePatternImpl); +} + + +namespace Nv +{ + namespace Blast + { + void savePatternToObj(DamagePattern* pattern) + { + FILE* fl = fopen("Pattern.obj", "w"); + + std::vector<uint32_t> trc; + + for (uint32_t mesh = 0; mesh < pattern->cellsCount; ++mesh) + { + Mesh* m = pattern->cellsMeshes[mesh]; + + Triangulator trgl; + trgl.triangulate(m); + + auto& t = trgl.getBaseMesh(); + + for (uint32_t v = 0; v < t.size(); ++v) + { + fprintf(fl, "v %f %f %f\n", t[v].a.p.x, t[v].a.p.y, t[v].a.p.z); + fprintf(fl, "v %f %f %f\n", t[v].b.p.x, t[v].b.p.y, t[v].b.p.z); + fprintf(fl, "v %f %f %f\n", t[v].c.p.x, t[v].c.p.y, t[v].c.p.z); + } + trc.push_back(t.size()); + } + + uint32_t cv = 1; + for (uint32_t m = 0; m < trc.size(); ++m) + { + fprintf(fl, "g %d\n", m); + for (uint32_t k = 0; k < trc[m]; ++k) + { + + fprintf(fl, "f %d %d %d \n", cv, cv + 1, cv + 2); + cv += 3; + } + } + + + fclose(fl); + } + + } +}
\ No newline at end of file |