// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2008-2018 NVIDIA Corporation. All rights reserved. #include "SplitMesh.h" #include "FloatMath.h" #include "PsArray.h" #include "foundation/PxVec3.h" #include "foundation/PxQuat.h" #include "foundation/PxMat44.h" using namespace physx::general_floatmath2; using namespace physx::shdfnd; using namespace physx; #pragma warning(disable:4100) namespace SPLIT_MESH { static void addTri(const PxF32 *p1, const PxF32 *p2, const PxF32 *p3, Array< PxU32 > &indices, fm_VertexIndex *vertices) { bool newPos; PxU32 i1 = vertices->getIndex(p1,newPos); PxU32 i2 = vertices->getIndex(p2,newPos); PxU32 i3 = vertices->getIndex(p3,newPos); indices.pushBack(i1); indices.pushBack(i2); indices.pushBack(i3); } PX_INLINE void rotationArc(const PxVec3 &v0,const PxVec3 &v1,PxQuat &quat) { PxVec3 cross = v0.cross(v1); PxF32 d = v0.dot(v1); if(d<=-1.0f) // 180 about x axis { quat.x = 1.0f; quat.y = quat.z = quat.w =0.0f; return; } PxF32 s = PxSqrt((1+d)*2); PxF32 recip = 1.0f / s; quat.x = cross.x * recip; quat.y = cross.y * recip; quat.z = cross.z * recip; quat.w = s * 0.5f; } void computePlaneQuad(const PxF32 *planeEquation,physx::PxVec3 *quad) { PxVec3 ref(0,1,0); PxQuat quat; PxVec3 normal(planeEquation[0],planeEquation[1],planeEquation[2]); rotationArc(ref,normal,quat); PxMat44 matrix(quat); PxVec3 origin(0,-planeEquation[3],0); PxVec3 center = matrix.transform(origin); #define PLANE_DIST 1000 PxVec3 upperLeft(-PLANE_DIST,0,-PLANE_DIST); PxVec3 upperRight(PLANE_DIST,0,-PLANE_DIST); PxVec3 lowerRight(PLANE_DIST,0,PLANE_DIST); PxVec3 lowerLeft(-PLANE_DIST,0,PLANE_DIST); quad[0] = matrix.transform(upperLeft); quad[1] = matrix.transform(upperRight); quad[2] = matrix.transform(lowerRight); quad[3] = matrix.transform(lowerLeft); } void splitMesh(const PxF32 *planeEquation,const SimpleMesh &input,SimpleMesh &leftMesh,SimpleMesh &rightMesh,bool /*closedMesh*/) { Array< PxU32 > leftIndices; Array< PxU32 > rightIndices; fm_VertexIndex *leftVertices = fm_createVertexIndex(0.00001f,false); fm_VertexIndex *rightVertices = fm_createVertexIndex(0.00001f,false); { for (PxU32 i=0; igetVcount(),leftIndices.size()/3,leftVertices->getVerticesFloat(),&leftIndices[0]); } if ( !rightIndices.empty() ) { rightMesh.set(rightVertices->getVcount(),rightIndices.size()/3,rightVertices->getVerticesFloat(),&rightIndices[0]); } fm_releaseVertexIndex(leftVertices); fm_releaseVertexIndex(rightVertices); } };