aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/shared/internal/include/authoring/Fracturing.h
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/shared/internal/include/authoring/Fracturing.h
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'APEX_1.4/shared/internal/include/authoring/Fracturing.h')
-rw-r--r--APEX_1.4/shared/internal/include/authoring/Fracturing.h544
1 files changed, 544 insertions, 0 deletions
diff --git a/APEX_1.4/shared/internal/include/authoring/Fracturing.h b/APEX_1.4/shared/internal/include/authoring/Fracturing.h
new file mode 100644
index 00000000..751d1ae9
--- /dev/null
+++ b/APEX_1.4/shared/internal/include/authoring/Fracturing.h
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2008-2015, 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.
+ */
+
+#ifndef FRACTURING_H
+
+#define FRACTURING_H
+
+#include "Apex.h"
+#include "ApexUsingNamespace.h"
+#include "PxPlane.h"
+//#include "ApexSharedSerialization.h"
+#include "FractureTools.h"
+#include "ApexString.h"
+#include "ExplicitHierarchicalMesh.h"
+#include "authoring/ApexCSG.h"
+
+#ifndef WITHOUT_APEX_AUTHORING
+
+namespace nvidia
+{
+namespace apex
+{
+
+using namespace FractureTools;
+
+
+struct IntersectMesh
+{
+ enum GridPattern
+ {
+ None, // An infinite plane
+ Equilateral,
+ Right
+ };
+
+ float getSide(const physx::PxVec3& v)
+ {
+ if (m_pattern == None)
+ {
+ return m_plane.distance(v);
+ }
+ physx::PxVec3 vLocal = m_tm.inverseRT().transform(v);
+ float x = vLocal.x - m_cornerX;
+ float y = vLocal.y - m_cornerY;
+ if (y < 0)
+ {
+ return 0;
+ }
+ float scaledY = y / m_ySpacing;
+ uint32_t gridY = (uint32_t)scaledY;
+ if (gridY >= m_numY)
+ {
+ return 0;
+ }
+ scaledY -= (float)gridY;
+ uint32_t yParity = gridY & 1;
+ if (yParity != 0)
+ {
+ scaledY = 1.0f - scaledY;
+ }
+ if (m_pattern == Equilateral)
+ {
+ x += 0.5f * m_xSpacing * scaledY;
+ }
+ if (x < 0)
+ {
+ return 0;
+ }
+ float scaledX = x / m_xSpacing;
+ uint32_t gridX = (uint32_t)scaledX;
+ if (gridX >= m_numX)
+ {
+ return 0;
+ }
+ scaledX -= (float)gridX;
+ uint32_t xParity = (uint32_t)(scaledX >= scaledY);
+ uint32_t triangleNum = 2 * (gridY * m_numX + gridX) + xParity;
+ PX_ASSERT(triangleNum < m_triangles.size());
+ nvidia::ExplicitRenderTriangle& triangle = m_triangles[triangleNum];
+ physx::PxVec3& v0 = triangle.vertices[0].position;
+ physx::PxVec3& v1 = triangle.vertices[1].position;
+ physx::PxVec3& v2 = triangle.vertices[2].position;
+ return ((v1 - v0).cross(v2 - v0)).dot(v - v0);
+ }
+
+ void clear()
+ {
+ m_pattern = None;
+ m_plane = physx::PxPlane(0, 0, 1, 0);
+ m_vertices.reset();
+ m_triangles.reset();
+ }
+
+ void build(const physx::PxPlane& plane)
+ {
+ clear();
+ m_plane = plane;
+ }
+
+ void build(GridPattern pattern, const physx::PxPlane& plane,
+ float cornerX, float cornerY, float xSpacing, float ySpacing, uint32_t numX, uint32_t numY,
+ const PxMat44& tm, float noiseAmplitude, float relativeFrequency, float xPeriod, float yPeriod,
+ int noiseType, int noiseDir, uint32_t submeshIndex, uint32_t frameIndex, const TriangleFrame& triangleFrame, bool forceGrid);
+
+ GridPattern m_pattern;
+
+ PxMat44 m_tm;
+ physx::PxPlane m_plane;
+ physx::Array<nvidia::Vertex> m_vertices;
+ physx::Array<nvidia::ExplicitRenderTriangle> m_triangles;
+
+ uint32_t m_numX;
+ float m_cornerX;
+ float m_xSpacing;
+ uint32_t m_numY;
+ float m_cornerY;
+ float m_ySpacing;
+};
+
+struct DisplacementMapVolumeImpl : public DisplacementMapVolume
+{
+ DisplacementMapVolumeImpl();
+
+ void init(const FractureSliceDesc& desc);
+
+ void getData(uint32_t& width, uint32_t& height, uint32_t& depth, uint32_t& size, unsigned char const** ppData) const;
+
+private:
+
+ void buildData(const physx::PxVec3 scale = physx::PxVec3(1)) const;
+
+ // Data creation is lazy, and does not effect externally visible state
+ // Note: At some point, we will want to switch to floating point displacements
+ mutable physx::Array<unsigned char> data;
+
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+
+};
+
+// CutoutSetImpl
+
+struct PolyVert
+{
+ uint16_t index;
+ uint16_t flags;
+};
+
+struct ConvexLoop
+{
+ physx::Array<PolyVert> polyVerts;
+};
+
+struct Cutout
+{
+ physx::Array<physx::PxVec3> vertices;
+ physx::Array<ConvexLoop> convexLoops;
+};
+
+struct CutoutSetImpl : public CutoutSet
+{
+ CutoutSetImpl() : periodic(false), dimensions(0.0f)
+ {
+ }
+
+ enum Version
+ {
+ First = 0,
+ // New versions must be put here. There is no need to explicitly number them. The
+ // numbers above were put there to conform to the old DestructionToolStreamVersion enum.
+
+ Count,
+ Current = Count - 1
+ };
+
+ uint32_t getCutoutCount() const
+ {
+ return cutouts.size();
+ }
+
+ uint32_t getCutoutVertexCount(uint32_t cutoutIndex) const
+ {
+ return cutouts[cutoutIndex].vertices.size();
+ }
+ uint32_t getCutoutLoopCount(uint32_t cutoutIndex) const
+ {
+ return cutouts[cutoutIndex].convexLoops.size();
+ }
+
+ const physx::PxVec3& getCutoutVertex(uint32_t cutoutIndex, uint32_t vertexIndex) const
+ {
+ return cutouts[cutoutIndex].vertices[vertexIndex];
+ }
+
+ uint32_t getCutoutLoopSize(uint32_t cutoutIndex, uint32_t loopIndex) const
+ {
+ return cutouts[cutoutIndex].convexLoops[loopIndex].polyVerts.size();
+ }
+
+ uint32_t getCutoutLoopVertexIndex(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexNum) const
+ {
+ return cutouts[cutoutIndex].convexLoops[loopIndex].polyVerts[vertexNum].index;
+ }
+ uint32_t getCutoutLoopVertexFlags(uint32_t cutoutIndex, uint32_t loopIndex, uint32_t vertexNum) const
+ {
+ return cutouts[cutoutIndex].convexLoops[loopIndex].polyVerts[vertexNum].flags;
+ }
+ bool isPeriodic() const
+ {
+ return periodic;
+ }
+ const physx::PxVec2& getDimensions() const
+ {
+ return dimensions;
+ }
+
+ void serialize(physx::PxFileBuf& stream) const;
+ void deserialize(physx::PxFileBuf& stream);
+
+ void release()
+ {
+ delete this;
+ }
+
+ physx::Array<Cutout> cutouts;
+ bool periodic;
+ physx::PxVec2 dimensions;
+};
+
+class PartConvexHullProxy : public ExplicitHierarchicalMesh::ConvexHull, public UserAllocated
+{
+public:
+ ConvexHullImpl impl;
+
+ PartConvexHullProxy()
+ {
+ impl.init();
+ }
+
+ PartConvexHullProxy(const PartConvexHullProxy& hull)
+ {
+ *this = hull;
+ }
+
+ PartConvexHullProxy& operator = (const PartConvexHullProxy& hull)
+ {
+ impl.init();
+ if (hull.impl.mParams)
+ {
+ impl.mParams->copy(*hull.impl.mParams);
+ }
+ return *this;
+ }
+
+ virtual void buildFromPoints(const void* points, uint32_t numPoints, uint32_t pointStrideBytes)
+ {
+ impl.buildFromPoints(points, numPoints, pointStrideBytes);
+ }
+
+ virtual const physx::PxBounds3& getBounds() const
+ {
+ return impl.getBounds();
+ }
+
+ virtual float getVolume() const
+ {
+ return impl.getVolume();
+ }
+
+ virtual uint32_t getVertexCount() const
+ {
+ return impl.getVertexCount();
+ }
+
+ virtual physx::PxVec3 getVertex(uint32_t vertexIndex) const
+ {
+ if (vertexIndex < impl.getVertexCount())
+ {
+ return impl.getVertex(vertexIndex);
+ }
+ return physx::PxVec3(0.0f);
+ }
+
+ virtual uint32_t getEdgeCount() const
+ {
+ return impl.getEdgeCount();
+ }
+
+ virtual physx::PxVec3 getEdgeEndpoint(uint32_t edgeIndex, uint32_t whichEndpoint) const
+ {
+ if (edgeIndex < impl.getEdgeCount())
+ {
+ return impl.getVertex(impl.getEdgeEndpointIndex(edgeIndex, whichEndpoint));
+ }
+ return physx::PxVec3(0.0f);
+ }
+
+ /**
+ This is the number of planes which bound the convex hull.
+ */
+ virtual uint32_t getPlaneCount() const
+ {
+ return impl.getPlaneCount();
+ }
+
+ /**
+ This is the plane indexed by planeIndex, which must in
+ the range [0, getPlaneCount()-1].
+ */
+ virtual physx::PxPlane getPlane(uint32_t planeIndex) const
+ {
+ if (planeIndex < impl.getPlaneCount())
+ {
+ return impl.getPlane(planeIndex);
+ }
+ return physx::PxPlane(physx::PxVec3(0.0f), 0.0f);
+ }
+
+ virtual bool rayCast(float& in, float& out, const physx::PxVec3& orig, const physx::PxVec3& dir,
+ const physx::PxTransform& localToWorldRT, const physx::PxVec3& scale, physx::PxVec3* normal = NULL) const
+ {
+ return impl.rayCast(in, out, orig, dir, localToWorldRT, scale, normal);
+ }
+
+ virtual bool reduceHull(uint32_t maxVertexCount, uint32_t maxEdgeCount, uint32_t maxFaceCount, bool inflated)
+ {
+ return impl.reduceHull(maxVertexCount, maxEdgeCount, maxFaceCount, inflated);
+ }
+
+ virtual void release()
+ {
+ delete this;
+ }
+};
+
+PX_INLINE void resizeCollision(physx::Array<PartConvexHullProxy*>& collision, uint32_t hullCount)
+{
+ const uint32_t oldHullCount = collision.size();
+ for (uint32_t i = hullCount; i < oldHullCount; ++i)
+ {
+ collision[i]->release();
+ }
+ collision.resize(hullCount);
+ for (uint32_t i = oldHullCount; i < hullCount; ++i)
+ {
+ collision[i] = PX_NEW(PartConvexHullProxy)();
+ }
+}
+
+void buildCollisionGeometry(physx::Array<PartConvexHullProxy*>& volumes, const CollisionVolumeDesc& desc,
+ const physx::PxVec3* vertices, uint32_t vertexCount, uint32_t vertexByteStride,
+ const uint32_t* indices, uint32_t indexCount);
+
+
+// ExplicitHierarchicalMeshImpl
+
+static uint64_t sNextChunkEUID = 0; // Execution-unique identifier for chunks
+
+class ExplicitHierarchicalMeshImpl : public ExplicitHierarchicalMesh, public UserAllocated
+{
+public:
+
+ // This has been copied from DestructionToolStreamVersion, at ToolStreamVersion_RemovedExplicitHMesh_mMaxDepth.
+ enum Version
+ {
+ First = 0,
+ AddedMaterialFramesToHMesh_and_NoiseType_and_GridSize_to_Cleavage = 7,
+ IncludingVertexFormatInSubmeshData = 12,
+ AddedMaterialLibraryToMesh = 14,
+ AddedCacheChunkSurfaceTracesAndInteriorSubmeshIndex = 32,
+ RemovedExplicitHMesh_mMaxDepth = 38,
+ UsingExplicitPartContainers,
+ SerializingMeshBSP,
+ SerializingMeshBounds,
+ AddedFlagsFieldToPart,
+ PerPartMeshBSPs,
+ StoringRootSubmeshCount,
+ MultipleConvexHullsPerChunk,
+ InstancingData,
+ UVInstancingData,
+ DisplacementData,
+ ChangedMaterialFrameToIncludeFracturingMethodContext,
+ RemovedInteriorSubmeshIndex,
+ AddedSliceDepthToMaterialFrame,
+ RemovedNxChunkAuthoringFlag,
+ ReaddedFlagsToPart,
+ IntroducingChunkPrivateFlags,
+ // New versions must be put here. There is no need to explicitly number them. The
+ // numbers above were put there to conform to the old DestructionToolStreamVersion enum.
+
+ Count,
+ Current = Count - 1
+ };
+
+ struct Part : public UserAllocated
+ {
+ Part() : mMeshBSP(NULL), mSurfaceNormal(0.0f), mFlags(0)
+ {
+ mBounds.setEmpty();
+ }
+
+ ~Part()
+ {
+ if (mMeshBSP != NULL)
+ {
+ mMeshBSP->release();
+ mMeshBSP = NULL;
+ }
+ resizeCollision(mCollision, 0);
+ }
+
+ enum Flags
+ {
+ MeshOpen = (1<<0),
+ };
+
+ physx::PxBounds3 mBounds;
+ physx::Array<nvidia::ExplicitRenderTriangle> mMesh;
+ ApexCSG::IApexBSP* mMeshBSP;
+ physx::Array<PartConvexHullProxy*> mCollision;
+ physx::PxVec3 mSurfaceNormal; // used to kick chunk out if desired
+ uint32_t mFlags; // See Flags
+ };
+
+ struct Chunk : public UserAllocated
+ {
+ Chunk() : mParentIndex(-1), mFlags(0), mPartIndex(-1), mInstancedPositionOffset(physx::PxVec3(0.0f)), mInstancedUVOffset(physx::PxVec2(0.0f)), mPrivateFlags(0)
+ {
+ mEUID = sNextChunkEUID++;
+ }
+
+ enum Flags
+ {
+ Root = (1<<0),
+ RootLeaf = (1<<1),
+ };
+
+ bool isRootChunk() const
+ {
+ return (mPrivateFlags & Root) != 0;
+ }
+
+ bool isRootLeafChunk() const // This means that the chunk is a root chunk and has no children that are root chunks
+ {
+ return (mPrivateFlags & RootLeaf) != 0;
+ }
+
+ PX_INLINE uint64_t getEUID() const
+ {
+ return mEUID;
+ }
+
+ int32_t mParentIndex;
+ uint32_t mFlags; // See DestructibleAsset::ChunkFlags
+ int32_t mPartIndex;
+ physx::PxVec3 mInstancedPositionOffset; // if instanced, the offsetPosition
+ physx::PxVec2 mInstancedUVOffset; // if instanced, the offset UV
+ uint32_t mPrivateFlags; // Things that don't make it to the DestructibleAsset; authoring only. See ExplicitHierarchicalMeshImpl::Chunk::Flags
+
+ private:
+ uint64_t mEUID; // A unique identifier during the application execution. Not to be serialized.
+ };
+
+ physx::Array<Part*> mParts;
+ physx::Array<Chunk*> mChunks;
+ physx::Array<ExplicitSubmeshData> mSubmeshData;
+ physx::Array<nvidia::MaterialFrame> mMaterialFrames;
+ uint32_t mRootSubmeshCount; // How many submeshes came with the root mesh
+
+ ApexCSG::IApexBSPMemCache* mBSPMemCache;
+
+ DisplacementMapVolumeImpl mDisplacementMapVolume;
+
+ ExplicitHierarchicalMeshImpl();
+ ~ExplicitHierarchicalMeshImpl();
+
+ // Sorts chunks in parent-sorted order (stable)
+ void sortChunks(physx::Array<uint32_t>* indexRemap = NULL);
+
+ // Generate part surface normals, if possible
+ void createPartSurfaceNormals();
+
+ // ExplicitHierarchicalMesh implementation:
+
+ uint32_t addPart();
+ bool removePart(uint32_t index);
+ uint32_t addChunk();
+ bool removeChunk(uint32_t index);
+ void serialize(physx::PxFileBuf& stream, Embedding& embedding) const;
+ void deserialize(physx::PxFileBuf& stream, Embedding& embedding);
+ int32_t maxDepth() const;
+ uint32_t partCount() const;
+ uint32_t chunkCount() const;
+ uint32_t depth(uint32_t chunkIndex) const;
+ int32_t* parentIndex(uint32_t chunkIndex);
+ uint64_t chunkUniqueID(uint32_t chunkIndex);
+ int32_t* partIndex(uint32_t chunkIndex);
+ physx::PxVec3* instancedPositionOffset(uint32_t chunkIndex);
+ physx::PxVec2* instancedUVOffset(uint32_t chunkIndex);
+ uint32_t meshTriangleCount(uint32_t partIndex) const;
+ nvidia::ExplicitRenderTriangle* meshTriangles(uint32_t partIndex);
+ physx::PxBounds3 meshBounds(uint32_t partIndex) const;
+ physx::PxBounds3 chunkBounds(uint32_t chunkIndex) const;
+ uint32_t* chunkFlags(uint32_t chunkIndex) const;
+ uint32_t convexHullCount(uint32_t partIndex) const;
+ const ExplicitHierarchicalMesh::ConvexHull** convexHulls(uint32_t partIndex) const;
+ physx::PxVec3* surfaceNormal(uint32_t partIndex);
+ const DisplacementMapVolume& displacementMapVolume() const;
+ uint32_t submeshCount() const;
+ ExplicitSubmeshData* submeshData(uint32_t submeshIndex);
+ uint32_t addSubmesh(const ExplicitSubmeshData& submeshData);
+ uint32_t getMaterialFrameCount() const;
+ nvidia::MaterialFrame getMaterialFrame(uint32_t index) const;
+ void setMaterialFrame(uint32_t index, const nvidia::MaterialFrame& materialFrame);
+ uint32_t addMaterialFrame();
+ void clear(bool keepRoot = false);
+ void set(const ExplicitHierarchicalMesh& mesh);
+ bool calculatePartBSP(uint32_t partIndex, uint32_t randomSeed, uint32_t microgridSize, BSPOpenMode::Enum meshMode, IProgressListener* progressListener = NULL, volatile bool* cancel = NULL);
+ void calculateMeshBSP(uint32_t randomSeed, IProgressListener* progressListener = NULL, const uint32_t* microgridSize = NULL, BSPOpenMode::Enum meshMode = BSPOpenMode::Automatic);
+ void replaceInteriorSubmeshes(uint32_t partIndex, uint32_t frameCount, uint32_t* frameIndices, uint32_t submeshIndex);
+ void visualize(RenderDebugInterface& debugRender, uint32_t flags, uint32_t index = 0) const;
+ void release();
+ void buildMeshBounds(uint32_t partIndex);
+ void buildCollisionGeometryForPart(uint32_t partIndex, const CollisionVolumeDesc& desc);
+ void buildCollisionGeometryForRootChunkParts(const CollisionDesc& desc, bool aggregateRootChunkParentCollision = true);
+ void initializeDisplacementMapVolume(const nvidia::FractureSliceDesc& desc);
+ void reduceHulls(const CollisionDesc& desc, bool inflated);
+ void aggregateCollisionHullsFromRootChildren(uint32_t chunkIndex);
+};
+
+}
+} // end namespace nvidia::apex
+
+#endif
+
+#endif