diff --git a/DebugView/ConvexDecomposition.exe b/DebugView/ConvexDecomposition.exe index 30977d47..5b4505fa 100644 Binary files a/DebugView/ConvexDecomposition.exe and b/DebugView/ConvexDecomposition.exe differ diff --git a/DebugView/NvRenderDebug/NvRenderDebug.h b/DebugView/NvRenderDebug/NvRenderDebug.h index cbb4a0fb..1582b050 100644 --- a/DebugView/NvRenderDebug/NvRenderDebug.h +++ b/DebugView/NvRenderDebug/NvRenderDebug.h @@ -17,16 +17,21 @@ /** \brief This defines the version number of the API. If the API changes in anyway, this version number needs to be bumped. */ -#define RENDER_DEBUG_VERSION 1009 +#define RENDER_DEBUG_VERSION 1010 /** \brief This defines the version number for the communications layer. If the format or layout of any packets change in a way that will not be backwards compatible, this needs to be bumped */ -#define RENDER_DEBUG_COMM_VERSION 1009 +#define RENDER_DEBUG_COMM_VERSION 1010 /** \brief The default port number for RenderDebug client/server connections. You can change this if you wish, but you must make sure both your client and server code uses the new port number. */ #define RENDER_DEBUG_PORT 5525 +namespace nvidia +{ + class NvAllocatorCallback; + class NvErrorCallback; +} namespace RENDER_DEBUG { @@ -897,7 +902,7 @@ class RenderDebug dllName = "RenderDebug_x86.dll"; versionNumber = RENDER_DEBUG_VERSION; runMode = RM_LOCAL; - recordFileName = nullptr; //"RenderDebug.rec"; + recordFileName = NULL; //"RenderDebug.rec"; errorCode = 0; echoFileLocally = false; hostName = "localhost"; @@ -973,12 +978,12 @@ class RenderDebug /** \brief This is an optional callback interface to vector all memory allocations performed back to the application. */ - void *allocatorCallback; + nvidia::NvAllocatorCallback *allocatorCallback; /** \brief This is an optional callback interface to vector all warning and error messages back to the application */ - void *errorCallback; + nvidia::NvErrorCallback *errorCallback; /** \brief This is an optional filename to record all commands received from the remote connection. This is a debugging feature only. diff --git a/DebugView/NvRenderDebug/NvRenderDebugBinding.cpp b/DebugView/NvRenderDebug/NvRenderDebugBinding.cpp index 5be6e0a6..1210089c 100644 --- a/DebugView/NvRenderDebug/NvRenderDebugBinding.cpp +++ b/DebugView/NvRenderDebug/NvRenderDebugBinding.cpp @@ -1,10 +1,20 @@ #include "NvRenderDebug.h" #include +#if NV_SIGNED_LIBRARY +#undef NV_SIGNED_LIBRARY +#endif + #ifdef _MSC_VER #include +#ifdef NV_SIGNED_LIBRARY +#include "nvSecureLoadLibrary.h" +#endif + + + namespace RENDER_DEBUG { @@ -15,7 +25,11 @@ RENDER_DEBUG::RenderDebug *createRenderDebug(RenderDebug::Desc &desc) UINT errorMode = 0; errorMode = SEM_FAILCRITICALERRORS; UINT oldErrorMode = SetErrorMode(errorMode); +#ifdef NV_SIGNED_LIBRARY + HMODULE module = nvLoadLibraryExA(desc.dllName,0,true); +#else HMODULE module = LoadLibraryA(desc.dllName); +#endif SetErrorMode(oldErrorMode); if ( module ) { diff --git a/DebugView/NvRenderDebug_x64.dll b/DebugView/NvRenderDebug_x64.dll index 6ec28fdb..f74dbf2c 100644 Binary files a/DebugView/NvRenderDebug_x64.dll and b/DebugView/NvRenderDebug_x64.dll differ diff --git a/DebugView/PhysXFramework/NvPhysXFramework.h b/DebugView/PhysXFramework/NvPhysXFramework.h index 412f53e6..f58a9472 100644 --- a/DebugView/PhysXFramework/NvPhysXFramework.h +++ b/DebugView/PhysXFramework/NvPhysXFramework.h @@ -79,6 +79,14 @@ class PhysXFramework uint32_t swing2Limit) = 0; // Swing 2 limit in degrees (if used) virtual bool getXform(float xform[16],uint32_t index) = 0; + virtual bool getConstraintXform(float xform[16], uint32_t constraint) = 0; + + // If we are mouse dragging and the currently selected object is an actor in this compound + // system, then return true and assign 'bodyIndex' to the index number of the body selected. + virtual bool getSelectedBody(uint32_t &bodyIndex) = 0; + + // Sets the collision filter pairs. + virtual void setCollisionFilterPairs(uint32_t pairCount, const uint32_t *collisionPairs) = 0; virtual void release(void) = 0; }; diff --git a/DebugView/PhysXFramework64.dll b/DebugView/PhysXFramework64.dll index 599fed86..92512bd6 100644 Binary files a/DebugView/PhysXFramework64.dll and b/DebugView/PhysXFramework64.dll differ diff --git a/DebugView/TestHACD.cpp b/DebugView/TestHACD.cpp index d27ceb14..b0b995a8 100644 --- a/DebugView/TestHACD.cpp +++ b/DebugView/TestHACD.cpp @@ -26,8 +26,6 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi { mHACD->Release(); releaseSimulationObjects(); - delete[]mIndices; - delete[]mVertices; } void getExplodePosition(const double source[3], float dest[3], const double diff[3],const float center[3]) @@ -37,77 +35,30 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi dest[2] = float(source[2] + diff[2] + center[2]); } - void getExplodePosition(const float source[3], float dest[3], const double diff[3], const float center[3]) + virtual void render(float explodeViewScale,const float center[3],bool wireframe) final { - dest[0] = float(source[0] + diff[0] + center[0]); - dest[1] = float(source[1] + diff[1] + center[1]); - dest[2] = float(source[2] + diff[2] + center[2]); - } - - void getExplodeViewPosition(const float center[3], const VHACD::IVHACD::ConvexHull &h, float explodeViewScale, const double sourcePos[3], float destPos[3]) - { - double diff[3]; - - diff[0] = h.m_center[0] - center[0]; - diff[1] = h.m_center[1] - center[1]; - diff[2] = h.m_center[2] - center[2]; - - diff[0] *= explodeViewScale; - diff[1] *= explodeViewScale; - diff[2] *= explodeViewScale; - - diff[0] -= h.m_center[0]; - diff[1] -= h.m_center[1]; - diff[2] -= h.m_center[2]; - - getExplodePosition(sourcePos, destPos, diff, center); - } - - virtual void render(float explodeViewScale, - const float center[3], - bool wireframe, - bool showConstraints, - bool showSkeleton, - bool showCollisionPairs) final - { - // We can't currently do the visualization if we are doing a full ragdoll simulation - // while simulating; so don't try - if (mSimulateAsRagdoll && isSimulating()) - { - return; - } uint32_t hullCount = mHACD->GetNConvexHulls(); if (hullCount) { - if (!mHaveConstraints) - { - mHaveConstraints = true; - mHACD->ComputeConstraints(); - } mRenderDebug->pushRenderState(); float xform[16]; getTransform(xform); mRenderDebug->setPose(xform); - - // Render constraints here... - uint32_t constraintCount; - const VHACD::IVHACD::Constraint *constraints = mHACD->GetConstraints(constraintCount); - for (uint32_t j = 0; j < hullCount; j++) { VHACD::IVHACD::ConvexHull h; mHACD->GetConvexHull(j, h); { - if (wireframe) - { - mRenderDebug->removeFromCurrentState(RENDER_DEBUG::DebugRenderState::SolidShaded); - mRenderDebug->removeFromCurrentState(RENDER_DEBUG::DebugRenderState::SolidWireShaded); - } - else - { - mRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::SolidWireShaded); - } + if (wireframe) + { + mRenderDebug->removeFromCurrentState(RENDER_DEBUG::DebugRenderState::SolidShaded); + mRenderDebug->removeFromCurrentState(RENDER_DEBUG::DebugRenderState::SolidWireShaded); + } + else + { + mRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::SolidWireShaded); + } uint32_t cindex = (j % 20) + RENDER_DEBUG::DebugColors::Red; @@ -148,100 +99,8 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi mRenderDebug->debugTri(v1, v2, v3); } - - if (constraints && showConstraints) - { - mRenderDebug->pushRenderState(); - for (uint32_t i = 0; i < constraintCount; i++) - { - const VHACD::IVHACD::Constraint &c = constraints[i]; - if (c.mHullA == j) - { - float p1[3]; - FLOAT_MATH::fm_doubleToFloat3(c.mConstraintPoint, p1); - float quat[4]; - quat[0] = float(c.mConstraintOrientation[0]); - quat[1] = float(c.mConstraintOrientation[1]); - quat[2] = float(c.mConstraintOrientation[2]); - quat[3] = float(c.mConstraintOrientation[3]); - float transform[16]; - FLOAT_MATH::fm_quatToMatrix(quat, transform); - transform[12] = p1[0]; - transform[13] = p1[1]; - transform[14] = p1[2]; - float p2[3]; - float basis[3] = { 1.5f, 0, 0, }; - FLOAT_MATH::fm_transform(transform, basis, p2); - float v1[3]; - float v2[3]; - getExplodePosition(p1, v1, diff, center); - getExplodePosition(p2, v2, diff, center); - mRenderDebug->debugThickRay(v1, v2, 0.01f); - mRenderDebug->setCurrentColor(0xFF00FF); - mRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::SolidShaded); - mRenderDebug->debugSphere(v1, 0.02f); - } - } - mRenderDebug->popRenderState(); - } - } - } - if (showSkeleton) - { - for (uint32_t i = 0; i < constraintCount; i++) - { - const VHACD::IVHACD::Constraint &c = constraints[i]; - VHACD::IVHACD::ConvexHull h1, h2; - - mHACD->GetConvexHull(c.mHullA, h1); - mHACD->GetConvexHull(c.mHullB, h2); - - float p1[3]; - float p2[3]; - - getExplodeViewPosition(center, h1, explodeViewScale, h1.m_center, p1); - getExplodeViewPosition(center, h2, explodeViewScale, h2.m_center, p2); - - mRenderDebug->pushRenderState(); - mRenderDebug->setCurrentColor(0xFFFF00); - mRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::SolidShaded); - mRenderDebug->debugSphere(p1, 0.1f); - mRenderDebug->debugSphere(p2, 0.1f); - mRenderDebug->debugThickRay(p1, p2, 0.02f); - mRenderDebug->popRenderState(); - } - } - if (showCollisionPairs) - { - uint32_t collisionCount; - const uint32_t *pairs = mHACD->GetCollisionFilterPairs(collisionCount); - for (uint32_t i = 0; i < collisionCount; i++) - { - uint32_t hulla = pairs[i * 2]; - uint32_t hullb = pairs[i * 2 + 1]; - - VHACD::IVHACD::ConvexHull h1, h2; - - mHACD->GetConvexHull(hulla, h1); - mHACD->GetConvexHull(hullb, h2); - - float p1[3]; - float p2[3]; - - getExplodeViewPosition(center, h1, explodeViewScale, h1.m_center, p1); - getExplodeViewPosition(center, h2, explodeViewScale, h2.m_center, p2); - - mRenderDebug->pushRenderState(); - mRenderDebug->setCurrentColor(0xFF0000); - mRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::SolidShaded); - mRenderDebug->debugSphere(p1, 0.1f); - mRenderDebug->debugSphere(p2, 0.1f); - mRenderDebug->debugThickRay(p1, p2, 0.02f); - mRenderDebug->popRenderState(); - } } - mRenderDebug->popRenderState(); } else @@ -262,7 +121,6 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi { desc.m_callback = this; desc.m_logger = this; - mHaveConstraints = false; // clear have constraints flag so they will be recomputed when the decomopsition is complete mHACD->Compute(points, countPoints, triangles, countTriangles, desc); } @@ -301,31 +159,6 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi return mHACD ? mHACD->GetNConvexHulls() : 0; } - virtual uint32_t getConstraintCount(void) const final - { - uint32_t ret = 0; - - if (mHACD) - { - mHACD->GetConstraints(ret); - } - - return ret; - } - - virtual uint32_t getCollisionFilterCount(void) const final - { - uint32_t ret = 0; - - if (mHACD) - { - mHACD->GetCollisionFilterPairs(ret); - } - - return ret; - } - - virtual void cancel(void) { if (mHACD) @@ -384,14 +217,8 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi } } - virtual void toggleSimulation(bool simulateAsRagdoll, - NV_PHYSX_FRAMEWORK::ConstraintType ctype, - float limitDistance, - uint32_t twistLimit, // Twist limit in degrees (if used) - uint32_t swing1Limit, // Swing 1 limit in degrees (if used) - uint32_t swing2Limit) final // Swing 2 limit in degrees (if used) + virtual void toggleSimulation(void) { - mSimulateAsRagdoll = simulateAsRagdoll; if (mCompoundActor) { releaseSimulationObjects(); @@ -434,29 +261,7 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi mCenterOfMass[0] = float(centerOfMass[0]); mCenterOfMass[1] = float(centerOfMass[1]); mCenterOfMass[2] = float(centerOfMass[2]); - mCompoundActor->createActor(mCenterOfMass,DEFAULT_MASS,simulateAsRagdoll); - if (simulateAsRagdoll) - { - uint32_t constraintCount; - const VHACD::IVHACD::Constraint *constraints = mHACD->GetConstraints(constraintCount); - if (constraints) - { - for (uint32_t i = 0; i < constraintCount; i++) - { - const VHACD::IVHACD::Constraint &c = constraints[i]; - float pos[3]; - float rot[4]; - pos[0] = float(c.mConstraintPoint[0]); - pos[1] = float(c.mConstraintPoint[1]); - pos[2] = float(c.mConstraintPoint[2]); - rot[0] = float(c.mConstraintOrientation[0]); - rot[1] = float(c.mConstraintOrientation[1]); - rot[2] = float(c.mConstraintOrientation[2]); - rot[3] = float(c.mConstraintOrientation[3]); - mCompoundActor->createConstraint(c.mHullA, c.mHullB, pos, rot, ctype, limitDistance, twistLimit, swing1Limit, swing2Limit); - } - } - } + mCompoundActor->createActor(mCenterOfMass, DEFAULT_MASS, false); } } } @@ -487,39 +292,10 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi FLOAT_MATH::fm_identity(xform); if (mCompoundActor) { - mCompoundActor->getXform(xform,0); + mCompoundActor->getXform(xform, 0); } } - void computeConstraints(void) - { - if (mHACD) - { - mHACD->ComputeConstraints(); - } - } - - virtual bool isSimulating(void) const - { - return mCompoundActor ? true : false; - } - - virtual void setRenderMesh(uint32_t vcount, - const float *vertices, - uint32_t tcount, - const uint32_t *indices) - { - delete[]mIndices; - delete[]mVertices; - mVertexCount = vcount; - mTriangleCount = tcount; - mVertices = new float[vcount * 3]; - mIndices = new uint32_t[tcount * 3]; - memcpy(mVertices,vertices, sizeof(float)*vcount * 3); - memcpy(mIndices,indices, sizeof(uint32_t)*tcount * 3); - } - - bool mSimulateAsRagdoll{ false }; uint32_t mConvexMeshCount{ 0 }; NV_PHYSX_FRAMEWORK::PhysXFramework::ConvexMesh **mConvexMeshes{ nullptr }; NV_PHYSX_FRAMEWORK::PhysXFramework::CompoundActor *mCompoundActor{ nullptr }; @@ -532,12 +308,6 @@ class TestHACDImpl : public TestHACD, public VHACD::IVHACD::IUserCallback, publi std::string mStage; std::string mOperation; float mCenterOfMass[3]; - bool mHaveConstraints{ false }; - // Render mesh.... - uint32_t mVertexCount{ 0 }; - uint32_t mTriangleCount{ 0 }; - float *mVertices{ nullptr }; - uint32_t *mIndices{ nullptr }; }; TestHACD *TestHACD::create(RENDER_DEBUG::RenderDebug *renderDebug,NV_PHYSX_FRAMEWORK::PhysXFramework *pf) diff --git a/DebugView/TestHACD.h b/DebugView/TestHACD.h index d384d3d0..6886980c 100644 --- a/DebugView/TestHACD.h +++ b/DebugView/TestHACD.h @@ -12,7 +12,6 @@ namespace RENDER_DEBUG namespace NV_PHYSX_FRAMEWORK { class PhysXFramework; - enum ConstraintType; } class TestHACD @@ -21,12 +20,7 @@ class TestHACD static TestHACD *create(RENDER_DEBUG::RenderDebug *renderDebug,NV_PHYSX_FRAMEWORK::PhysXFramework *physxFramework); - virtual void toggleSimulation(bool simulateAsRagdoll, - NV_PHYSX_FRAMEWORK::ConstraintType ctype, - float limitDistance, - uint32_t twistLimit, // Twist limit in degrees (if used) - uint32_t swing1Limit, // Swing 1 limit in degrees (if used) - uint32_t swing2Limit) = 0; // Swing 2 limit in degrees (if used) + virtual void toggleSimulation(void) = 0; virtual void decompose( const double* const points, @@ -35,30 +29,16 @@ class TestHACD const uint32_t countTriangles, VHACD::IVHACD::Parameters &desc) = 0; - virtual void render(float explodeViewScale, - const float center[3], - bool wireframe, - bool showConstraints, - bool showSkeleton, - bool showCollisionPairs) = 0; + virtual void render(float explodeViewScale,const float center[3],bool wireframe) = 0; virtual void getTransform(float xform[16]) = 0; virtual uint32_t getHullCount(void) const = 0; - virtual uint32_t getConstraintCount(void) const = 0; - virtual uint32_t getCollisionFilterCount(void) const = 0; virtual void saveConvexDecomposition(const char *fname,const char *sourceMeshName) = 0; - virtual bool isSimulating(void) const = 0; - virtual void cancel(void) = 0; - virtual void setRenderMesh(uint32_t vcount, - const float *vertices, - uint32_t tcount, - const uint32_t *indices) = 0; - virtual void release(void) = 0; protected: virtual ~TestHACD(void) diff --git a/DebugView/main.cpp b/DebugView/main.cpp index 1d90f08a..7d2ab9ec 100644 --- a/DebugView/main.cpp +++ b/DebugView/main.cpp @@ -27,7 +27,6 @@ static bool gShowSourceMesh = true; static bool gShowConvexDecomposition = true; static bool gUseHACD = true; static float gScaleInputMesh = 1; -static uint32_t gTessellateInputMesh = 1; static float gExplodeViewScale = 1; static float gCenter[3] { 0, 0, 0 }; static uint32_t gVertexCount = 0; @@ -38,6 +37,45 @@ static std::string gSourceMeshName; static VHACD::IVHACD::Parameters gDesc; +float fm_computePlane(const float *A,const float *B,const float *C,float *n) // returns D +{ + float vx = (B[0] - C[0]); + float vy = (B[1] - C[1]); + float vz = (B[2] - C[2]); + + float wx = (A[0] - B[0]); + float wy = (A[1] - B[1]); + float wz = (A[2] - B[2]); + + float vw_x = vy * wz - vz * wy; + float vw_y = vz * wx - vx * wz; + float vw_z = vx * wy - vy * wx; + + float mag = ::sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + + if ( mag < 0.000001f ) + { + mag = 0; + } + else + { + mag = 1.0f/mag; + } + + float x = vw_x * mag; + float y = vw_y * mag; + float z = vw_z * mag; + + + float D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2])); + + n[0] = x; + n[1] = y; + n[2] = z; + + return D; +} + class MeshBuilder { public: @@ -67,7 +105,7 @@ class MeshBuilder void addTriangle(const float *p1,const float *p2,const float *p3) { float normal[3]; - FLOAT_MATH::fm_computePlane(p3,p2,p1,normal); + fm_computePlane(p3,p2,p1,normal); double nx = fabs(normal[0]); double ny = fabs(normal[1]); @@ -163,12 +201,12 @@ void createMenus(void) gRenderDebug->sendRemoteCommand("BeginGroup \"View\""); // Mark the beginning of a group of controls. gRenderDebug->sendRemoteCommand("CheckBox ShowSourceMesh true ShowSourceMesh"); gRenderDebug->sendRemoteCommand("CheckBox ShowConvexDecomposition true ShowConvexDecomposition"); - gRenderDebug->sendRemoteCommand("CheckBox WireframeSourceMesh false WireframeSourceMesh"); gRenderDebug->sendRemoteCommand("CheckBox WireframeConvex false WireframeConvex"); gRenderDebug->sendRemoteCommand("CheckBox ShowPhysics true ShowPhysics"); gRenderDebug->sendRemoteCommand("Slider ScaleInputMesh 1 0.01 100 ScaleInputMesh"); - gRenderDebug->sendRemoteCommand("SliderInt TessellateInputMesh 1 1 100 TessellateInputMesh"); gRenderDebug->sendRemoteCommand("Slider ExplodeViewScale 1 1 4 ExplodeViewScale"); + gRenderDebug->sendRemoteCommand("Button PerformConvexDecomposition decomp"); + gRenderDebug->sendRemoteCommand("Button Cancel \"cancel\""); gRenderDebug->sendRemoteCommand("EndGroup"); // End the group called 'controls' @@ -176,8 +214,6 @@ void createMenus(void) gRenderDebug->sendRemoteCommand("SliderInt MaxHullVertices 32 8 512 MaxHullVertices"); gRenderDebug->sendRemoteCommand("SliderInt MaxConvexHulls 32 1 512 MaxConvexHulls"); gRenderDebug->sendRemoteCommand("Slider Concavity 0.001 0 0.1 Concavity"); - gRenderDebug->sendRemoteCommand("Button PerformConvexDecomposition decomp"); - gRenderDebug->sendRemoteCommand("Button Cancel \"cancel\""); gRenderDebug->sendRemoteCommand("EndGroup"); // End the group called 'HACD settings' gRenderDebug->sendRemoteCommand("BeginGroup \"V-HACD Settings2\""); // Mark the beginning of a group of controls. @@ -188,12 +224,6 @@ void createMenus(void) gRenderDebug->sendRemoteCommand("EndGroup"); // End the group called 'HACD settings' gRenderDebug->sendRemoteCommand("BeginGroup \"Simulation\""); // Mark the beginning of a group of controls. - gRenderDebug->sendRemoteCommand("Combo ConstraintType ConstraintType HINGE FIXED SPHERICAL BALLSOCKET REVOLUTE"); - gRenderDebug->sendRemoteCommand("SliderInt LimitRangeDegrees 45 1 90 LimitRangeDegrees"); - gRenderDebug->sendRemoteCommand("CheckBox ShowConstraints true ShowConstraints"); - gRenderDebug->sendRemoteCommand("CheckBox ShowSkeleton true ShowSkeleton"); - gRenderDebug->sendRemoteCommand("CheckBox ShowCollisionPairs false ShowCollisionPairs"); - gRenderDebug->sendRemoteCommand("CheckBox SimulateAsRagdoll false SimulateAsRagdoll"); gRenderDebug->sendRemoteCommand("Button ToggleSimulation ToggleSimulation"); gRenderDebug->sendRemoteCommand("EndGroup"); // End the group called 'controls' @@ -244,6 +274,10 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa { mExit = true; } + else if (strcmp(cmd, "toggle") == 0) + { + mSolid = mSolid ? false : true; + } else if (strcmp(cmd, "decomp") == 0 && mTestHACD) { printf("Performing Convex Decomposition\n"); @@ -254,26 +288,6 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa const char *value = argv[1]; mShowPhysics = strcmp(value, "true") == 0; } - else if (strcmp(cmd, "ShowConstraints") == 0 && argc == 2) - { - const char *value = argv[1]; - mShowConstraints = strcmp(value, "true") == 0; - } - else if (strcmp(cmd, "ShowSkeleton") == 0 && argc == 2) - { - const char *value = argv[1]; - mShowSkeleton = strcmp(value, "true") == 0; - } - else if (strcmp(cmd, "ShowCollisionPairs") == 0 && argc == 2) - { - const char *value = argv[1]; - mShowCollisionPairs = strcmp(value, "true") == 0; - } - else if (strcmp(cmd, "SimulateAsRagdoll") == 0 && argc == 2) - { - const char *value = argv[1]; - mSimulateAsRagdoll = strcmp(value, "true") == 0; - } else if (strcmp(cmd, "SaveObj") == 0) { mWavefront.saveObj("wavefront.obj"); @@ -293,7 +307,7 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa } else if (strcmp(cmd, "ToggleSimulation") == 0 && mTestHACD ) { - mTestHACD->toggleSimulation(mSimulateAsRagdoll, mConstraintType, 0, mLimitRangeDegrees, 0, 0); + mTestHACD->toggleSimulation(); } else if (strcmp(cmd, "raycast") == 0 && mTestHACD) { @@ -307,36 +321,6 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa printf("Canceling Convex Decomposition\n"); mTestHACD->cancel(); } - else if (strcmp(cmd, "LimitRangeDegrees") == 0 && argc == 2) - { - mLimitRangeDegrees = uint32_t( atoi(argv[1])); - printf("LimitRangeDegrees=%d\n", mLimitRangeDegrees); - } - else if (strcmp(cmd, "ConstraintType") == 0 && argc == 2) - { - const char *ct = argv[1]; - if (strcmp(ct, "HINGE") == 0) - { - mConstraintType = NV_PHYSX_FRAMEWORK::CT_HINGE; - } - else if (strcmp(ct, "FIXED") == 0) - { - mConstraintType = NV_PHYSX_FRAMEWORK::CT_FIXED; - } - else if (strcmp(ct, "SPHERICAL") == 0) - { - mConstraintType = NV_PHYSX_FRAMEWORK::CT_SPHERICAL; - } - else if (strcmp(ct, "BALLSOCKET") == 0) - { - mConstraintType = NV_PHYSX_FRAMEWORK::CT_BALL_AND_SOCKET; - } - else if (strcmp(ct, "REVOLUTE") == 0) - { - mConstraintType = NV_PHYSX_FRAMEWORK::CT_REVOLUTE; - } - printf("ConstraintType=%s\n", ct); - } else if (strcmp(cmd, "MaxHullVertices") == 0 && argc == 2) { gDesc.m_maxNumVerticesPerCH = atoi(argv[1]); @@ -388,11 +372,6 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa const char *value = argv[1]; mWireframeConvex = strcmp(value, "true") == 0; } - else if (strcmp(cmd, "WireframeSourceMesh") == 0 && argc == 2) - { - const char *value = argv[1]; - mWireframeSourceMesh = strcmp(value, "true") == 0; - } else if (strcmp(cmd, "Resolution") == 0 && argc == 2) { const char *value = argv[1]; @@ -418,19 +397,6 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa gRenderDebug->releaseTriangleMesh(mMeshID); mMeshID = 0; } - else if (strcmp(cmd, "TessellateInputMesh") == 0 && argc == 2) - { - const char *value = argv[1]; - gTessellateInputMesh = uint32_t(atoi(value)); - printf("TessellateInputMesh=%d\n", gTessellateInputMesh); - if (mTestHACD) - { - mTestHACD->release(); - mTestHACD = nullptr; - } - gRenderDebug->releaseTriangleMesh(mMeshID); - mMeshID = 0; - } else if (strcmp(cmd, "save") == 0) { if (mTestHACD) @@ -447,7 +413,7 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa { if (mMeshID == 0 && mSourceMesh.mVertexCount) { - mSourceMesh.deepCopyScale(mWavefront, gScaleInputMesh,gCenterMesh,gTessellateInputMesh); + mSourceMesh.deepCopyScale(mWavefront, gScaleInputMesh,gCenterMesh); gCenterMesh = false; // clear the center mesh semaphore gVertexCount = mWavefront.mVertexCount; gTriangleCount = mWavefront.mTriCount; @@ -477,77 +443,67 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa gRenderDebug->createTriangleMesh(mMeshID, (uint32_t)mb.mVertices.size(), &mb.mVertices[0], 0, nullptr); } fm_computCenter(mWavefront.mVertexCount, mWavefront.mVertices, gCenter); - if (mTestHACD) - { - mTestHACD->setRenderMesh(mWavefront.mVertexCount, mWavefront.mVertices, mWavefront.mTriCount, mWavefront.mIndices); - } } gRenderDebug->debugText2D(0, 0.04f, 0.5f, 2.0f, false, 0xFFFF00, "%s", mMeshName.c_str()); if ( mTestHACD ) { - gRenderDebug->debugText2D(0, 0.08f, 0.5f, 2.0f, false, 0xFFFF00, "VertexCount: %d TriangleCount: %d", mWavefront.mVertexCount, mWavefront.mTriCount); - gRenderDebug->debugText2D(0, 0.12f, 0.5f, 2.0f, false, 0xFFFF00, "HullCount: %d ConstraintCount: %d CollisionFilterCount: %d", mTestHACD->getHullCount(), mTestHACD->getConstraintCount(), mTestHACD->getCollisionFilterCount()); + gRenderDebug->debugText2D(0, 0.08f, 0.5f, 2.0f, false, 0xFFFF00, "HullCount: %d", mTestHACD->getHullCount()); } gRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::SolidWireShaded); gRenderDebug->addToCurrentState(RENDER_DEBUG::DebugRenderState::CameraFacing); gRenderDebug->setCurrentColor(0xFFFF00); + + if (gShowSourceMesh) { - if (mTestHACD && mSimulateAsRagdoll && mTestHACD->isSimulating()) + if (mSolid) { - // we don't render while simulating... + RENDER_DEBUG::RenderDebugInstance instance; + float xform[16]; + FLOAT_MATH::fm_identity(xform); + if (mTestHACD) + { + mTestHACD->getTransform(xform); + instance.mTransform[0] = xform[12]; + instance.mTransform[1] = xform[13]; + instance.mTransform[2] = xform[14]; + + instance.mTransform[3] = xform[0]; + instance.mTransform[4] = xform[1]; + instance.mTransform[5] = xform[2]; + + instance.mTransform[6] = xform[4]; + instance.mTransform[7] = xform[5]; + instance.mTransform[8] = xform[6]; + + instance.mTransform[9] = xform[8]; + instance.mTransform[10] = xform[9]; + instance.mTransform[11] = xform[10]; + } + gRenderDebug->renderTriangleMeshInstances(mMeshID, 1, &instance); } else { - if (!mWireframeSourceMesh) + gRenderDebug->pushRenderState(); + float xform[16]; + FLOAT_MATH::fm_identity(xform); + if (mTestHACD) { - RENDER_DEBUG::RenderDebugInstance instance; - float xform[16]; - FLOAT_MATH::fm_identity(xform); - if (mTestHACD) - { - mTestHACD->getTransform(xform); - instance.mTransform[0] = xform[12]; - instance.mTransform[1] = xform[13]; - instance.mTransform[2] = xform[14]; - - instance.mTransform[3] = xform[0]; - instance.mTransform[4] = xform[1]; - instance.mTransform[5] = xform[2]; - - instance.mTransform[6] = xform[4]; - instance.mTransform[7] = xform[5]; - instance.mTransform[8] = xform[6]; - - instance.mTransform[9] = xform[8]; - instance.mTransform[10] = xform[9]; - instance.mTransform[11] = xform[10]; - } - gRenderDebug->renderTriangleMeshInstances(mMeshID, 1, &instance); + mTestHACD->getTransform(xform); } - else + gRenderDebug->setPose(xform); + for (uint32_t i = 0; i < mWavefront.mTriCount; i++) { - gRenderDebug->pushRenderState(); - float xform[16]; - FLOAT_MATH::fm_identity(xform); - if (mTestHACD) - { - mTestHACD->getTransform(xform); - } - gRenderDebug->setPose(xform); - for (uint32_t i = 0; i < mWavefront.mTriCount; i++) - { - uint32_t i1 = mWavefront.mIndices[i * 3 + 0]; - uint32_t i2 = mWavefront.mIndices[i * 3 + 1]; - uint32_t i3 = mWavefront.mIndices[i * 3 + 2]; - const float *p1 = &mWavefront.mVertices[i1 * 3]; - const float *p2 = &mWavefront.mVertices[i2 * 3]; - const float *p3 = &mWavefront.mVertices[i3 * 3]; - gRenderDebug->debugTri(p3, p2, p1); - } - gRenderDebug->popRenderState(); + uint32_t i1 = mWavefront.mIndices[i * 3 + 0]; + uint32_t i2 = mWavefront.mIndices[i * 3 + 1]; + uint32_t i3 = mWavefront.mIndices[i * 3 + 2]; + const float *p1 = &mWavefront.mVertices[i1 * 3]; + const float *p2 = &mWavefront.mVertices[i2 * 3]; + const float *p3 = &mWavefront.mVertices[i3 * 3]; + gRenderDebug->debugTri(p3, p2, p1); } + gRenderDebug->popRenderState(); } } if (mTestHACD == nullptr) @@ -556,7 +512,7 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa } if (mTestHACD && gShowConvexDecomposition) { - mTestHACD->render(gExplodeViewScale, gCenter, mWireframeConvex, mShowConstraints, mShowSkeleton, mShowCollisionPairs); + mTestHACD->render(gExplodeViewScale, gCenter, mWireframeConvex); } gPhysXFramework->simulate(mShowPhysics); @@ -608,21 +564,15 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa } uint32_t mMeshID{ 0 }; - uint32_t mLimitRangeDegrees{ 45 }; - bool mSimulateAsRagdoll{ false }; - bool mShowConstraints{ true }; - bool mShowCollisionPairs{ false }; - bool mShowSkeleton{ true }; bool mShowPhysics{ true }; + bool mSolid{ true }; bool mWireframeConvex{ false }; - bool mWireframeSourceMesh{ false }; TestHACD *mTestHACD{ nullptr }; bool mExit{ false }; WavefrontObj mSourceMesh; WavefrontObj mWavefront; double *mMeshVertices{ nullptr }; std::string mMeshName; - NV_PHYSX_FRAMEWORK::ConstraintType mConstraintType{ NV_PHYSX_FRAMEWORK::CT_HINGE }; }; #define USE_DEBUG 0 diff --git a/DebugView/wavefront.cpp b/DebugView/wavefront.cpp index c1e3b516..724aa6dc 100644 --- a/DebugView/wavefront.cpp +++ b/DebugView/wavefront.cpp @@ -8,7 +8,6 @@ #include #include "wavefront.h" -#include "FloatMath.h" /*! ** @@ -922,10 +921,7 @@ bool WavefrontObj::saveObj(const char *fname,uint32_t vcount,const float *vertic return ret; } -void WavefrontObj::deepCopyScale(WavefrontObj &dest, - float scaleFactor, - bool centerMesh, - uint32_t tessellateInputMesh) +void WavefrontObj::deepCopyScale(WavefrontObj &dest, float scaleFactor,bool centerMesh) { dest.releaseMesh(); dest.mVertexCount = mVertexCount; @@ -982,6 +978,8 @@ void WavefrontObj::deepCopyScale(WavefrontObj &dest, adjustY = bmin[1]; // (bmin[1] + bmax[1])*0.5f; adjustZ = (bmin[2] + bmax[2])*0.5f; } + + dest.mVertices = new float[mVertexCount * 3]; for (uint32_t i = 0; i < mVertexCount; i++) { @@ -989,62 +987,6 @@ void WavefrontObj::deepCopyScale(WavefrontObj &dest, dest.mVertices[i * 3 + 1] = (mVertices[i * 3 + 1]-adjustY) * scaleFactor; dest.mVertices[i * 3 + 2] = (mVertices[i * 3 + 2]-adjustZ) * scaleFactor; } - // if we are going to tessellate the input mesh.. - - if (tessellateInputMesh > 1) - { - // Compute the diagonal length of the input mesh - float bmin[3]; - float bmax[3]; - FLOAT_MATH::fm_initMinMax(bmin, bmax); - for (uint32_t i = 0; i < dest.mVertexCount; i++) - { - const float *p = &dest.mVertices[i * 3]; - FLOAT_MATH::fm_minmax(p, bmin, bmax); - } - float diagonalLength = FLOAT_MATH::fm_distance(bmin, bmax); - // Populate the vertex index system with vertices and save the indices - FLOAT_MATH::fm_VertexIndex *vindex = FLOAT_MATH::fm_createVertexIndex(0.0f, false); - std::vector< uint32_t > indices; - for (uint32_t i = 0; i < dest.mTriCount; i++) - { - uint32_t i1 = dest.mIndices[i * 3 + 0]; - uint32_t i2 = dest.mIndices[i * 3 + 1]; - uint32_t i3 = dest.mIndices[i * 3 + 2]; - - const float *p1 = &dest.mVertices[i1 * 3]; - const float *p2 = &dest.mVertices[i2 * 3]; - const float *p3 = &dest.mVertices[i3 * 3]; - - bool newPos; - i1 = vindex->getIndex(p1, newPos); - i2 = vindex->getIndex(p2, newPos); - i3 = vindex->getIndex(p3, newPos); - indices.push_back(i1); - indices.push_back(i2); - indices.push_back(i3); - } - // The tessellation distance is the diagonal length divided by the tesselation factor - float tessellationDistance = diagonalLength / float(tessellateInputMesh); - - FLOAT_MATH::fm_Tesselate *tess = FLOAT_MATH::fm_createTesselate(); - uint32_t outcount; - const uint32_t *newIndices = tess->tesselate(vindex, dest.mTriCount, &indices[0], tessellationDistance, 8, outcount); - - delete[]dest.mIndices; - delete[]dest.mVertices; - - dest.mIndices = new uint32_t[outcount * 3]; - dest.mTriCount = outcount; // new number of triangles.. - memcpy(dest.mIndices, newIndices, outcount * 3 * sizeof(uint32_t)); - - dest.mVertexCount = vindex->getVcount(); - dest.mVertices = new float[dest.mVertexCount * 3]; - memcpy(dest.mVertices, vindex->getVerticesFloat(), sizeof(float)*dest.mVertexCount * 3); - - FLOAT_MATH::fm_releaseVertexIndex(vindex); - FLOAT_MATH::fm_releaseTesselate(tess); - } } } diff --git a/DebugView/wavefront.h b/DebugView/wavefront.h index 10f34900..838c9c85 100644 --- a/DebugView/wavefront.h +++ b/DebugView/wavefront.h @@ -55,7 +55,7 @@ class WavefrontObj void releaseMesh(void); - void deepCopyScale(WavefrontObj &dest, float scaleFactor,bool centerMesh,uint32_t tessellateInputMesh); + void deepCopyScale(WavefrontObj &dest, float scaleFactor,bool centerMesh); bool saveObj(const char *fname); diff --git a/src/VHACD_Lib/inc/FloatMath.h b/src/VHACD_Lib/inc/FloatMath.h index 3fdcdaf2..37b07cb6 100644 --- a/src/VHACD_Lib/inc/FloatMath.h +++ b/src/VHACD_Lib/inc/FloatMath.h @@ -244,16 +244,31 @@ bool fm_computeBestFitPlane(uint32_t vcount, // number of input data points double plane[4], double center[3]); +// Computes the average center of a set of data points bool fm_computeCentroid(uint32_t vcount, // number of input data points const float *points, // starting address of points array. - uint32_t vstride, // stride between input points. float *center); bool fm_computeCentroid(uint32_t vcount, // number of input data points const double *points, // starting address of points array. - uint32_t vstride, // stride between input points. double *center); +// Compute centroid of a triangle mesh; takes area of each triangle into account +// weighted average +bool fm_computeCentroid(uint32_t vcount, // number of input data points + const float *points, // starting address of points array. + uint32_t triangleCount, + const uint32_t *indices, + float *center); + +// Compute centroid of a triangle mesh; takes area of each triangle into account +// weighted average +bool fm_computeCentroid(uint32_t vcount, // number of input data points + const double *points, // starting address of points array. + uint32_t triangleCount, + const uint32_t *indices, + double *center); + float fm_computeBestFitAABB(uint32_t vcount,const float *points,uint32_t pstride,float bmin[3],float bmax[3]); // returns the diagonal distance double fm_computeBestFitAABB(uint32_t vcount,const double *points,uint32_t pstride,double bmin[3],double bmax[3]); // returns the diagonal distance @@ -341,8 +356,8 @@ PlaneTriResult fm_planeTriIntersection(const double plane[4], // the plane eq uint32_t &bcount); // the number of vertices in the 'back' triangle. -void fm_intersectPointPlane(const float p1[3],const float p2[3],float *split,const float plane[4]); -void fm_intersectPointPlane(const double p1[3],const double p2[3],double *split,const double plane[4]); +bool fm_intersectPointPlane(const float p1[3],const float p2[3],float *split,const float plane[4]); +bool fm_intersectPointPlane(const double p1[3],const double p2[3],double *split,const double plane[4]); PlaneTriResult fm_getSidePlane(const float p[3],const float plane[4],float epsilon); PlaneTriResult fm_getSidePlane(const double p[3],const double plane[4],double epsilon); @@ -504,6 +519,7 @@ void fm_computeMeanNormals(uint32_t vcount, // the number of vertices bool fm_isValidTriangle(const float *p1,const float *p2,const float *p3,float epsilon=0.00001f); bool fm_isValidTriangle(const double *p1,const double *p2,const double *p3,double epsilon=0.00001f); + }; // end of namespace #endif diff --git a/src/VHACD_Lib/inc/vhacdVHACD.h b/src/VHACD_Lib/inc/vhacdVHACD.h index 3bf84992..d67b1076 100644 --- a/src/VHACD_Lib/inc/vhacdVHACD.h +++ b/src/VHACD_Lib/inc/vhacdVHACD.h @@ -29,8 +29,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #include "vhacdRaycastMesh.h" #include -typedef std::vector< VHACD::IVHACD::Constraint > ConstraintVector; - #define USE_THREAD 1 #define OCL_MIN_NUM_PRIMITIVES 4096 #define CH_APP_MIN_NUM_PRIMITIVES 64000 @@ -116,26 +114,6 @@ class VHACD : public IVHACD { virtual bool ComputeCenterOfMass(double centerOfMass[3]) const; - // Will analyze the HACD results and compute the constraints solutions. - // It will analyze the point at which any two convex hulls touch each other and - // return the total number of constraint pairs found - virtual uint32_t ComputeConstraints(void); - - // Returns a pointer to the list of constraints generated and the 'constraintCount' - // Returns a null pointer if 'ComputeConstraints' has not yet been called or - // no constraints were found. - virtual const Constraint *GetConstraints(uint32_t &constraintCount) const; - - // Returns the number of collision pairs which need to be filtered. - // These are convex hulls that overlap in their rest pose but are not constrained - // to each other. These will generate potentially bad collision contacts which - // prevent the objects from coming to rest. - // Use these pairs to exclude those collisions - // If it returns a null pointer, then no collision pair filters are required (or constraints haven't been generated yet) - // collisionFilterPairCount will be assigned the number of pairs to filter. - // The return value will be pairs of integer; example 3,4 meaning body 3 and body 4 should not collide - virtual const uint32_t *GetCollisionFilterPairs(uint32_t &collisionPairFilterCount) const; - private: void SetCancel(bool cancel) { @@ -388,8 +366,6 @@ class VHACD : public IVHACD { cl_kernel* m_oclKernelComputeSum; size_t m_oclWorkGroupSize; #endif //CL_VERSION_1_1 - ConstraintVector mConstraints; - std::vector mExclusionList; }; } #endif // VHACD_VHACD_H diff --git a/src/VHACD_Lib/public/VHACD.h b/src/VHACD_Lib/public/VHACD.h index 228575ab..65390984 100644 --- a/src/VHACD_Lib/public/VHACD.h +++ b/src/VHACD_Lib/public/VHACD.h @@ -109,15 +109,6 @@ class IVHACD { bool m_projectHullVertices; }; - class Constraint - { - public: - uint32_t mHullA; // Convex Hull A index - uint32_t mHullB; // Convex Hull B index - double mConstraintPoint[3]; // The point of intersection between the two convex hulls - double mConstraintOrientation[4]; // the orientation of the constraint as a quaternion - }; - virtual void Cancel() = 0; virtual bool Compute(const float* const points, const uint32_t countPoints, @@ -144,27 +135,6 @@ class IVHACD { // in 'centerOfMass'. Returns false if the center of mass could not be computed. virtual bool ComputeCenterOfMass(double centerOfMass[3]) const = 0; - // Will analyze the HACD results and compute the constraints solutions. - // It will analyze the point at which any two convex hulls touch each other and - // return the total number of constraint pairs found - virtual uint32_t ComputeConstraints(void) = 0; - - // Returns a pointer to the list of constraints generated and the 'constraintCount' - // Returns a null pointer if 'ComputeConstraints' has not yet been called or - // no constraints were found. - virtual const Constraint *GetConstraints(uint32_t &constraintCount) const = 0; - - // Returns the number of collision pairs which need to be filtered. - // These are convex hulls that overlap in their rest pose but are not constrained - // to each other. These will generate potentially bad collision contacts which - // prevent the objects from coming to rest. - // Use these pairs to exclude those collisions - // If it returns a null pointer, then no collision pair filters are required (or constraints haven't been generated yet) - // collisionFilterPairCount will be assigned the number of pairs to filter. - // The return value will be pairs of integer; example 3,4 meaning body 3 and body 4 should not collide - virtual const uint32_t *GetCollisionFilterPairs(uint32_t &collisionPairFilterCount) const = 0; - - // In synchronous mode (non-multi-threaded) the state is always 'ready' // In asynchronous mode, this returns true if the background thread is not still actively computing // a new solution. In an asynchronous config the 'IsReady' call will report any update or log diff --git a/src/VHACD_Lib/src/FloatMath.cpp b/src/VHACD_Lib/src/FloatMath.cpp index ecc985e4..481e8751 100644 --- a/src/VHACD_Lib/src/FloatMath.cpp +++ b/src/VHACD_Lib/src/FloatMath.cpp @@ -6,7 +6,6 @@ #include #include "FloatMath.h" #include -#include #define REAL float diff --git a/src/VHACD_Lib/src/FloatMath.inl b/src/VHACD_Lib/src/FloatMath.inl index 4fa9235e..ce529e6f 100644 --- a/src/VHACD_Lib/src/FloatMath.inl +++ b/src/VHACD_Lib/src/FloatMath.inl @@ -7,8 +7,6 @@ // a quaternion is a 'float *' to 4 floats representing a quaternion x,y,z,w // -#pragma warning(disable:4996) - namespace FLOAT_MATH { @@ -1777,10 +1775,19 @@ IntersectResult fm_intersectLineSegments2dTime(const REAL *a1,const REAL *a2,con // assumes that the points are on opposite sides of the plane! -void fm_intersectPointPlane(const REAL *p1,const REAL *p2,REAL *split,const REAL *plane) +bool fm_intersectPointPlane(const REAL *p1,const REAL *p2,REAL *split,const REAL *plane) { REAL dp1 = fm_distToPlane(plane,p1); + REAL dp2 = fm_distToPlane(plane, p2); + if (dp1 <= 0 && dp2 <= 0) + { + return false; + } + if (dp1 >= 0 && dp2 >= 0) + { + return false; + } REAL dir[3]; @@ -1797,6 +1804,7 @@ void fm_intersectPointPlane(const REAL *p1,const REAL *p2,REAL *split,const REAL split[1] = (dir[1]*t)+p1[1]; split[2] = (dir[2]*t)+p1[2]; + return true; } PlaneTriResult fm_getSidePlane(const REAL *p,const REAL *plane,REAL epsilon) @@ -3408,7 +3416,7 @@ bool fm_pointInsidePolygon2d(uint32_t pcount,const REAL *points,uint32_t pstrid REAL x2 = p2[xindex]; REAL y2 = p2[yindex]; - if ( y1 < y && y2 >= y || y2 < y && y1 >= y ) + if ( (y1 < y && y2 >= y) || (y2 < y && y1 >= y) ) { if (x1+(y-y1)/(y2-y1)*(x2-x1) class Vec3 diff --git a/src/VHACD_Lib/src/VHACD-ASYNC.cpp b/src/VHACD_Lib/src/VHACD-ASYNC.cpp index 651019f9..5a2f6be6 100644 --- a/src/VHACD_Lib/src/VHACD-ASYNC.cpp +++ b/src/VHACD_Lib/src/VHACD-ASYNC.cpp @@ -296,53 +296,6 @@ class MyHACD_API : public VHACD::IVHACD, public VHACD::IVHACD::IUserCallback, VH return ret; } - // Will analyze the HACD results and compute the constraints solutions. - // It will analyze the point at which any two convex hulls touch each other and - // return the total number of constraint pairs found - virtual uint32_t ComputeConstraints(void) final - { - uint32_t ret = 0; - if (mVHACD && IsReady()) - { - ret = mVHACD->ComputeConstraints(); - } - return ret; - } - - // Returns a pointer to the list of constraints generated and the 'constraintCount' - // Returns a null pointer if 'ComputeConstraints' has not yet been called or - // no constraints were found. - virtual const Constraint *GetConstraints(uint32_t &constraintCount) const final - { - const Constraint * ret = nullptr; - if (mVHACD && IsReady()) - { - ret = mVHACD->GetConstraints(constraintCount); - } - return ret; - } - - // Returns the number of collision pairs which need to be filtered. - // These are convex hulls that overlap in their rest pose but are not constrained - // to each other. These will generate potentially bad collision contacts which - // prevent the objects from coming to rest. - // Use these pairs to exclude those collisions - // If it returns a null pointer, then no collision pair filters are required (or constraints haven't been generated yet) - // collisionFilterPairCount will be assigned the number of pairs to filter. - // The return value will be pairs of integer; example 3,4 meaning body 3 and body 4 should not collide - virtual const uint32_t *GetCollisionFilterPairs(uint32_t &collisionPairFilterCount) const - { - const uint32_t *ret = nullptr; - collisionPairFilterCount = 0; - if (mVHACD && IsReady()) - { - ret = mVHACD->GetCollisionFilterPairs(collisionPairFilterCount); - } - - - return ret; - } - private: double *mVertices{ nullptr }; uint32_t *mIndices{ nullptr }; diff --git a/src/VHACD_Lib/src/VHACD.cpp b/src/VHACD_Lib/src/VHACD.cpp index dbc4f5ab..01bb0c72 100644 --- a/src/VHACD_Lib/src/VHACD.cpp +++ b/src/VHACD_Lib/src/VHACD.cpp @@ -35,15 +35,6 @@ #include "vhacdVolume.h" #include "FloatMath.h" -// Internal debugging feature only -#define DEBUG_VISUALIZE_CONSTRAINTS 0 - -#if DEBUG_VISUALIZE_CONSTRAINTS -#include "NvRenderDebug.h" -extern RENDER_DEBUG::RenderDebug *gRenderDebug; -#pragma warning(disable:4702) -#endif - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define ABS(a) (((a) < 0) ? -(a) : (a)) @@ -1593,307 +1584,4 @@ bool VHACD::ComputeCenterOfMass(double centerOfMass[3]) const return ret; } -#pragma warning(disable:4189 4101) - -// Will analyze the HACD results and compute the constraints solutions. -// It will analyze the point at which any two convex hulls touch each other and -// return the total number of constraint pairs found -uint32_t VHACD::ComputeConstraints(void) -{ - mConstraints.clear(); // erase any previous constraint results - mExclusionList.clear(); // erase any previous collision filter pairs - uint32_t hullCount = GetNConvexHulls(); // get the number of convex hulls in the results - if (hullCount == 0) - return 0; -#if DEBUG_VISUALIZE_CONSTRAINTS - gRenderDebug->pushRenderState(); - gRenderDebug->setCurrentDisplayTime(10); -#endif - - // We voxelize the convex hull - class HullData - { - public: - HullData(void) - { - FLOAT_MATH::fm_initMinMax(mBmin, mBmax); - } - - ~HullData(void) - { - FLOAT_MATH::fm_releaseVertexIndex(mVertexIndex); - FLOAT_MATH::fm_releaseTesselate(mTesselate); - delete[]mIndices; - } - - void computeResolution(void) - { - mDiagonalDistance = FLOAT_MATH::fm_distance(mBmin, mBmax); - mTessellateDistance = mDiagonalDistance / 10; - mNearestPointDistance = mDiagonalDistance / 10.0f; - mPointResolution = mDiagonalDistance / 100; - mVertexIndex = FLOAT_MATH::fm_createVertexIndex(mPointResolution, false); - mTesselate = FLOAT_MATH::fm_createTesselate(); - } - - void computeTesselation(void) - { - mTesselationIndices = mTesselate->tesselate(mVertexIndex, mSourceTriangleCount, mIndices, mTessellateDistance, 6, mTessellateTriangleCount); - uint32_t vcount = mVertexIndex->getVcount(); - } - - bool getNearestVert(const double sourcePoint[3], - double nearest[3], - const HullData &other, - double nearestThreshold) - { - bool ret = false; - - double nt2 = nearestThreshold*nearestThreshold; - uint32_t vcount = other.mVertexIndex->getVcount(); - for (uint32_t i = 0; i < vcount; i++) - { - const double *p = other.mVertexIndex->getVertexDouble(i); - double d2 = FLOAT_MATH::fm_distanceSquared(sourcePoint, p); - if (d2 < nt2) - { - nearest[0] = p[0]; - nearest[1] = p[1]; - nearest[2] = p[2]; - nt2 = d2; - ret = true; - } - } - - return ret; - } - - bool findMatchingPoints(const HullData &other,double constraintPos[3], double constraintRotation[4]) - { - bool ret = false; - class Vec3 - { - public: - Vec3(const double *p) - { - mPos[0] = p[0]; - mPos[1] = p[1]; - mPos[2] = p[2]; - } - double mPos[3]; - }; - std::vector< Vec3 > points; - std::vector< double > weights; - - uint32_t vcount = mVertexIndex->getVcount(); - for (uint32_t i = 0; i < vcount; i++) - { - const double *sourcePoint = mVertexIndex->getVertexDouble(i); - double nearestPoint[3]; - if (getNearestVert(sourcePoint, nearestPoint, other, mNearestPointDistance)) - { - Vec3 p1(sourcePoint); - Vec3 p2(nearestPoint); - double distance = FLOAT_MATH::fm_distance(sourcePoint, nearestPoint); - - points.push_back(p1); - points.push_back(p2); - weights.push_back(distance); - weights.push_back(distance); - -#if DEBUG_VISUALIZE_CONSTRAINTS && 0 - float fp1[3]; - float fp2[3]; - FLOAT_MATH::fm_doubleToFloat3(sourcePoint, fp1); - FLOAT_MATH::fm_doubleToFloat3(nearestPoint, fp2); - gRenderDebug->debugLine(fp1, fp2); -#endif - } - } - uint32_t count = uint32_t(points.size()); - if (count) - { - double plane[4]; - double center[3]; - bool found = FLOAT_MATH::fm_computeBestFitPlane(count, points[0].mPos, sizeof(Vec3), &weights[0], sizeof(double), plane, center); - if (found) - { - - double quat[4]; - double ref[3] = { 0,1,0 }; - FLOAT_MATH::fm_rotationArc(ref, plane, quat); - - constraintPos[0] = center[0]; - constraintPos[1] = center[1]; - constraintPos[2] = center[2]; - - constraintRotation[0] = quat[0]; - constraintRotation[1] = quat[1]; - constraintRotation[2] = quat[2]; - constraintRotation[3] = quat[3]; - - ret = true; - -#if DEBUG_VISUALIZE_CONSTRAINTS - float from[3]; - float to[3]; - - FLOAT_MATH::fm_doubleToFloat3(center, from); - FLOAT_MATH::fm_doubleToFloat3(plane, to); - to[0] += from[0]; - to[1] += from[1]; - to[2] += from[2]; - gRenderDebug->debugThickRay(from, to); - gRenderDebug->debugSphere(from, 0.1f); - - - double xform[16]; - float transform[16]; - FLOAT_MATH::fm_quatToMatrix(quat, xform); - for (uint32_t i = 0; i < 16; i++) - { - transform[i] = float(xform[i]); - } - transform[12] = from[0]; - transform[13] = from[1]; - transform[14] = from[2]; - - - gRenderDebug->debugAxes(transform, 0.8f); -#endif - - } - } - return ret; - } - - double mBmin[3]; - double mBmax[3]; - double mDiagonalDistance; - double mTessellateDistance; - double mPointResolution; - double mNearestPointDistance; - uint32_t mSourceTriangleCount{ 0 }; - uint32_t mTessellateTriangleCount{ 0 }; - uint32_t *mIndices{ nullptr }; - FLOAT_MATH::fm_VertexIndex *mVertexIndex{ nullptr }; - FLOAT_MATH::fm_Tesselate *mTesselate{ nullptr }; - const uint32_t *mTesselationIndices{ nullptr }; - }; - - HullData *hullData = new HullData[hullCount]; - for (uint32_t i = 0; i < hullCount; i++) - { - HullData &hd = hullData[i]; - ConvexHull ch; - GetConvexHull(i, ch); - // Compute the bounding volume of this convex hull - for (uint32_t j = 0; j < ch.m_nPoints; j++) - { - const double *p = &ch.m_points[j * 3]; - FLOAT_MATH::fm_minmax(p, hd.mBmin, hd.mBmax); - } - hd.computeResolution(); // Compute the tessellation resolution - uint32_t tcount = ch.m_nTriangles; - hd.mSourceTriangleCount = tcount; - hd.mIndices = new uint32_t[tcount * 3]; - for (uint32_t j = 0; j < tcount; j++) - { - uint32_t i1 = ch.m_triangles[j * 3 + 0]; - uint32_t i2 = ch.m_triangles[j * 3 + 1]; - uint32_t i3 = ch.m_triangles[j * 3 + 2]; - const double *p1 = &ch.m_points[i1 * 3]; - const double *p2 = &ch.m_points[i2 * 3]; - const double *p3 = &ch.m_points[i3 * 3]; - bool newPos; - hd.mIndices[j * 3 + 0] = hd.mVertexIndex->getIndex(p1, newPos); - hd.mIndices[j * 3 + 1] = hd.mVertexIndex->getIndex(p2, newPos); - hd.mIndices[j * 3 + 2] = hd.mVertexIndex->getIndex(p3, newPos); - } - hd.computeTesselation(); - } - - for (uint32_t i = 0; i < hullCount; i++) - { - HullData &hd = hullData[i]; - // Slightly inflate the bounding box around each convex hull for intersection tests - // during the constraint building phase - FLOAT_MATH::fm_inflateMinMax(hd.mBmin, hd.mBmax, 0.05f); - } - - // Look for every possible pair of convex hulls as possible constraints - for (uint32_t i = 0; i < hullCount; i++) - { - HullData &hd1 = hullData[i]; - for (uint32_t j = i + 1; j < hullCount; j++) - { - HullData &hd2 = hullData[j]; - if (FLOAT_MATH::fm_intersectAABB(hd1.mBmin, hd1.mBmax, hd2.mBmin, hd2.mBmax)) - { - // ok. if two convex hulls intersect, we are going to find the number of nearest - // matching points between them. - VHACD::Constraint c; - c.mHullA = i; - c.mHullB = j; - if (hd1.findMatchingPoints(hd2, c.mConstraintPoint, c.mConstraintOrientation)) - { - mConstraints.push_back(c); - } - else // if the bounding boxes overlap but there is not a constraint between them; add this pair to the exclusion list - { - mExclusionList.push_back(i); - mExclusionList.push_back(j); - } - } - } - } - - -#if DEBUG_VISUALIZE_CONSTRAINTS - gRenderDebug->popRenderState(); -#endif - - return uint32_t(mConstraints.size()); -} - -// Returns a pointer to the list of constraints generated and the 'constraintCount' -// Returns a null pointer if 'ComputeConstraints' has not yet been called or -// no constraints were found. -const VHACD::IVHACD::Constraint *VHACD::GetConstraints(uint32_t &constraintCount) const -{ - const Constraint *ret = nullptr; - - constraintCount = 0; - if ( !mConstraints.empty() ) - { - constraintCount = uint32_t(mConstraints.size()); - ret = &mConstraints[0]; - } - - return ret; -} - -// Returns the number of collision pairs which need to be filtered. -// These are convex hulls that overlap in their rest pose but are not constrained -// to each other. These will generate potentially bad collision contacts which -// prevent the objects from coming to rest. -// Use these pairs to exclude those collisions -// If it returns a null pointer, then no collision pair filters are required (or constraints haven't been generated yet) -// collisionFilterPairCount will be assigned the number of pairs to filter. -// The return value will be pairs of integer; example 3,4 meaning body 3 and body 4 should not collide -const uint32_t *VHACD::GetCollisionFilterPairs(uint32_t &collisionPairFilterCount) const -{ - const uint32_t *ret = nullptr; - - collisionPairFilterCount = 0; - if (!mExclusionList.empty()) - { - collisionPairFilterCount = (uint32_t)mExclusionList.size() / 2; - ret = &mExclusionList[0]; - } - - return ret; -} - - } // end of VHACD namespace \ No newline at end of file diff --git a/src/VHACD_Lib/src/vhacdMesh.cpp b/src/VHACD_Lib/src/vhacdMesh.cpp index 83e0952f..4efb59ae 100644 --- a/src/VHACD_Lib/src/vhacdMesh.cpp +++ b/src/VHACD_Lib/src/vhacdMesh.cpp @@ -16,6 +16,7 @@ #include "btConvexHullComputer.h" #include "vhacdMesh.h" +#include "FloatMath.h" #include #include #include @@ -37,6 +38,15 @@ Vec3& Mesh::ComputeCenter(void) const size_t nV = GetNPoints(); if (nV) { + double center[3]; + uint32_t pcount = uint32_t(GetNPoints()); + const double *points = GetPoints(); + uint32_t tcount = uint32_t(GetNTriangles()); + const uint32_t *indices = (const uint32_t *)GetTriangles(); + FLOAT_MATH::fm_computeCentroid(pcount, points, tcount, indices, center); + m_center.X() = center[0]; + m_center.Y() = center[1]; + m_center.Z() = center[2]; m_minBB = GetPoint(0); m_maxBB = GetPoint(0); for (size_t v = 1; v < nV; v++) @@ -67,9 +77,6 @@ Vec3& Mesh::ComputeCenter(void) m_maxBB.Z() = p.Z(); } } - m_center.X() = (m_maxBB.X() - m_minBB.X())*0.5 + m_minBB.X(); - m_center.Y() = (m_maxBB.Y() - m_minBB.Y())*0.5 + m_minBB.Y(); - m_center.Z() = (m_maxBB.Z() - m_minBB.Z())*0.5 + m_minBB.Z(); } return m_center; }