void Gu::ConvexMesh::debugVisualize(Cm::RenderOutput& out, const PxTransform& pose, const PxMeshScale& scale) const { const PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA); const PxVec3* vertices = mHullData.getHullVertices(); const PxU8* indexBuffer = mHullData.getVertexData8(); const PxU32 nbPolygons = getNbPolygonsFast(); const PxMat44 m44(PxMat33(pose.q) * scale.toMat33(), pose.p); out << m44 << scolor; // PT: no need to output this for each segment! for (PxU32 i = 0; i < nbPolygons; i++) { const PxU32 pnbVertices = mHullData.mPolygons[i].mNbVerts; PxVec3 begin = m44.transform(vertices[indexBuffer[0]]); // PT: transform it only once before the loop starts for (PxU32 j = 1; j < pnbVertices; j++) { PxVec3 end = m44.transform(vertices[indexBuffer[j]]); out.outputSegment(begin, end); begin = end; } out.outputSegment(begin, m44.transform(vertices[indexBuffer[0]])); indexBuffer += pnbVertices; } }
void Gu::TriangleMesh::debugVisualize( Cm::RenderOutput& out, const Cm::Matrix34& absPose, const PxBounds3& cullbox, const PxU64 mask, const PxReal fscale) const { bool cscale = !!(mask & ((PxU64)1 << PxVisualizationParameter::eCULL_BOX)); const PxMat44 midt = PxMat44::createIdentity(); const PxU32 nbTriangles = mesh.getNumTriangles(); const PxU32 nbVertices = mesh.getNumVertices(); const PxVec3* vertices = mesh.getVertices(); const void* indices = getTrianglesFast(); const bool has16BitIndices = mesh.has16BitIndices(); if (fscale) { const PxU32 fcolor = PxDebugColor::eARGB_DARKRED; for (PxU32 i=0; i<nbTriangles; i++) { PxVec3 wp[3]; getTriangle(*this, i, wp, vertices, indices, absPose, has16BitIndices); const PxVec3 center = (wp[0] + wp[1] + wp[2]) / 3.0f; PxVec3 normal = (wp[0] - wp[1]).cross(wp[0] - wp[2]); PX_ASSERT(!normal.isZero()); normal = normal.getNormalized(); if (!cscale || cullbox.contains(center)) out << midt << fcolor << Cm::DebugArrow(center, normal * fscale); } } if (mask & ((PxU64)1 << PxVisualizationParameter::eCOLLISION_SHAPES)) { const PxU32 scolor = PxDebugColor::eARGB_MAGENTA; out << midt << scolor; // PT: no need to output this for each segment! // PT: transform vertices only once PxVec3* transformed = (PxVec3*)PX_ALLOC(sizeof(PxVec3)*nbVertices); for(PxU32 i=0;i<nbVertices;i++) transformed[i] = absPose.transform(vertices[i]); for (PxU32 i=0; i<nbTriangles; i++) { PxVec3 wp[3]; getTriangle(*this, i, wp, transformed, indices, has16BitIndices); if (!cscale || (cullbox.contains(wp[0]) && cullbox.contains(wp[1]) && cullbox.contains(wp[2]))) { out.outputSegment(wp[0], wp[1]); out.outputSegment(wp[1], wp[2]); out.outputSegment(wp[2], wp[0]); } } PX_FREE(transformed); } if (mask & ((PxU64)1 << PxVisualizationParameter::eCOLLISION_EDGES)) { const PxU32 ecolor = PxDebugColor::eARGB_YELLOW; for (PxU32 i=0; i<nbTriangles; i++) { PxVec3 wp[3]; getTriangle(*this, i, wp, vertices, indices, absPose, has16BitIndices); const PxU32 flags = mesh.getTrigSharedEdgeFlags(i); if(flags & Gu::ETD_CONVEX_EDGE_01) { if (!cscale || (cullbox.contains(wp[0]) && cullbox.contains(wp[1]))) out << midt << ecolor << Cm::RenderOutput::LINES << wp[0] << wp[1]; } if(flags & Gu::ETD_CONVEX_EDGE_12) { if (!cscale || (cullbox.contains(wp[1]) && cullbox.contains(wp[2]))) out << midt << ecolor << Cm::RenderOutput::LINES << wp[1] << wp[2]; } if(flags & Gu::ETD_CONVEX_EDGE_20) { if (!cscale || (cullbox.contains(wp[0]) && cullbox.contains(wp[2]))) out << midt << ecolor << Cm::RenderOutput::LINES << wp[0] << wp[2]; } } } }