aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp
diff options
context:
space:
mode:
authorsschirm <[email protected]>2016-12-23 14:20:36 +0100
committersschirm <[email protected]>2016-12-23 14:56:17 +0100
commitef6937e69e8ee3f409cf9d460d5ad300a65d5924 (patch)
tree710426e8daa605551ce3f34b581897011101c30f /PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp
parentInitial commit: (diff)
downloadphysx-3.4-ef6937e69e8ee3f409cf9d460d5ad300a65d5924.tar.xz
physx-3.4-ef6937e69e8ee3f409cf9d460d5ad300a65d5924.zip
PhysX 3.4 / APEX 1.4 release candidate @21506124
Diffstat (limited to 'PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp')
-rw-r--r--PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp460
1 files changed, 444 insertions, 16 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp b/PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp
index ab2d6d8b..55eceec6 100644
--- a/PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp
+++ b/PhysX_3.4/Source/PhysX/src/NpShapeManager.cpp
@@ -31,7 +31,6 @@
#include "NpFactory.h"
#include "ScbRigidObject.h"
#include "NpActor.h"
-#include "SqSceneQueryManager.h"
#include "SqPruningStructure.h"
#include "NpScene.h"
#include "NpPtrTableStorageManager.h"
@@ -40,6 +39,8 @@
using namespace physx;
using namespace Sq;
+using namespace Gu;
+using namespace Cm;
namespace physx
{
@@ -63,7 +64,7 @@ NpShapeManager::NpShapeManager(const PxEMPTY) :
NpShapeManager::~NpShapeManager()
{
PX_ASSERT(!mPruningStructure);
- Cm::PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
+ PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
mShapes.clear(sm);
mSceneQueryData.clear(sm);
}
@@ -85,7 +86,7 @@ void NpShapeManager::attachShape(NpShape& shape, PxRigidActor& actor)
{
PX_ASSERT(!mPruningStructure);
- Cm::PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
+ PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
const PxU32 index = getNbShapes();
mShapes.add(&shape, sm);
@@ -106,7 +107,7 @@ void NpShapeManager::detachShape(NpShape& s, PxRigidActor& actor, bool wakeOnLos
{
PX_ASSERT(!mPruningStructure);
- Cm::PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
+ PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
const PxU32 index = mShapes.find(&s);
PX_ASSERT(index!=0xffffffff);
@@ -143,7 +144,7 @@ void NpShapeManager::detachAll(NpScene* scene)
for(PxU32 i=0;i<nbShapes;i++)
shapes[i]->onActorDetach();
- Cm::PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
+ PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();
mShapes.clear(sm);
mSceneQueryData.clear(sm);
@@ -151,7 +152,7 @@ void NpShapeManager::detachAll(NpScene* scene)
PxU32 NpShapeManager::getShapes(PxShape** buffer, PxU32 bufferSize, PxU32 startIndex) const
{
- return Cm::getArrayOfPointers(buffer, bufferSize, startIndex, getShapes(), getNbShapes());
+ return getArrayOfPointers(buffer, bufferSize, startIndex, getShapes(), getNbShapes());
}
PxBounds3 NpShapeManager::getWorldBounds(const PxRigidActor& actor) const
@@ -159,11 +160,11 @@ PxBounds3 NpShapeManager::getWorldBounds(const PxRigidActor& actor) const
PxBounds3 bounds(PxBounds3::empty());
const PxU32 nbShapes = getNbShapes();
- PxTransform actorPose = actor.getGlobalPose();
+ const PxTransform actorPose = actor.getGlobalPose();
NpShape*const* PX_RESTRICT shapes = getShapes();
for(PxU32 i=0;i<nbShapes;i++)
- bounds.include(Gu::computeBounds(shapes[i]->getScbShape().getGeometry(), actorPose * shapes[i]->getLocalPoseFast(), !physx::gUnifiedHeightfieldCollision));
+ bounds.include(Gu::computeBounds(shapes[i]->getScbShape().getGeometry(), actorPose * shapes[i]->getLocalPoseFast(), !gUnifiedHeightfieldCollision));
return bounds;
}
@@ -284,26 +285,453 @@ void NpShapeManager::teardownSceneQuery(SceneQueryManager& sqManager, PxU32 inde
}
#if PX_ENABLE_DEBUG_VISUALIZATION
-void NpShapeManager::visualize(Cm::RenderOutput& out, NpScene* scene, const PxRigidActor& actor)
+#include "GuHeightFieldUtil.h"
+#include "PxGeometryQuery.h"
+#include "PxMeshQuery.h"
+#include "GuConvexEdgeFlags.h"
+#include "GuMidphaseInterface.h"
+
+static const PxDebugColor::Enum gColors[] =
+{
+ 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,
+};
+
+static const PxU32 gColorCount = sizeof(gColors)/sizeof(PxDebugColor::Enum);
+
+static const PxU32 gCollisionShapeColor = PxU32(PxDebugColor::eARGB_MAGENTA);
+
+static void visualizeSphere(const PxSphereGeometry& geometry, RenderOutput& out, const PxTransform& absPose)
+{
+ out << gCollisionShapeColor; // PT: no need to output this for each segment!
+
+ out << absPose << DebugCircle(100, geometry.radius);
+
+ PxMat44 rotPose(absPose);
+ Ps::swap(rotPose.column1, rotPose.column2);
+ rotPose.column1 = -rotPose.column1;
+ out << rotPose << DebugCircle(100, geometry.radius);
+
+ Ps::swap(rotPose.column0, rotPose.column2);
+ rotPose.column0 = -rotPose.column0;
+ out << rotPose << DebugCircle(100, geometry.radius);
+}
+
+static void visualizePlane(const PxPlaneGeometry& /*geometry*/, RenderOutput& out, const PxTransform& absPose)
+{
+ PxMat44 rotPose(absPose);
+ Ps::swap(rotPose.column1, rotPose.column2);
+ rotPose.column1 = -rotPose.column1;
+
+ Ps::swap(rotPose.column0, rotPose.column2);
+ rotPose.column0 = -rotPose.column0;
+
+ out << rotPose << gCollisionShapeColor; // PT: no need to output this for each segment!
+ for(PxReal radius = 2.0f; radius < 20.0f ; radius += 2.0f)
+ out << DebugCircle(100, radius*radius);
+}
+
+static void visualizeCapsule(const PxCapsuleGeometry& geometry, RenderOutput& out, const PxTransform& absPose)
+{
+ out << gCollisionShapeColor;
+ out.outputCapsule(geometry.radius, geometry.halfHeight, absPose);
+}
+
+static void visualizeBox(const PxBoxGeometry& geometry, RenderOutput& out, const PxTransform& absPose)
+{
+ out << gCollisionShapeColor;
+ out << absPose << DebugBox(geometry.halfExtents);
+}
+
+static void visualizeConvexMesh(const PxConvexMeshGeometry& geometry, RenderOutput& out, const PxTransform& absPose)
+{
+ const ConvexMesh* convexMesh = static_cast<const ConvexMesh*>(geometry.convexMesh);
+ const ConvexHullData& hullData = convexMesh->getHull();
+
+ const PxVec3* vertices = hullData.getHullVertices();
+ const PxU8* indexBuffer = hullData.getVertexData8();
+ const PxU32 nbPolygons = convexMesh->getNbPolygonsFast();
+
+ const PxMat44 m44(PxMat33(absPose.q) * geometry.scale.toMat33(), absPose.p);
+
+ out << m44 << gCollisionShapeColor; // PT: no need to output this for each segment!
+
+ for(PxU32 i=0; i<nbPolygons; i++)
+ {
+ const PxU32 pnbVertices = hullData.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++)
+ {
+ const PxVec3 end = m44.transform(vertices[indexBuffer[j]]);
+ out.outputSegment(begin, end);
+ begin = end;
+ }
+ out.outputSegment(begin, m44.transform(vertices[indexBuffer[0]]));
+
+ indexBuffer += pnbVertices;
+ }
+}
+
+static void getTriangle(const Gu::TriangleMesh&, PxU32 i, PxVec3* wp, const PxVec3* vertices, const void* indices, bool has16BitIndices)
+{
+ PxU32 ref0, ref1, ref2;
+
+ if(!has16BitIndices)
+ {
+ const PxU32* dtriangles = reinterpret_cast<const PxU32*>(indices);
+ ref0 = dtriangles[i*3+0];
+ ref1 = dtriangles[i*3+1];
+ ref2 = dtriangles[i*3+2];
+ }
+ else
+ {
+ const PxU16* wtriangles = reinterpret_cast<const PxU16*>(indices);
+ ref0 = wtriangles[i*3+0];
+ ref1 = wtriangles[i*3+1];
+ ref2 = wtriangles[i*3+2];
+ }
+
+ wp[0] = vertices[ref0];
+ wp[1] = vertices[ref1];
+ wp[2] = vertices[ref2];
+}
+
+static void getTriangle(const Gu::TriangleMesh& mesh, PxU32 i, PxVec3* wp, const PxVec3* vertices, const void* indices, const Matrix34& absPose, bool has16BitIndices)
+{
+ PxVec3 localVerts[3];
+ getTriangle(mesh, i, localVerts, vertices, indices, has16BitIndices);
+
+ wp[0] = absPose.transform(localVerts[0]);
+ wp[1] = absPose.transform(localVerts[1]);
+ wp[2] = absPose.transform(localVerts[2]);
+}
+
+static void visualizeActiveEdges(RenderOutput& out, const Gu::TriangleMesh& mesh, PxU32 nbTriangles, const PxU32* results, const Matrix34& absPose)
+{
+ const PxU8* extraTrigData = mesh.getExtraTrigData();
+ PX_ASSERT(extraTrigData);
+
+ const PxVec3* vertices = mesh.getVerticesFast();
+ const void* indices = mesh.getTrianglesFast();
+
+ out << PxU32(PxDebugColor::eARGB_YELLOW); // PT: no need to output this for each segment!
+
+ const bool has16Bit = mesh.has16BitIndices();
+ for(PxU32 i=0; i<nbTriangles; i++)
+ {
+ const PxU32 index = results ? results[i] : i;
+
+ PxVec3 wp[3];
+ getTriangle(mesh, index, wp, vertices, indices, absPose, has16Bit);
+
+ const PxU32 flags = extraTrigData[index];
+
+ if(flags & Gu::ETD_CONVEX_EDGE_01)
+ out.outputSegment(wp[0], wp[1]);
+
+ if(flags & Gu::ETD_CONVEX_EDGE_12)
+ out.outputSegment(wp[1], wp[2]);
+
+ if(flags & Gu::ETD_CONVEX_EDGE_20)
+ out.outputSegment(wp[0], wp[2]);
+ }
+}
+
+static void visualizeFaceNormals( PxReal fscale, RenderOutput& out, const TriangleMesh& mesh, PxU32 nbTriangles, const PxVec3* vertices,
+ const void* indices, bool has16Bit, const PxU32* results, const Matrix34& absPose, const PxMat44& midt)
+{
+ if(fscale==0.0f)
+ return;
+
+ out << midt << PxU32(PxDebugColor::eARGB_DARKRED); // PT: no need to output this for each segment!
+
+ for(PxU32 i=0; i<nbTriangles; i++)
+ {
+ const PxU32 index = results ? results[i] : i;
+ PxVec3 wp[3];
+ getTriangle(mesh, index, wp, vertices, indices, absPose, has16Bit);
+
+ 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 << DebugArrow(center, normal * fscale);
+ }
+}
+
+static PX_FORCE_INLINE void outputTriangle(PxDebugLine* segments, const PxVec3& v0, const PxVec3& v1, const PxVec3& v2, PxU32 color)
+{
+ // PT: TODO: use SIMD
+ segments[0] = PxDebugLine(v0, v1, color);
+ segments[1] = PxDebugLine(v1, v2, color);
+ segments[2] = PxDebugLine(v2, v0, color);
+}
+
+static void visualizeTriangleMesh(const PxTriangleMeshGeometry& geometry, RenderOutput& out, const PxTransform& pose, const PxBounds3& cullbox, const PxReal fscale, bool visualizeShapes, bool visualizeEdges, bool useCullBox)
+{
+ const TriangleMesh* triangleMesh = static_cast<const TriangleMesh*>(geometry.triangleMesh);
+
+ const PxMat44 midt(PxIdentity);
+ const Matrix34 absPose(PxMat33(pose.q) * geometry.scale.toMat33(), pose.p);
+
+ PxU32 nbTriangles = triangleMesh->getNbTrianglesFast();
+ const PxU32 nbVertices = triangleMesh->getNbVerticesFast();
+ const PxVec3* vertices = triangleMesh->getVerticesFast();
+ const void* indices = triangleMesh->getTrianglesFast();
+ const bool has16Bit = triangleMesh->has16BitIndices();
+
+ // PT: TODO: don't render the same edge multiple times
+
+ PxU32* results = NULL;
+ if(useCullBox)
+ {
+ 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
+ results = reinterpret_cast<PxU32*>(PX_ALLOC_TEMP(sizeof(PxU32)*nbTriangles, "tmp triangle indices"));
+ LimitedResults limitedResults(results, nbTriangles, 0);
+ Midphase::intersectBoxVsMesh(worldBox, *triangleMesh, pose, geometry.scale, &limitedResults);
+ nbTriangles = limitedResults.mNbResults;
+
+ if(visualizeShapes)
+ {
+ const PxU32 scolor = gCollisionShapeColor;
+
+ 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++)
+ {
+ PxVec3 wp[3];
+ getTriangle(*triangleMesh, results[i], wp, vertices, indices, absPose, has16Bit);
+ outputTriangle(segments, wp[0], wp[1], wp[2], scolor);
+ segments+=3;
+ }
+ }
+ }
+ else
+ {
+ if(visualizeShapes)
+ {
+ PxU32 scolor = gCollisionShapeColor;
+
+ out << midt << scolor; // PT: no need to output this for each segment!
+
+ // PT: TODO: use SIMD
+ 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(*triangleMesh, i, wp, transformed, indices, has16Bit);
+ const PxU32 localMaterialIndex = triangleMesh->getTriangleMaterialIndex(i);
+ // PT: TODO: I doubt this is correct. "localMaterialIndex" will be 0xffff for most meshes so
+ // the color we pick is basically random. Also, get rid of these modulos (==divisions)
+ scolor = gColors[localMaterialIndex % gColorCount];
+
+ outputTriangle(segments, wp[0], wp[1], wp[2], scolor);
+ segments+=3;
+ }
+
+ PX_FREE(transformed);
+ }
+ }
+
+ visualizeFaceNormals(fscale, out, *triangleMesh, nbTriangles, vertices, indices, has16Bit, results, absPose, midt);
+
+ if(visualizeEdges && triangleMesh->getExtraTrigData())
+ visualizeActiveEdges(out, *triangleMesh, nbTriangles, results, absPose);
+
+ if(results)
+ PX_FREE(results);
+}
+
+static void visualizeHeightField(const PxHeightFieldGeometry& hfGeometry, RenderOutput& out, const PxTransform& absPose, const PxBounds3& cullbox, bool useCullBox)
{
+ const HeightField* heightfield = static_cast<const HeightField*>(hfGeometry.heightField);
+
+ // PT: TODO: the debug viz for HFs is minimal at the moment...
+ // PT: TODO: REALLY? all shapes use magenta but HFs use yellow?
+ PxU32 scolor = PxU32(PxDebugColor::eARGB_YELLOW);
+ const PxMat44 midt = PxMat44(PxIdentity);
+
+ HeightFieldUtil hfUtil(hfGeometry);
+
+ const PxU32 nbRows = heightfield->getNbRowsFast();
+ const PxU32 nbColumns = heightfield->getNbColumnsFast();
+ const PxU32 nbVerts = nbRows * nbColumns;
+ const PxU32 nbTriangles = 2 * nbVerts;
+
+ out << midt << scolor; // PT: no need to output the same matrix/color for each triangle
+
+ if(useCullBox)
+ {
+ const PxTransform pose0((cullbox.maximum + cullbox.minimum)*0.5f);
+ const PxBoxGeometry boxGeometry((cullbox.maximum - cullbox.minimum)*0.5f);
+
+ PxU32* results = reinterpret_cast<PxU32*>(PX_ALLOC(sizeof(PxU32)*nbTriangles, "tmp triangle indices"));
+
+ bool overflow = false;
+ PxU32 nbTouchedTris = PxMeshQuery::findOverlapHeightField(boxGeometry, pose0, hfGeometry, absPose, results, nbTriangles, 0, overflow);
+
+ PxDebugLine* segments = out.reserveSegments(nbTouchedTris*3);
+
+ for(PxU32 i=0; i<nbTouchedTris; i++)
+ {
+ const PxU32 index = results[i];
+ PxTriangle currentTriangle;
+ PxMeshQuery::getTriangle(hfGeometry, absPose, index, currentTriangle);
+
+ //The check has been done in the findOverlapHeightField
+ //if(heightfield->isValidTriangle(index) && heightfield->getTriangleMaterial(index) != PxHeightFieldMaterial::eHOLE)
+ {
+ const PxU16 localMaterialIndex = heightfield->getTriangleMaterialIndex(index);
+ // PT: TODO: optimize away modulos/divisions
+ scolor = gColors[localMaterialIndex % gColorCount];
+
+ outputTriangle(segments, currentTriangle.verts[0], currentTriangle.verts[1], currentTriangle.verts[2], scolor);
+ segments+=3;
+ }
+ }
+ PX_FREE(results);
+ }
+ else
+ {
+ // PT: transform vertices only once
+ PxVec3* tmpVerts = reinterpret_cast<PxVec3*>(PX_ALLOC(sizeof(PxVec3)*nbVerts, "PxVec3"));
+ // PT: TODO: optimize the following line
+ for(PxU32 i=0;i<nbVerts;i++)
+ tmpVerts[i] = absPose.transform(hfUtil.hf2shapep(heightfield->getVertex(i)));
+
+ for(PxU32 i=0; i<nbTriangles; i++)
+ {
+ // PT: TODO: optimize away the useless divisions/modulos in the lines below
+ if(heightfield->isValidTriangle(i) && heightfield->getTriangleMaterial(i) != PxHeightFieldMaterial::eHOLE)
+ {
+ PxU32 vi0, vi1, vi2;
+ heightfield->getTriangleVertexIndices(i, vi0, vi1, vi2);
+ const PxU16 localMaterialIndex = heightfield->getTriangleMaterialIndex(i);
+
+ PxDebugLine* segments = out.reserveSegments(3);
+ outputTriangle(segments, tmpVerts[vi0], tmpVerts[vi1], tmpVerts[vi2], gColors[localMaterialIndex % gColorCount]);
+ }
+ }
+ PX_FREE(tmpVerts);
+ }
+}
+
+static void visualize(const PxGeometry& geometry, RenderOutput& out, const PxTransform& absPose, const PxBounds3& cullbox, const PxReal fscale, bool visualizeShapes, bool visualizeEdges, bool useCullBox)
+{
+ // triangle meshes can render active edges or face normals, but for other types we can just early out if there are no collision shapes
+ if(!visualizeShapes && geometry.getType() != PxGeometryType::eTRIANGLEMESH)
+ return;
+
+ switch(geometry.getType())
+ {
+ case PxGeometryType::eSPHERE:
+ visualizeSphere(static_cast<const PxSphereGeometry&>(geometry), out, absPose);
+ break;
+ case PxGeometryType::eBOX:
+ visualizeBox(static_cast<const PxBoxGeometry&>(geometry), out, absPose);
+ break;
+ case PxGeometryType::ePLANE:
+ visualizePlane(static_cast<const PxPlaneGeometry&>(geometry), out, absPose);
+ break;
+ case PxGeometryType::eCAPSULE:
+ visualizeCapsule(static_cast<const PxCapsuleGeometry&>(geometry), out, absPose);
+ break;
+ case PxGeometryType::eCONVEXMESH:
+ visualizeConvexMesh(static_cast<const PxConvexMeshGeometry&>(geometry), out, absPose);
+ break;
+ case PxGeometryType::eTRIANGLEMESH:
+ visualizeTriangleMesh(static_cast<const PxTriangleMeshGeometry&>(geometry), out, absPose, cullbox, fscale, visualizeShapes, visualizeEdges, useCullBox);
+ break;
+ case PxGeometryType::eHEIGHTFIELD:
+ visualizeHeightField(static_cast<const PxHeightFieldGeometry&>(geometry), out, absPose, cullbox, useCullBox);
+ break;
+ case PxGeometryType::eINVALID:
+ break;
+ case PxGeometryType::eGEOMETRY_COUNT:
+ break;
+ }
+}
+
+void NpShapeManager::visualize(RenderOutput& out, NpScene* scene, const PxRigidActor& actor)
+{
+ const PxReal scale = scene->getVisualizationParameter(PxVisualizationParameter::eSCALE);
+ if(!scale)
+ return;
+
const PxU32 nbShapes = getNbShapes();
NpShape*const* PX_RESTRICT shapes = getShapes();
- PxTransform actorPose = actor.getGlobalPose();
const bool visualizeCompounds = (nbShapes>1) && scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_COMPOUNDS)!=0.0f;
+ // PT: moved all these out of the loop, no need to grab them once per shape
+ const bool visualizeAABBs = scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_AABBS)!=0.0f;
+ const bool visualizeShapes = scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES)!=0.0f;
+ const bool visualizeEdges = scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_EDGES)!=0.0f;
+ const float fNormals = scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_FNORMALS);
+ const bool visualizeFNormals = fNormals!=0.0f;
+ const bool visualizeCollision = visualizeShapes || visualizeFNormals || visualizeEdges;
+ const bool useCullBox = scene->getVisualizationParameter(PxVisualizationParameter::eCULL_BOX)!=0.0f;
+ const bool needsShapeBounds0 = visualizeCompounds || (visualizeCollision && useCullBox);
+ const PxReal collisionAxes = scale * scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_AXES);
+ const PxReal fscale = scale * fNormals;
+ const PxBounds3& cullbox = scene->getScene().getVisualizationCullingBox();
+
+ const PxTransform actorPose = actor.getGlobalPose();
+
PxBounds3 compoundBounds(PxBounds3::empty());
for(PxU32 i=0;i<nbShapes;i++)
{
- Scb::Shape& shape = shapes[i]->getScbShape();
- if(shape.getFlags() & PxShapeFlag::eVISUALIZATION)
+ const Scb::Shape& scbShape = shapes[i]->getScbShape();
+
+ const PxTransform absPose = actorPose * scbShape.getShape2Actor();
+ const PxGeometry& geom = scbShape.getGeometry();
+
+ const bool shapeDebugVizEnabled = scbShape.getFlags() & PxShapeFlag::eVISUALIZATION;
+
+ const bool needsShapeBounds = needsShapeBounds0 || (visualizeAABBs && shapeDebugVizEnabled);
+ const PxBounds3 currentShapeBounds = needsShapeBounds ? Gu::computeBounds(geom, absPose, !gUnifiedHeightfieldCollision) : PxBounds3::empty();
+
+ if(shapeDebugVizEnabled)
{
- shapes[i]->visualize(out, actor);
- if(visualizeCompounds)
- compoundBounds.include(Gu::computeBounds(shape.getGeometry(), actorPose*shapes[i]->getLocalPose(), !physx::gUnifiedHeightfieldCollision));
+ if(visualizeAABBs)
+ out << PxU32(PxDebugColor::eARGB_YELLOW) << PxMat44(PxIdentity) << DebugBox(currentShapeBounds);
+
+ if(collisionAxes != 0.0f)
+ out << PxMat44(absPose) << DebugBasis(PxVec3(collisionAxes), 0xcf0000, 0x00cf00, 0x0000cf);
+
+ if(visualizeCollision)
+ {
+ if(!useCullBox || cullbox.intersects(currentShapeBounds))
+ ::visualize(geom, out, absPose, cullbox, fscale, visualizeShapes, visualizeEdges, useCullBox);
+ }
}
+
+ if(visualizeCompounds)
+ compoundBounds.include(currentShapeBounds);
}
if(visualizeCompounds && !compoundBounds.isEmpty())
- out << PxU32(PxDebugColor::eARGB_MAGENTA) << PxMat44(PxIdentity) << Cm::DebugBox(compoundBounds);
+ out << gCollisionShapeColor << PxMat44(PxIdentity) << DebugBox(compoundBounds);
}
#endif // PX_ENABLE_DEBUG_VISUALIZATION