APEX Framework: ExplicitHierarchicalMesh.h Source File

NVIDIA APEX

ExplicitHierarchicalMesh.h
00001 /*
00002  * Copyright (c) 2008-2017, NVIDIA CORPORATION.  All rights reserved.
00003  *
00004  * NVIDIA CORPORATION and its licensors retain all intellectual property
00005  * and proprietary rights in and to this software, related documentation
00006  * and any modifications thereto.  Any use, reproduction, disclosure or
00007  * distribution of this software and related documentation without an express
00008  * license agreement from NVIDIA CORPORATION is strictly prohibited.
00009  */
00010 
00011 
00012 #ifndef EXPLICIT_HIERARCHICAL_MESH_H
00013 #define EXPLICIT_HIERARCHICAL_MESH_H
00014 
00015 #include "foundation/Px.h"
00016 #include "IProgressListener.h"
00017 #include "RenderMeshAsset.h"
00018 #include "ConvexHullMethod.h"
00019 #include "foundation/PxPlane.h"
00020 
00021 namespace nvidia
00022 {
00023 namespace apex
00024 {
00025 
00026 PX_PUSH_PACK_DEFAULT
00027 
00033 struct ExplicitVertexFormat
00034 {
00036     uint32_t            mWinding;
00037 
00039     bool                mHasStaticPositions;
00040 
00042     bool                mHasStaticNormals;
00043 
00045     bool                mHasStaticTangents;
00046 
00048     bool                mHasStaticBinormals;
00049 
00051     bool                mHasStaticColors;
00052 
00054     bool                mHasStaticSeparateBoneBuffer;
00055 
00057     bool                mHasStaticDisplacements;
00058 
00060     bool                mHasDynamicPositions;
00061 
00063     bool                mHasDynamicNormals;
00064 
00066     bool                mHasDynamicTangents;
00067 
00069     bool                mHasDynamicBinormals;
00070 
00072     bool                mHasDynamicColors;
00073 
00075     bool                mHasDynamicSeparateBoneBuffer;
00076 
00078     bool                mHasDynamicDisplacements;
00079 
00081     uint32_t            mUVCount;
00082 
00084     uint32_t            mBonesPerVertex;
00085 
00087     ExplicitVertexFormat()
00088     {
00089         clear();
00090     }
00091 
00113     void    clear()
00114     {
00115         mWinding = RenderCullMode::CLOCKWISE;
00116         mHasStaticPositions = false;
00117         mHasStaticNormals = false;
00118         mHasStaticTangents = false;
00119         mHasStaticBinormals = false;
00120         mHasStaticColors = false;
00121         mHasStaticSeparateBoneBuffer = false;
00122         mHasStaticDisplacements = false;
00123         mHasDynamicPositions = false;
00124         mHasDynamicNormals = false;
00125         mHasDynamicTangents = false;
00126         mHasDynamicBinormals = false;
00127         mHasDynamicColors = false;
00128         mHasDynamicSeparateBoneBuffer = false;
00129         mHasDynamicDisplacements = false;
00130         mUVCount = 0;
00131         mBonesPerVertex = 0;
00132     }
00133 
00137     bool    operator == (const ExplicitVertexFormat& data) const
00138     {
00139         if (mWinding != data.mWinding)
00140         {
00141             return false;
00142         }
00143         if (mHasStaticPositions != data.mHasStaticPositions ||
00144                 mHasStaticNormals != data.mHasStaticNormals ||
00145                 mHasStaticTangents != data.mHasStaticTangents ||
00146                 mHasStaticBinormals != data.mHasStaticBinormals ||
00147                 mHasStaticColors != data.mHasStaticColors ||
00148                 mHasStaticSeparateBoneBuffer != data.mHasStaticSeparateBoneBuffer ||
00149                 mHasStaticDisplacements != data.mHasStaticDisplacements)
00150         {
00151             return false;
00152         }
00153         if (mHasDynamicPositions != data.mHasDynamicPositions ||
00154                 mHasDynamicNormals != data.mHasDynamicNormals ||
00155                 mHasDynamicTangents != data.mHasDynamicTangents ||
00156                 mHasDynamicBinormals != data.mHasDynamicBinormals ||
00157                 mHasDynamicColors != data.mHasDynamicColors ||
00158                 mHasDynamicSeparateBoneBuffer != data.mHasDynamicSeparateBoneBuffer ||
00159                 mHasDynamicDisplacements != data.mHasDynamicDisplacements)
00160         {
00161             return false;
00162         }
00163         if (mUVCount != data.mUVCount)
00164         {
00165             return false;
00166         }
00167         return true;
00168     }
00169 
00173     bool    operator != (const ExplicitVertexFormat& data) const
00174     {
00175         return !(*this == data);
00176     }
00177 
00181     void    copyToVertexFormat(VertexFormat* format) const
00182     {
00183         format->reset();
00184         uint32_t bi;
00185         if (mHasStaticPositions)
00186         {
00187             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::POSITION));
00188             format->setBufferFormat(bi, RenderDataFormat::FLOAT3);
00189             format->setBufferAccess(bi, mHasDynamicPositions ? RenderDataAccess::DYNAMIC :  RenderDataAccess::STATIC);
00190         }
00191         if (mHasStaticNormals)
00192         {
00193             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::NORMAL));
00194             format->setBufferFormat(bi, RenderDataFormat::FLOAT3);
00195             format->setBufferAccess(bi, mHasDynamicNormals ? RenderDataAccess::DYNAMIC :  RenderDataAccess::STATIC);
00196         }
00197         if (mHasStaticTangents)
00198         {
00199             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::TANGENT));
00200             format->setBufferFormat(bi, RenderDataFormat::FLOAT3);
00201             format->setBufferAccess(bi, mHasDynamicTangents ? RenderDataAccess::DYNAMIC :  RenderDataAccess::STATIC);
00202         }
00203         if (mHasStaticBinormals)
00204         {
00205             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BINORMAL));
00206             format->setBufferFormat(bi, RenderDataFormat::FLOAT3);
00207             format->setBufferAccess(bi, mHasDynamicBinormals ? RenderDataAccess::DYNAMIC :  RenderDataAccess::STATIC);
00208         }
00209         if (mHasStaticDisplacements)
00210         {
00211             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::DISPLACEMENT_TEXCOORD));
00212             format->setBufferFormat(bi, RenderDataFormat::FLOAT3);
00213             format->setBufferAccess(bi, mHasDynamicDisplacements ? RenderDataAccess::DYNAMIC : RenderDataAccess::STATIC);
00214             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::DISPLACEMENT_FLAGS));
00215             format->setBufferFormat(bi, RenderDataFormat::UINT1);
00216             format->setBufferAccess(bi, mHasDynamicDisplacements ? RenderDataAccess::DYNAMIC : RenderDataAccess::STATIC);
00217         }
00218         if (mUVCount > 0)
00219         {
00220             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::TEXCOORD0));
00221             format->setBufferFormat(bi, RenderDataFormat::FLOAT2);
00222         }
00223         if (mUVCount > 1)
00224         {
00225             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::TEXCOORD1));
00226             format->setBufferFormat(bi, RenderDataFormat::FLOAT2);
00227         }
00228         if (mUVCount > 2)
00229         {
00230             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::TEXCOORD2));
00231             format->setBufferFormat(bi, RenderDataFormat::FLOAT2);
00232         }
00233         if (mUVCount > 3)
00234         {
00235             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::TEXCOORD3));
00236             format->setBufferFormat(bi, RenderDataFormat::FLOAT2);
00237         }
00238         switch (mBonesPerVertex)
00239         {
00240         case 1:
00241             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_INDEX));
00242             format->setBufferFormat(bi, RenderDataFormat::USHORT1);
00243             break;
00244         case 2:
00245             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_INDEX));
00246             format->setBufferFormat(bi, RenderDataFormat::USHORT2);
00247             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_WEIGHT));
00248             format->setBufferFormat(bi, RenderDataFormat::FLOAT2);
00249             break;
00250         case 3:
00251             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_INDEX));
00252             format->setBufferFormat(bi, RenderDataFormat::USHORT3);
00253             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_WEIGHT));
00254             format->setBufferFormat(bi, RenderDataFormat::FLOAT3);
00255             break;
00256         case 4:
00257             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_INDEX));
00258             format->setBufferFormat(bi, RenderDataFormat::USHORT4);
00259             bi = (uint32_t)format->addBuffer(format->getSemanticName(RenderVertexSemantic::BONE_WEIGHT));
00260             format->setBufferFormat(bi, RenderDataFormat::FLOAT4);
00261             break;
00262         }
00263 
00264         format->setHasSeparateBoneBuffer(mHasStaticSeparateBoneBuffer);
00265         format->setWinding((RenderCullMode::Enum)mWinding);
00266     }
00267 };
00268 
00269 
00277 struct ExplicitSubmeshData
00278 {
00282     enum
00283     {
00284         MaterialNameBufferSize = 1024
00285     };
00286 
00290     char                    mMaterialName[MaterialNameBufferSize];
00291     
00296     ExplicitVertexFormat    mVertexFormat; 
00297 
00301     bool    operator == (const ExplicitSubmeshData& data) const
00302     {
00303         return !::strcmp(mMaterialName, data.mMaterialName) && mVertexFormat == data.mVertexFormat;
00304     }
00305 
00309     bool    operator != (const ExplicitSubmeshData& data) const
00310     {
00311         return !(*this == data);
00312     }
00313 };
00314 
00315 
00319 struct CollisionVolumeDesc
00320 {
00321     CollisionVolumeDesc()
00322     {
00323         setToDefault();
00324     }
00325 
00329     void setToDefault()
00330     {
00331         mHullMethod = ConvexHullMethod::CONVEX_DECOMPOSITION;
00332         mConcavityPercent = 4.0f;
00333         mMergeThreshold = 4.0f;
00334         mRecursionDepth = 0;
00335         mMaxVertexCount = 0;
00336         mMaxEdgeCount = 0;
00337         mMaxFaceCount = 0;
00338     }
00339 
00344     ConvexHullMethod::Enum  mHullMethod;
00345 
00350     float                   mConcavityPercent;
00351 
00356     float                   mMergeThreshold;
00357     
00364     uint32_t                mRecursionDepth;
00365 
00370     uint32_t                mMaxVertexCount;
00371 
00376     uint32_t                mMaxEdgeCount;
00377 
00382     uint32_t                mMaxFaceCount;
00383 };
00384 
00385 
00389 struct CollisionDesc
00390 {
00400     unsigned                mDepthCount;
00401 
00405     CollisionVolumeDesc*    mVolumeDescs;
00406 
00412     float                   mMaximumTrimming;
00413 
00415     CollisionDesc()
00416     {
00417         setToDefault();
00418     }
00419 
00423     void setToDefault()
00424     {
00425         mDepthCount = 0;
00426         mVolumeDescs = NULL;
00427         mMaximumTrimming = 0.2f;
00428     }
00429 };
00430 
00431 
00436 struct FractureMethod
00437 {
00441     enum Enum
00442     {
00443         Unknown,
00444         Slice,
00445         Cutout,
00446         Voronoi,
00447 
00448         FractureMethodCount
00449     };
00450 };
00451 
00452 
00458 struct FractureMaterialDesc
00459 {
00463     PxVec2  uvScale;
00464 
00468     PxVec2  uvOffset;
00469 
00474     PxVec3  tangent;
00475 
00479     float   uAngle;
00480 
00485     uint32_t interiorSubmeshIndex;
00486 
00488     FractureMaterialDesc()
00489     {
00490         setToDefault();
00491     }
00492 
00501     void    setToDefault()
00502     {
00503         uvScale = PxVec2(1.0f);
00504         uvOffset = PxVec2(0.0f);
00505         tangent = PxVec3(0.0f);
00506         uAngle = 0.0f;
00507         interiorSubmeshIndex = 0;
00508     }
00509 };
00510 
00511 
00516 struct MaterialFrame
00517 {
00518     MaterialFrame() :
00519         mCoordinateSystem(PxVec4(1.0f)),
00520         mUVPlane(PxVec3(0.0f, 0.0f, 1.0f), 0.0f),
00521         mUVScale(1.0f),
00522         mUVOffset(0.0f),
00523         mFractureMethod(FractureMethod::Unknown),
00524         mFractureIndex(-1),
00525         mSliceDepth(0)
00526     {       
00527     }
00528 
00532     void    buildCoordinateSystemFromMaterialDesc(const nvidia::FractureMaterialDesc& materialDesc, const PxPlane& plane)
00533             {
00534                 PxVec3 zAxis = plane.n;
00535                 zAxis.normalize();
00536                 PxVec3 xAxis = materialDesc.tangent;
00537                 PxVec3 yAxis = zAxis.cross(xAxis);
00538                 const float l2 = yAxis.magnitudeSquared();
00539                 if (l2 > PX_EPS_F32*PX_EPS_F32)
00540                 {
00541                     yAxis *= PxRecipSqrt(l2);
00542                 }
00543                 else
00544                 {
00545                     uint32_t maxDir =  PxAbs(plane.n.x) > PxAbs(plane.n.y) ?
00546                         (PxAbs(plane.n.x) > PxAbs(plane.n.z) ? 0u : 2u) :
00547                         (PxAbs(plane.n.y) > PxAbs(plane.n.z) ? 1u : 2u);
00548                     xAxis = PxMat33(PxIdentity)[(maxDir + 1) % 3];
00549                     yAxis = zAxis.cross(xAxis);
00550                     yAxis.normalize();
00551                 }
00552                 xAxis = yAxis.cross(zAxis);
00553 
00554                 const float c = PxCos(materialDesc.uAngle);
00555                 const float s = PxSin(materialDesc.uAngle);
00556 
00557                 mCoordinateSystem.column0 = PxVec4(c*xAxis + s*yAxis, 0.0f);
00558                 mCoordinateSystem.column1 = PxVec4(c*yAxis - s*xAxis, 0.0f);
00559                 mCoordinateSystem.column2 = PxVec4(zAxis, 0.0f);
00560                 mCoordinateSystem.setPosition(plane.project(PxVec3(0.0f)));
00561 
00562                 mUVPlane = plane;
00563                 mUVScale = materialDesc.uvScale;
00564                 mUVOffset = materialDesc.uvOffset;
00565             }
00566 
00567     PxMat44 mCoordinateSystem; 
00568     PxPlane mUVPlane; 
00569     PxVec2  mUVScale; 
00570     PxVec2  mUVOffset; 
00571     uint32_t    mFractureMethod; 
00572     int32_t mFractureIndex; 
00573     uint32_t    mSliceDepth;    
00574 };
00575 
00576 
00587 class DisplacementMapVolume
00588 {
00589 public:
00596     virtual void getData(uint32_t& width, uint32_t& height, uint32_t& depth, uint32_t& size, unsigned char const** ppData) const = 0;
00597 
00598     virtual ~DisplacementMapVolume() { }
00599 };
00600 
00601 
00609 struct BSPOpenMode
00610 {
00614     enum Enum
00615     {
00616         Automatic,
00617         Closed,
00618         Open,
00619 
00620         BSPOpenModeCount
00621     };
00622 };
00623 
00624 
00633 class ExplicitHierarchicalMesh
00634 {
00635 public:
00637     enum Enum
00638     {
00643         VisualizeMeshBSPOutsideRegions  = (1 << 0),
00644 
00649         VisualizeMeshBSPInsideRegions   = (1 << 1),
00650 
00656         VisualizeMeshBSPSingleRegion    = (1 << 8),
00657 
00659         VisualizeSliceBSPOutsideRegions = (1 << 16),
00660 
00662         VisualizeSliceBSPInsideRegions  = (1 << 17),
00663 
00665         VisualizeSliceBSPSingleRegion   = (1 << 24),
00666 
00667         VisualizeMeshBSPAllRegions      = VisualizeMeshBSPOutsideRegions | VisualizeMeshBSPInsideRegions
00668     };
00669 
00675     class Embedding
00676     {
00677     public:
00681         enum DataType
00682         {
00683             MaterialLibrary
00684         };
00685         
00689         virtual void    serialize(PxFileBuf& stream, Embedding::DataType type) const = 0;
00690         
00694         virtual void    deserialize(PxFileBuf& stream, Embedding::DataType type, uint32_t version) = 0;
00695     };
00696 
00700     class ConvexHull
00701     {
00702     protected:
00703         ConvexHull()
00704         {
00705         }
00706 
00707         virtual ~ConvexHull()
00708         {
00709         }
00710 
00711     public:
00715         virtual void                    buildFromPoints(const void* points, uint32_t numPoints, uint32_t pointStrideBytes) = 0;
00716 
00720         virtual const PxBounds3&        getBounds() const = 0;
00721 
00725         virtual float                   getVolume() const = 0;
00726 
00730         virtual uint32_t                getVertexCount() const = 0;
00731 
00736         virtual PxVec3                  getVertex(uint32_t vertexIndex) const = 0;
00737 
00741         virtual uint32_t                getEdgeCount() const = 0;
00742 
00748         virtual PxVec3                  getEdgeEndpoint(uint32_t edgeIndex, uint32_t whichEndpoint) const = 0;
00749 
00753         virtual uint32_t                getPlaneCount() const = 0;
00754 
00759         virtual PxPlane                 getPlane(uint32_t planeIndex) const = 0;
00760 
00788         virtual bool                    rayCast(float& in, float& out, const PxVec3& orig, const PxVec3& dir,
00789                                                 const PxTransform& localToWorldRT, const PxVec3& scale, PxVec3* normal = NULL) const = 0;
00798         virtual bool                    reduceHull(uint32_t maxVertexCount, uint32_t maxEdgeCount, uint32_t maxFaceCount, bool inflated) = 0;
00799 
00803         virtual void                    release() = 0;
00804     };
00805 
00813     virtual void                        clear(bool keepRoot = false) = 0;
00814 
00819     virtual int32_t                     maxDepth() const = 0;
00820 
00824     virtual uint32_t                    partCount() const = 0;
00825 
00829     virtual uint32_t                    chunkCount() const = 0;
00830 
00835     virtual int32_t*                    parentIndex(uint32_t chunkIndex) = 0;
00836 
00841     virtual uint64_t                    chunkUniqueID(uint32_t chunkIndex) = 0;
00842 
00846     virtual int32_t*                    partIndex(uint32_t chunkIndex) = 0;
00847 
00851     virtual PxVec3*                     instancedPositionOffset(uint32_t chunkIndex) = 0;
00852 
00856     virtual PxVec2*                     instancedUVOffset(uint32_t chunkIndex) = 0;
00857 
00862     virtual uint32_t                    meshTriangleCount(uint32_t partIndex) const = 0;
00863 
00868     virtual ExplicitRenderTriangle*     meshTriangles(uint32_t partIndex) = 0;
00869 
00873     virtual PxBounds3                   meshBounds(uint32_t partIndex) const = 0;
00874 
00878     virtual PxBounds3                   chunkBounds(uint32_t chunkIndex) const = 0;
00879 
00884     virtual uint32_t*                   chunkFlags(uint32_t chunkIndex) const = 0;
00885 
00889     virtual void                        buildCollisionGeometryForPart(uint32_t partIndex, const CollisionVolumeDesc& desc) = 0;
00890 
00898     virtual void                        buildCollisionGeometryForRootChunkParts(const CollisionDesc& desc, bool aggregateRootChunkParentCollision = true) = 0;
00899 
00903     virtual void                        reduceHulls(const CollisionDesc& desc, bool inflated) = 0;
00904 
00908     virtual uint32_t                    convexHullCount(uint32_t partIndex) const = 0;
00909 
00913     virtual const ConvexHull**          convexHulls(uint32_t partIndex) const = 0;
00914 
00918     virtual PxVec3*                     surfaceNormal(uint32_t partIndex) = 0;
00919 
00923     virtual const DisplacementMapVolume&    displacementMapVolume() const = 0;
00924 
00930     virtual uint32_t                    submeshCount() const = 0;
00931 
00935     virtual ExplicitSubmeshData*        submeshData(uint32_t submeshIndex) = 0;
00936 
00941     virtual uint32_t                    addSubmesh(const ExplicitSubmeshData& submeshData) = 0;
00942 
00951     virtual uint32_t                    getMaterialFrameCount() const = 0;
00952     virtual nvidia::MaterialFrame       getMaterialFrame(uint32_t index) const = 0; 
00953     virtual void                        setMaterialFrame(uint32_t index, const nvidia::MaterialFrame& materialFrame) = 0; 
00954     virtual uint32_t                    addMaterialFrame() = 0; 
00955 
00960     virtual void                        serialize(PxFileBuf& stream, Embedding& embedding) const = 0;
00961     
00966     virtual void                        deserialize(PxFileBuf& stream, Embedding& embedding) = 0;
00967 
00971     virtual void                        set(const ExplicitHierarchicalMesh& mesh) = 0;
00972 
00981     virtual void                        calculateMeshBSP(uint32_t randomSeed, IProgressListener* progressListener = NULL, const uint32_t* microgridSize = NULL, BSPOpenMode::Enum meshMode = BSPOpenMode::Automatic) = 0;
00982 
00986     virtual void                        replaceInteriorSubmeshes(uint32_t partIndex, uint32_t frameCount, uint32_t* frameIndices, uint32_t submeshIndex) = 0;
00987 
00993     virtual void                        visualize(RenderDebugInterface& debugRender, uint32_t flags, uint32_t index = 0) const = 0;
00994 
00998     virtual void                        release() = 0;
00999 
01000 protected:
01006     ExplicitHierarchicalMesh() {}
01007     virtual                             ~ExplicitHierarchicalMesh() {}
01008 
01009 private:
01011     ExplicitHierarchicalMesh&           operator = (const ExplicitHierarchicalMesh&)
01012     {
01013         return *this;
01014     }
01015 };
01016 
01017 
01018 PX_POP_PACK
01019 
01020 }
01021 } // end namespace nvidia
01022 
01023 
01024 #endif // EXPLICIT_HIERARCHICAL_MESH_H

Generated on Fri Dec 15 2017 13:58:35
Copyright © 2012-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved.