diff options
Diffstat (limited to 'PhysX_3.4/Source/PhysXCooking/src/convex')
9 files changed, 158 insertions, 120 deletions
diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/BigConvexDataBuilder.cpp b/PhysX_3.4/Source/PhysXCooking/src/convex/BigConvexDataBuilder.cpp index f7ef03dd..0021d3a4 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/BigConvexDataBuilder.cpp +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/BigConvexDataBuilder.cpp @@ -108,8 +108,6 @@ bool BigConvexDataBuilder::save(PxOutputStream& stream, bool platformMismatch) c // we dont compute the edges again here, we have them temporary stored in mHullDataFacesByAllEdges8 structure bool BigConvexDataBuilder::computeValencies(const ConvexHullBuilder& meshBuilder) { - PX_ASSERT(meshBuilder.mHullDataFacesByAllEdges8); - // Create valencies const PxU32 numVertices = meshBuilder.mHull->mNbHullVertices; mSVM->mData.mNbVerts = numVertices; @@ -159,8 +157,10 @@ bool BigConvexDataBuilder::computeValencies(const ConvexHullBuilder& meshBuilder mSVM->mData.mAdjacentVerts[mSVM->mData.mValencies[vertexIndex].mOffset++] = prevIndex; numAdj++; // now traverse the neighbors - PxU8 n0 = meshBuilder.mHullDataFacesByAllEdges8[(meshBuilder.mHullDataPolygons[i].mVRef8 + j)*2]; - PxU8 n1 = meshBuilder.mHullDataFacesByAllEdges8[(meshBuilder.mHullDataPolygons[i].mVRef8 + j)*2 + 1]; + const PxU16 edgeIndex = PxU16(meshBuilder.mEdgeData16[meshBuilder.mHullDataPolygons[i].mVRef8 + j]*2); + PxU8 n0 = meshBuilder.mHullDataFacesByEdges8[edgeIndex]; + PxU8 n1 = meshBuilder.mHullDataFacesByEdges8[edgeIndex + 1]; + PxU32 neighborPolygon = n0 == i ? n1 : n0; while (neighborPolygon != i) { @@ -192,8 +192,10 @@ bool BigConvexDataBuilder::computeValencies(const ConvexHullBuilder& meshBuilder } // now move to next neighbor - n0 = meshBuilder.mHullDataFacesByAllEdges8[(meshBuilder.mHullDataPolygons[neighborPolygon].mVRef8 + nextEdgeIndex)*2]; - n1 = meshBuilder.mHullDataFacesByAllEdges8[(meshBuilder.mHullDataPolygons[neighborPolygon].mVRef8 + nextEdgeIndex)*2 + 1]; + const PxU16 edgeIndex2 = PxU16(meshBuilder.mEdgeData16[(meshBuilder.mHullDataPolygons[neighborPolygon].mVRef8 + nextEdgeIndex)]*2); + n0 = meshBuilder.mHullDataFacesByEdges8[edgeIndex2]; + n1 = meshBuilder.mHullDataFacesByEdges8[edgeIndex2 + 1]; + neighborPolygon = n0 == neighborPolygon ? n1 : n0; } vertexMarker[vertexIndex] = numAdj; diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.cpp b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.cpp index a28c404e..35dac326 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.cpp +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.cpp @@ -37,6 +37,7 @@ #include "PxCooking.h" #include "CookingUtils.h" #include "ConvexHullBuilder.h" +#include "ConvexHullLib.h" #include "CmRadixSortBuffered.h" #include "MeshCleaner.h" #include "PsArray.h" @@ -62,7 +63,6 @@ ConvexHullBuilder::ConvexHullBuilder(Gu::ConvexHullData* hull, const bool buildG mHullDataVertexData8 (NULL), mHullDataFacesByEdges8 (NULL), mHullDataFacesByVertices8 (NULL), - mHullDataFacesByAllEdges8 (NULL), mEdgeData16 (NULL), mEdges (NULL), mHull (hull), @@ -82,7 +82,6 @@ ConvexHullBuilder::~ConvexHullBuilder() PX_DELETE_POD(mHullDataVertexData8); PX_DELETE_POD(mHullDataFacesByEdges8); PX_DELETE_POD(mHullDataFacesByVertices8); - PX_DELETE_POD(mHullDataFacesByAllEdges8); } ////////////////////////////////////////////////////////////////////////// @@ -92,8 +91,10 @@ ConvexHullBuilder::~ConvexHullBuilder() // \param indices [in] indices array // \param nbPolygons [in] number of polygons // \param hullPolygons [in] polygons array +// \param doValidation [in] specifies whether we should run the validation code +// \param hullLib [in] if hullLib is provided, we can reuse the hull create data, hulllib is NULL in case of user provided polygons bool ConvexHullBuilder::init(PxU32 nbVerts, const PxVec3* verts, const PxU32* indices, const PxU32 nbIndices, - const PxU32 nbPolygons, const PxHullPolygon* hullPolygons, PxU32 gaussMapVertexLimit, bool doValidation, bool userPolygons) + const PxU32 nbPolygons, const PxHullPolygon* hullPolygons, bool doValidation, ConvexHullLib* hullLib) { PX_ASSERT(indices); PX_ASSERT(verts); @@ -106,7 +107,6 @@ bool ConvexHullBuilder::init(PxU32 nbVerts, const PxVec3* verts, const PxU32* in mHullDataVertexData8 = NULL; mHullDataFacesByEdges8 = NULL; mHullDataFacesByVertices8 = NULL; - mHullDataFacesByAllEdges8 = NULL; mEdges = NULL; mEdgeData16 = NULL; @@ -153,13 +153,20 @@ bool ConvexHullBuilder::init(PxU32 nbVerts, const PxVec3* verts, const PxU32* in dest += numVerts; } - if(!calculateVertexMapTable(nbPolygons, userPolygons)) + if(!calculateVertexMapTable(nbPolygons, (hullLib != NULL) ? false : true)) return false; // moved create edge list here from save, copy. This is a part of the validation process and // we need to create the edge list anyway - if (!createEdgeList(doValidation, nbIndices, mHull->mNbHullVertices > gaussMapVertexLimit ? true : false)) - return false; + if(!hullLib || !hullLib->createEdgeList(nbIndices, mHullDataVertexData8, &mHullDataFacesByEdges8, &mEdgeData16, &mEdges)) + { + if (!createEdgeList(doValidation, nbIndices)) + return false; + } + else + { + mHull->mNbEdges = PxU16(nbIndices/2); + } #ifdef USE_PRECOMPUTED_HULL_PROJECTION // Loop through polygons @@ -524,7 +531,7 @@ bool ConvexHullBuilder::calculateVertexMapTable(PxU32 nbPolygons, bool userPolyg ////////////////////////////////////////////////////////////////////////// // create edge list -bool ConvexHullBuilder::createEdgeList(bool doValidation, PxU32 nbEdges, bool prepareBigHullData) +bool ConvexHullBuilder::createEdgeList(bool doValidation, PxU32 nbEdges) { // Code below could be greatly simplified if we assume manifold meshes! @@ -562,11 +569,6 @@ bool ConvexHullBuilder::createEdgeList(bool doValidation, PxU32 nbEdges, bool pr return false; } - if (prepareBigHullData) - { - mHullDataFacesByAllEdges8 = PX_NEW(PxU8)[nbEdges * 2]; - } - // 1) Get some bytes: I need one EdgesRefs for each face, and some temp buffers // Face indices by edge indices. First face is the one where the edge is ordered from tail to head. @@ -642,37 +644,6 @@ bool ConvexHullBuilder::createEdgeList(bool doValidation, PxU32 nbEdges, bool pr mHull->mNbEdges = 0; // #non-redundant edges - // A.B. Comment out the early exit temporary since we need to precompute the additonal edge data for GPU - //if (!doValidation) - //{ - // // TODO avoroshilov: this codepath is not supported - - // for (PxU32 i = 0; i < nbEdgesUnshared; i = i + 2) - // { - // const PxU32 sortedIndex = sorted[i]; // Between 0 and Nb - // const PxU32 nextSortedIndex = sorted[i + 1]; // Between 0 and Nb - // const PxU32 polyID = polyIndex[sortedIndex]; // Poly index - // const PxU32 nextPolyID = polyIndex[nextSortedIndex]; // Poly index - // - // mHullDataFacesByEdges8[(mHull->mNbEdges) * 2] = Ps::to8(polyID); - // mHullDataFacesByEdges8[(mHull->mNbEdges) * 2 + 1] = Ps::to8(nextPolyID); - - // // store the full edge data for later use in big convex hull valencies computation - // if(mHullDataFacesByAllEdges8) - // { - // mHullDataFacesByAllEdges8[edgeData[sortedIndex] * 2] = Ps::to8(polyID); - // mHullDataFacesByAllEdges8[edgeData[sortedIndex] * 2 + 1] = Ps::to8(nextPolyID); - - // mHullDataFacesByAllEdges8[edgeData[nextSortedIndex] * 2] = Ps::to8(polyID); - // mHullDataFacesByAllEdges8[edgeData[nextSortedIndex] * 2 + 1] = Ps::to8(nextPolyID); - // } - // mHull->mNbEdges++; - // } - - // PX_DELETE_POD(bufferAdd); - // return true; - //} - // 4) Loop through all possible edges // - clean edges list by removing redundant edges // - create EdgesRef list @@ -685,7 +656,6 @@ bool ConvexHullBuilder::createEdgeList(bool doValidation, PxU32 nbEdges, bool pr PxU32 previousRef0 = PX_INVALID_U32; PxU32 previousRef1 = PX_INVALID_U32; - PxU32 previousIndex = PX_INVALID_U32; PxU32 previousPolyId = PX_INVALID_U32; PxU16 nbHullEdges = 0; @@ -732,23 +702,6 @@ bool ConvexHullBuilder::createEdgeList(bool doValidation, PxU32 nbEdges, bool pr mEdgeData16[mHullDataPolygons[polyID].mVRef8 + vertexID] = Ps::to16(i / 2); - if (mHullDataFacesByAllEdges8) - { - if (previousIndex != PX_INVALID_U32) - { - // store the full edge data for later use in big convex hull valencies computation - mHullDataFacesByAllEdges8[edgeData[sortedIndex] * 2] = Ps::to8(polyID); - mHullDataFacesByAllEdges8[edgeData[sortedIndex] * 2 + 1] = Ps::to8(polyIndex[previousIndex]); - - mHullDataFacesByAllEdges8[edgeData[previousIndex] * 2] = Ps::to8(polyID); - mHullDataFacesByAllEdges8[edgeData[previousIndex] * 2 + 1] = Ps::to8(polyIndex[previousIndex]); - previousIndex = PX_INVALID_U32; - } - else - { - previousIndex = sortedIndex; - } - } // Create mEdgesRef on the fly polyIndex2[i] = polyID; diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.h b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.h index 7d2215e2..da0ffaf3 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.h +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullBuilder.h @@ -38,6 +38,7 @@ namespace physx { struct PxHullPolygon; + class ConvexHullLib; namespace Gu { @@ -57,12 +58,12 @@ namespace physx ~ConvexHullBuilder(); bool init(PxU32 nbVerts, const PxVec3* verts, const PxU32* indices, const PxU32 nbIndices, const PxU32 nbPolygons, - const PxHullPolygon* hullPolygons, PxU32 gaussMapVertexLimit, bool doValidation = true, bool userPolygons = false); + const PxHullPolygon* hullPolygons, bool doValidation = true, ConvexHullLib* hullLib = NULL); bool save(PxOutputStream& stream, bool platformMismatch) const; bool copy(Gu::ConvexHullData& hullData, PxU32& nb); - bool createEdgeList(bool doValidation, PxU32 nbEdges, bool prepareBigHullData); + bool createEdgeList(bool doValidation, PxU32 nbEdges); bool checkHullPolygons() const; bool calculateVertexMapTable(PxU32 nbPolygons, bool userPolygons = false); @@ -78,7 +79,6 @@ namespace physx PxU8* mHullDataVertexData8; PxU8* mHullDataFacesByEdges8; PxU8* mHullDataFacesByVertices8; - PxU8* mHullDataFacesByAllEdges8; // data used fom big hull valencies computation PxU16* mEdgeData16; //!< Edge indices indexed by hull polygons PxU16* mEdges; //!< Edge to vertex mapping diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullLib.h b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullLib.h index cd8f766e..06ff9adc 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullLib.h +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexHullLib.h @@ -58,6 +58,9 @@ namespace physx // fills the PxConvexMeshDesc with computed hull data virtual void fillConvexMeshDesc(PxConvexMeshDesc& desc) = 0; + // compute the edge list information if possible + virtual bool createEdgeList(const PxU32 nbIndices, const PxU8* indices, PxU8** hullDataFacesByEdges8, PxU16** edgeData16, PxU16** edges) = 0; + static const PxU32 gpuMaxVertsPerFace = 32; protected: diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.cpp b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.cpp index bfdf0bef..0d283d9f 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.cpp +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.cpp @@ -66,7 +66,7 @@ ConvexMeshBuilder::~ConvexMeshBuilder() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // load the mesh data from given polygons -bool ConvexMeshBuilder::build(const PxConvexMeshDesc& desc, PxU32 gaussMapVertexLimit, bool validateOnly, bool userPolygons) +bool ConvexMeshBuilder::build(const PxConvexMeshDesc& desc, PxU32 gaussMapVertexLimit, bool validateOnly, ConvexHullLib* hullLib) { if(!desc.isValid()) { @@ -74,7 +74,7 @@ bool ConvexMeshBuilder::build(const PxConvexMeshDesc& desc, PxU32 gaussMapVertex return false; } - if(!loadConvexHull(desc, gaussMapVertexLimit, userPolygons)) + if(!loadConvexHull(desc, hullLib)) return false; // Compute local bounds (*after* hull has been created) @@ -239,7 +239,7 @@ void ConvexMeshBuilder::computeMassInfo(bool lowerPrecision) #pragma warning(disable:4996) // permitting use of gatherStrided until we have a replacement. #endif -bool ConvexMeshBuilder::loadConvexHull(const PxConvexMeshDesc& desc, PxU32 gaussMapVertexLimit, bool userPolygons) +bool ConvexMeshBuilder::loadConvexHull(const PxConvexMeshDesc& desc, ConvexHullLib* hullLib) { // gather points PxVec3* geometry = reinterpret_cast<PxVec3*>(PxAlloca(sizeof(PxVec3)*desc.points.count)); @@ -281,7 +281,7 @@ bool ConvexMeshBuilder::loadConvexHull(const PxConvexMeshDesc& desc, PxU32 gauss Cooking::gatherStrided(desc.polygons.data,hullPolygons,desc.polygons.count,sizeof(PxHullPolygon),desc.polygons.stride); // if user polygons, make sure the largest one is the first one - if (userPolygons) + if (!hullLib) { PxU32 largestPolygon = 0; for (PxU32 i = 1; i < desc.polygons.count; i++) @@ -299,7 +299,7 @@ bool ConvexMeshBuilder::loadConvexHull(const PxConvexMeshDesc& desc, PxU32 gauss } const bool doValidation = desc.flags & PxConvexFlag::eDISABLE_MESH_VALIDATION ? false : true; - if(!hullBuilder.init(desc.points.count, geometry, topology, desc.indices.count, desc.polygons.count, hullPolygons, gaussMapVertexLimit, doValidation)) + if(!hullBuilder.init(desc.points.count, geometry, topology, desc.indices.count, desc.polygons.count, hullPolygons, doValidation, hullLib)) { Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Gu::ConvexMesh::loadConvexHull: convex hull init failed!"); return false; diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.h b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.h index cdfe0376..e81c68cc 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.h +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/ConvexMeshBuilder.h @@ -47,7 +47,7 @@ namespace physx // loads the computed or given convex hull from descriptor. // the descriptor does contain polygons directly, triangles are not allowed - bool build(const PxConvexMeshDesc&, PxU32 gaussMapVertexLimit, bool validateOnly = false, bool userPolygons = false); + bool build(const PxConvexMeshDesc&, PxU32 gaussMapVertexLimit, bool validateOnly = false, ConvexHullLib* hullLib = NULL); // save the convex mesh into stream bool save(PxOutputStream& stream, bool platformMismatch) const; @@ -56,7 +56,7 @@ namespace physx bool copy(Gu::ConvexHullData& convexData, PxU32& nb); // loads the convex mesh from given polygons - bool loadConvexHull(const PxConvexMeshDesc&, PxU32 gaussMapVertexLimit, bool userPolygons); + bool loadConvexHull(const PxConvexMeshDesc&, ConvexHullLib* hullLib); // computed hull polygons from given triangles bool computeHullPolygons(const PxU32& nbVerts,const PxVec3* verts, const PxU32& nbTriangles, const PxU32* triangles, PxAllocatorCallback& inAllocator, diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/InflationConvexHullLib.h b/PhysX_3.4/Source/PhysXCooking/src/convex/InflationConvexHullLib.h index 3713bdb7..ee03a15d 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/InflationConvexHullLib.h +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/InflationConvexHullLib.h @@ -96,6 +96,9 @@ namespace physx // computes the convex hull from provided points virtual PxConvexMeshCookingResult::Enum createConvexHull(); + // Inflation convex hull does not store edge information so we cannot provide the edge list + virtual bool createEdgeList(const PxU32 , const PxU8* , PxU8** , PxU16** , PxU16** ) { return false; } + // fills the convexmeshdesc with computed hull data virtual void fillConvexMeshDesc(PxConvexMeshDesc& desc); diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.cpp b/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.cpp index eab6f336..881c9218 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.cpp +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.cpp @@ -182,12 +182,12 @@ namespace local // representation of quick hull half edge struct QuickHullHalfEdge { - QuickHullHalfEdge() : prev(NULL), next(NULL), twin(NULL), face(NULL) + QuickHullHalfEdge() : prev(NULL), next(NULL), twin(NULL), face(NULL), edgeIndex(0xFFFFFFFF) { } QuickHullHalfEdge(PxU32 ) - : prev(NULL), next(NULL), twin(NULL), face(NULL) + : prev(NULL), next(NULL), twin(NULL), face(NULL), edgeIndex(0xFFFFFFFF) { } @@ -199,6 +199,8 @@ namespace local QuickHullFace* face; // face where the edge belong + PxU32 edgeIndex; // edge index used for edge creation + PX_FORCE_INLINE const QuickHullVertex& getTail() const { return tail; @@ -256,17 +258,18 @@ namespace local QuickHullFace* nextFace; // used to indicate next free face in faceList PxU32 index; // face index for compare identification + PxU8 outIndex; // face index used for output descriptor public: QuickHullFace() : edge(NULL), numEdges(0), conflictList(NULL), area(0.0f), planeOffset(0.0f), expandOffset(-FLT_MAX), - state(eVISIBLE), nextFace(NULL) + state(eVISIBLE), nextFace(NULL), outIndex(0) { } QuickHullFace(PxU32 ind) : edge(NULL), numEdges(0), conflictList(NULL), area(0.0f), planeOffset(0.0f), expandOffset(-FLT_MAX), - state(eVISIBLE), nextFace(NULL), index(ind) + state(eVISIBLE), nextFace(NULL), index(ind), outIndex(0) { } @@ -1778,7 +1781,7 @@ namespace local ////////////////////////////////////////////////////////////////////////// QuickHullConvexHullLib::QuickHullConvexHullLib(const PxConvexMeshDesc& desc, const PxCookingParams& params) - : ConvexHullLib(desc, params),mQuickHull(NULL), mCropedConvexHull(NULL), mVertsOut(NULL), mIndicesOut(NULL), mPolygonsOut(NULL) + : ConvexHullLib(desc, params),mQuickHull(NULL), mCropedConvexHull(NULL), mOutMemoryBuffer(NULL), mFaceTranslateTable(NULL) { mQuickHull = PX_NEW_TEMP(local::QuickHull)(params, desc); mQuickHull->preallocate(desc.points.count); @@ -1796,9 +1799,8 @@ QuickHullConvexHullLib::~QuickHullConvexHullLib() PX_DELETE(mCropedConvexHull); } - PX_FREE(mVertsOut); - PX_FREE(mPolygonsOut); - PX_FREE(mIndicesOut); + PX_FREE(mOutMemoryBuffer); + mFaceTranslateTable = NULL; // memory is a part of mOutMemoryBuffer } ////////////////////////////////////////////////////////////////////////// @@ -2224,9 +2226,8 @@ PxConvexMeshCookingResult::Enum QuickHullConvexHullLib::expandHullOBB() computeOBBFromConvex(convexDesc, sides, obbTransform); // free the memory used for the convex mesh desc - PX_FREE_AND_RESET(mVertsOut); - PX_FREE_AND_RESET(mPolygonsOut); - PX_FREE_AND_RESET(mIndicesOut); + PX_FREE_AND_RESET(mOutMemoryBuffer); + mFaceTranslateTable = NULL; // crop the OBB PxU32 maxplanes = PxMin(PxU32(256), expandPlanes.size()); @@ -2279,8 +2280,72 @@ PxConvexMeshCookingResult::Enum QuickHullConvexHullLib::expandHullOBB() return PxConvexMeshCookingResult::eSUCCESS; } +////////////////////////////////////////////////////////////////////////// + +bool QuickHullConvexHullLib::createEdgeList(const PxU32 nbIndices, const PxU8* indices, PxU8** outHullDataFacesByEdges8, PxU16** outEdgeData16, PxU16** outEdges) +{ + // if we croped hull, we dont have the edge information, early exit + if (mCropedConvexHull) + return false; + + PX_ASSERT(mQuickHull); + + // Make sure we did recieved empty buffers + PX_ASSERT(*outHullDataFacesByEdges8 == NULL); + PX_ASSERT(*outEdges == NULL); + PX_ASSERT(*outEdgeData16 == NULL); + + // Allocated the out bufferts + PxU8* hullDataFacesByEdges8 = PX_NEW(PxU8)[nbIndices]; + PxU16* edges = PX_NEW(PxU16)[nbIndices]; + PxU16* edgeData16 = PX_NEW(PxU16)[nbIndices]; + + *outHullDataFacesByEdges8 = hullDataFacesByEdges8; + *outEdges = edges; + *outEdgeData16 = edgeData16; + + PxU16 edgeIndex = 0; + PxU32 edgeOffset = 0; + for(PxU32 i = 0; i < mQuickHull->mNumHullFaces; i++) + { + const local::QuickHullFace& face = *mQuickHull->mHullFaces[mFaceTranslateTable[i]]; + + // Face must be visible + PX_ASSERT(face.state == local::QuickHullFace::eVISIBLE); + + // parse the edges + const PxU32 startEdgeOffset = edgeOffset; + local::QuickHullHalfEdge* hedge = face.edge; + do + { + // check if hedge has been stored + if(hedge->edgeIndex == 0xFFFFFFFF) + { + edges[edgeIndex*2] = indices[edgeOffset]; + edges[edgeIndex*2 + 1] = indices[(hedge->next != face.edge) ? edgeOffset + 1 : startEdgeOffset]; + + hullDataFacesByEdges8[edgeIndex*2] = hedge->face->outIndex; + hullDataFacesByEdges8[edgeIndex*2 + 1] = hedge->next->twin->face->outIndex; + edgeData16[edgeOffset] = edgeIndex; + hedge->edgeIndex = edgeIndex; + hedge->next->twin->prev->edgeIndex = edgeIndex; + + edgeIndex++; + } + else + { + edgeData16[edgeOffset] = Ps::to16(hedge->edgeIndex); + } + + hedge = hedge->next; + edgeOffset++; + } while (hedge != face.edge); + } + + return true; +} ////////////////////////////////////////////////////////////////////////// // fill the descriptor with computed verts, indices and polygons @@ -2317,12 +2382,20 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromQuickHull(PxConvexMeshDesc& d } // allocate out buffers - PxU32* indices = reinterpret_cast<PxU32*> (PX_ALLOC_TEMP(sizeof(PxU32)*numIndices, "PxU32")); - PxI32* translateTable = reinterpret_cast<PxI32*> (PX_ALLOC_TEMP(sizeof(PxU32)*mQuickHull->mNumVertices, "PxU32")); + const PxU32 indicesBufferSize = sizeof(PxU32)*numIndices; + const PxU32 verticesBufferSize = sizeof(PxVec3)*mQuickHull->mNumVertices + 1; + const PxU32 facesBufferSize = sizeof(PxHullPolygon)*numFacesOut; + const PxU32 faceTranslationTableSize = sizeof(PxU16)*numFacesOut; + const PxU32 translationTableSize = sizeof(PxU32)*mQuickHull->mNumVertices; + const PxU32 bufferMemorySize = indicesBufferSize + verticesBufferSize + facesBufferSize + faceTranslationTableSize + translationTableSize; + mOutMemoryBuffer = reinterpret_cast<PxU8*>(PX_ALLOC_TEMP(bufferMemorySize, "ConvexMeshDesc")); + + PxU32* indices = reinterpret_cast<PxU32*> (mOutMemoryBuffer); + PxVec3* vertices = reinterpret_cast<PxVec3*> (mOutMemoryBuffer + indicesBufferSize); + PxHullPolygon* polygons = reinterpret_cast<PxHullPolygon*> (mOutMemoryBuffer + indicesBufferSize + verticesBufferSize); + mFaceTranslateTable = reinterpret_cast<PxU16*> (mOutMemoryBuffer + indicesBufferSize + verticesBufferSize + facesBufferSize); + PxI32* translateTable = reinterpret_cast<PxI32*> (mOutMemoryBuffer + indicesBufferSize + verticesBufferSize + facesBufferSize + faceTranslationTableSize); PxMemSet(translateTable,-1,mQuickHull->mNumVertices*sizeof(PxU32)); - // allocate additional vec3 for V4 safe load in VolumeInteration - PxVec3* vertices = reinterpret_cast<PxVec3*> (PX_ALLOC_TEMP(sizeof(PxVec3)*mQuickHull->mNumVertices + 1, "PxVec3")); - PxHullPolygon* polygons = reinterpret_cast<PxHullPolygon*> (PX_ALLOC_TEMP(sizeof(PxHullPolygon)*numFacesOut, "PxHullPolygon")); // go over the hullPolygons and mark valid vertices, create translateTable PxU32 numVertices = 0; @@ -2380,12 +2453,13 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromQuickHull(PxConvexMeshDesc& d faceIndex = (i == largestFace) ? 0 : i; } - const local::QuickHullFace& face = *mQuickHull->mHullFaces[faceIndex]; + local::QuickHullFace& face = *mQuickHull->mHullFaces[faceIndex]; if(face.state == local::QuickHullFace::eVISIBLE) { //create index data local::QuickHullHalfEdge* he = face.edge; PxU32 index = 0; + he->edgeIndex = 0xFFFFFFFF; indices[index + indexOffset] = PxU32(translateTable[he->tail.index]); index++; he = he->next; @@ -2393,6 +2467,7 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromQuickHull(PxConvexMeshDesc& d { indices[index + indexOffset] = PxU32(translateTable[he->tail.index]); index++; + he->edgeIndex = 0xFFFFFFFF; he = he->next; } @@ -2407,17 +2482,13 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromQuickHull(PxConvexMeshDesc& d polygon.mNbVerts = face.numEdges; indexOffset += face.numEdges; polygons[numFacesOut] = polygon; + mFaceTranslateTable[numFacesOut] = Ps::to16(faceIndex); + face.outIndex = Ps::to8(numFacesOut); numFacesOut++; } } - PX_ASSERT(mQuickHull->mNumHullFaces == numFacesOut); - - mVertsOut = vertices; - mIndicesOut = indices; - mPolygonsOut = polygons; - - PX_FREE(translateTable); + PX_ASSERT(mQuickHull->mNumHullFaces == numFacesOut); } ////////////////////////////////////////////////////////////////////////// @@ -2426,17 +2497,21 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromCroppedHull(PxConvexMeshDesc& { PX_ASSERT(mCropedConvexHull); - // parse the hullOut and fill the result with vertices and polygons - mIndicesOut = reinterpret_cast<PxU32*> (PX_ALLOC_TEMP(sizeof(PxU32)*(mCropedConvexHull->getEdges().size()), "PxU32")); - PxU32 numIndices = mCropedConvexHull->getEdges().size(); - - PxU32 numPolygons = mCropedConvexHull->getFacets().size(); - mPolygonsOut = reinterpret_cast<PxHullPolygon*> (PX_ALLOC_TEMP(sizeof(PxHullPolygon)*numPolygons, "PxHullPolygon")); + // allocate the output buffers + const PxU32 numIndices = mCropedConvexHull->getEdges().size(); + const PxU32 numPolygons = mCropedConvexHull->getFacets().size(); + const PxU32 numVertices = mCropedConvexHull->getVertices().size(); + const PxU32 indicesBufferSize = sizeof(PxU32)*numIndices; + const PxU32 facesBufferSize = sizeof(PxHullPolygon)*numPolygons; + const PxU32 verticesBufferSize = sizeof(PxVec3)*numVertices + 1; // allocate additional vec3 for V4 safe load in VolumeInteration + const PxU32 bufferMemorySize = indicesBufferSize + verticesBufferSize + facesBufferSize; + mOutMemoryBuffer = reinterpret_cast<PxU8*>(PX_ALLOC_TEMP(bufferMemorySize, "ConvexMeshDesc")); - // allocate additional vec3 for V4 safe load in VolumeInteration - mVertsOut = reinterpret_cast<PxVec3*> (PX_ALLOC_TEMP(sizeof(PxVec3)*mCropedConvexHull->getVertices().size() + 1, "PxVec3")); - PxU32 numVertices = mCropedConvexHull->getVertices().size(); - PxMemCopy(mVertsOut, mCropedConvexHull->getVertices().begin(), sizeof(PxVec3)*numVertices); + // parse the hullOut and fill the result with vertices and polygons + PxU32* indicesOut = reinterpret_cast<PxU32*> (mOutMemoryBuffer); + PxHullPolygon* polygonsOut = reinterpret_cast<PxHullPolygon*> (mOutMemoryBuffer + indicesBufferSize); + PxVec3* vertsOut = reinterpret_cast<PxVec3*> (mOutMemoryBuffer + indicesBufferSize + facesBufferSize); + PxMemCopy(vertsOut, mCropedConvexHull->getVertices().begin(), sizeof(PxVec3)*numVertices); PxU32 i = 0; PxU32 k = 0; @@ -2444,7 +2519,7 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromCroppedHull(PxConvexMeshDesc& while (i < mCropedConvexHull->getEdges().size()) { j = 1; - PxHullPolygon& polygon = mPolygonsOut[k]; + PxHullPolygon& polygon = polygonsOut[k]; // get num indices per polygon while (j + i < mCropedConvexHull->getEdges().size() && mCropedConvexHull->getEdges()[i].p == mCropedConvexHull->getEdges()[i + j].p) { @@ -2462,7 +2537,7 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromCroppedHull(PxConvexMeshDesc& while (j--) { - mIndicesOut[i] = mCropedConvexHull->getEdges()[i].v; + indicesOut[i] = mCropedConvexHull->getEdges()[i].v; i++; } k++; @@ -2472,15 +2547,15 @@ void QuickHullConvexHullLib::fillConvexMeshDescFromCroppedHull(PxConvexMeshDesc& outDesc.indices.count = numIndices; outDesc.indices.stride = sizeof(PxU32); - outDesc.indices.data = mIndicesOut; + outDesc.indices.data = indicesOut; outDesc.points.count = numVertices; outDesc.points.stride = sizeof(PxVec3); - outDesc.points.data = mVertsOut; + outDesc.points.data = vertsOut; outDesc.polygons.count = numPolygons; outDesc.polygons.stride = sizeof(PxHullPolygon); - outDesc.polygons.data = mPolygonsOut; + outDesc.polygons.data = polygonsOut; swapLargestFace(outDesc); } diff --git a/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.h b/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.h index b8e657a9..0a9df992 100644 --- a/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.h +++ b/PhysX_3.4/Source/PhysXCooking/src/convex/QuickHullConvexHullLib.h @@ -66,6 +66,9 @@ namespace physx // fills the convexmeshdesc with computed hull data virtual void fillConvexMeshDesc(PxConvexMeshDesc& desc); + // provide the edge list information + virtual bool createEdgeList(const PxU32, const PxU8* , PxU8** , PxU16** , PxU16** ); + protected: // if vertex limit reached we need to expand the hull using the OBB slicing PxConvexMeshCookingResult::Enum expandHullOBB(); @@ -88,9 +91,8 @@ namespace physx local::QuickHull* mQuickHull; // the internal quick hull representation ConvexHull* mCropedConvexHull; //the hull cropped from OBB, used for vertex limit path - PxVec3* mVertsOut; // vertices for output - PxU32* mIndicesOut; // inidices for output - PxHullPolygon* mPolygonsOut; // polygons for output + PxU8* mOutMemoryBuffer; // memory buffer used for output data + PxU16* mFaceTranslateTable; // translation table mapping output faces to internal quick hull table }; } |