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 PxTransform& pose, const PxMeshScale& scaling, const PxBounds3& cullbox, const PxU64 mask, const PxReal fscale, const PxU32 numMaterials) const { PX_UNUSED(numMaterials); //bool cscale = !!(mask & ((PxU64)1 << PxVisualizationParameter::eCULL_BOX)); const PxU64 cullBoxMask = PxU64(1) << PxVisualizationParameter::eCULL_BOX; bool cscale = ((mask & cullBoxMask) == cullBoxMask); const PxMat44 midt(PxIdentity); const Cm::Matrix34 absPose(PxMat33(pose.q) * scaling.toMat33(), pose.p); PxU32 nbTriangles = getNbTrianglesFast(); const PxU32 nbVertices = getNbVerticesFast(); const PxVec3* vertices = getVerticesFast(); const void* indices = getTrianglesFast(); const PxDebugColor::Enum colors[] = { PxDebugColor::eARGB_BLACK, PxDebugColor::eARGB_RED, PxDebugColor::eARGB_GREEN, PxDebugColor::eARGB_BLUE, PxDebugColor::eARGB_YELLOW, PxDebugColor::eARGB_MAGENTA, PxDebugColor::eARGB_CYAN, PxDebugColor::eARGB_WHITE, PxDebugColor::eARGB_GREY, PxDebugColor::eARGB_DARKRED, PxDebugColor::eARGB_DARKGREEN, PxDebugColor::eARGB_DARKBLUE, }; const PxU32 colorCount = sizeof(colors)/sizeof(PxDebugColor::Enum); if(cscale) { const Gu::Box worldBox( (cullbox.maximum + cullbox.minimum)*0.5f, (cullbox.maximum - cullbox.minimum)*0.5f, PxMat33(PxIdentity)); // PT: TODO: use the callback version here to avoid allocating this huge array PxU32* results = reinterpret_cast<PxU32*>(PX_ALLOC_TEMP(sizeof(PxU32)*nbTriangles, "tmp triangle indices")); LimitedResults limitedResults(results, nbTriangles, 0); Midphase::intersectBoxVsMesh(worldBox, *this, pose, scaling, &limitedResults); nbTriangles = limitedResults.mNbResults; if (fscale) { const PxU32 fcolor = PxU32(PxDebugColor::eARGB_DARKRED); for (PxU32 i=0; i<nbTriangles; i++) { const PxU32 index = results[i]; PxVec3 wp[3]; getTriangle(*this, index, 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(); out << midt << fcolor << Cm::DebugArrow(center, normal * fscale); } } if (mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_SHAPES)) { const PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA); out << midt << scolor; // PT: no need to output this for each segment! PxDebugLine* segments = out.reserveSegments(nbTriangles*3); for(PxU32 i=0; i<nbTriangles; i++) { const PxU32 index = results[i]; PxVec3 wp[3]; getTriangle(*this, index, wp, vertices, indices, absPose, has16BitIndices()); segments[0] = PxDebugLine(wp[0], wp[1], scolor); segments[1] = PxDebugLine(wp[1], wp[2], scolor); segments[2] = PxDebugLine(wp[2], wp[0], scolor); segments+=3; } } if ((mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_EDGES)) && mExtraTrigData) visualizeActiveEdges(out, *this, nbTriangles, results, absPose, midt); PX_FREE(results); } else { if (fscale) { const PxU32 fcolor = PxU32(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(); out << midt << fcolor << Cm::DebugArrow(center, normal * fscale); } } if (mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_SHAPES)) { PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA); out << midt << scolor; // PT: no need to output this for each segment! PxVec3* transformed = reinterpret_cast<PxVec3*>(PX_ALLOC(sizeof(PxVec3)*nbVertices, "PxVec3")); for(PxU32 i=0;i<nbVertices;i++) transformed[i] = absPose.transform(vertices[i]); PxDebugLine* segments = out.reserveSegments(nbTriangles*3); for (PxU32 i=0; i<nbTriangles; i++) { PxVec3 wp[3]; getTriangle(*this, i, wp, transformed, indices, has16BitIndices()); const PxU32 localMaterialIndex = getTriangleMaterialIndex(i); scolor = colors[localMaterialIndex % colorCount]; segments[0] = PxDebugLine(wp[0], wp[1], scolor); segments[1] = PxDebugLine(wp[1], wp[2], scolor); segments[2] = PxDebugLine(wp[2], wp[0], scolor); segments+=3; } PX_FREE(transformed); } if ((mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_EDGES)) && mExtraTrigData) visualizeActiveEdges(out, *this, nbTriangles, NULL, absPose, midt); } }
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]; } } } }