Skip to content

Commit

Permalink
Work in progress on constraint computation
Browse files Browse the repository at this point in the history
  • Loading branch information
jratcliff committed Aug 25, 2017
1 parent c53070f commit f86204d
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 119 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,11 @@ build/
/DebugView/compiler/vc14win32/Win32/ConvexDecomposition/debug/wavefront.obj
/DebugView/compiler/xpj/*.bak
/DebugView/*.bak
/DebugView/compiler/vc14win64/wavefront.obj
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/link.2656-cvtres.read.1.tlog
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/link.2656-cvtres.write.1.tlog
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/link.2656-rc.read.1.tlog
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/link.2656-rc.write.1.tlog
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/link.2656.read.1.tlog
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/link.2656.write.1.tlog
/DebugView/compiler/vc14win64/x64/ConvexDecomposition/release/ConvexDe.D0AF22C5.tlog/unsuccessfulbuild
Binary file modified DebugView/ConvexDecomposition.exe
Binary file not shown.
3 changes: 3 additions & 0 deletions DebugView/PhysXFramework/NvPhysXFramework.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class PhysXFramework

virtual void setCommandCallback(CommandCallback *cc) = 0;

// create a box in the simulated scene
virtual void createBox(const float boxSize[3], const float boxPosition[3]) = 0;

// Return the render debug interface if available
virtual RENDER_DEBUG::RenderDebug *getRenderDebug(void) = 0;

Expand Down
Binary file modified DebugView/PhysXFramework64.dll
Binary file not shown.
14 changes: 14 additions & 0 deletions DebugView/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>
#include <math.h>
#include <string>
#include <unordered_map>

#include "wavefront.h"
#include "NvRenderDebug.h"
Expand Down Expand Up @@ -587,8 +588,21 @@ class ConvexDecomposition : public NV_PHYSX_FRAMEWORK::PhysXFramework::CommandCa

#define USE_DEBUG 0

void testList(void)
{
uint32_t count = 5;
for (uint32_t i = 0; i < count; i++)
{
for (uint32_t j = i + 1; j < count; j++)
{
printf("[%d][%d]\n", i, j);
}
}
}

int32_t main(int32_t /*argc*/,const char ** /*argv*/)
{
testList();
{

const char *dllName = nullptr;
Expand Down
10 changes: 7 additions & 3 deletions src/VHACD_Lib/inc/FloatMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,13 @@ void fm_initMinMax(const double p[3],double bmin[3],double bmax[3]);
void fm_initMinMax(float bmin[3],float bmax[3]);
void fm_initMinMax(double bmin[3],double bmax[3]);

void fm_minmax(const float p[3],float bmin[3],float bmax[3]); // accmulate to a min-max value
void fm_minmax(const double p[3],double bmin[3],double bmax[3]); // accmulate to a min-max value
void fm_minmax(const float p[3],float bmin[3],float bmax[3]); // accumulate to a min-max value
void fm_minmax(const double p[3],double bmin[3],double bmax[3]); // accumulate to a min-max value

// Computes the diagonal length of the bounding box and then inflates the bounding box on all sides
// by the ratio provided.
void fm_inflateMinMax(float bmin[3], float bmax[3], float ratio);
void fm_inflateMinMax(double bmin[3], double bmax[3], double ratio);

float fm_solveX(const float plane[4],float y,float z); // solve for X given this plane equation and the other two components.
double fm_solveX(const double plane[4],double y,double z); // solve for X given this plane equation and the other two components.
Expand Down Expand Up @@ -468,7 +472,7 @@ bool fm_samePlane(const double p1[4],const double p2[4],double normalEpsilon=

void fm_OBBtoAABB(const float obmin[3],const float obmax[3],const float matrix[16],float abmin[3],float abmax[3]);

// a utility class that will tesseleate a mesh.
// a utility class that will tessellate a mesh.
class fm_Tesselate
{
public:
Expand Down
19 changes: 16 additions & 3 deletions src/VHACD_Lib/src/FloatMath.inl
Original file line number Diff line number Diff line change
Expand Up @@ -3851,11 +3851,24 @@ void fm_initMinMax(REAL bmin[3],REAL bmax[3])
bmin[0] = FLT_MAX;
bmin[1] = FLT_MAX;
bmin[2] = FLT_MAX;
bmax[0] = FLT_MIN;
bmax[1] = FLT_MIN;
bmax[2] = FLT_MIN;

bmax[0] = -FLT_MAX;
bmax[1] = -FLT_MAX;
bmax[2] = -FLT_MAX;
}

void fm_inflateMinMax(REAL bmin[3], REAL bmax[3], REAL ratio)
{
REAL inflate = fm_distance(bmin, bmax)*0.5f*ratio;

bmin[0] -= inflate;
bmin[1] -= inflate;
bmin[2] -= inflate;

bmax[0] += inflate;
bmax[1] += inflate;
bmax[2] += inflate;
}

#ifndef TESSELATE_H

Expand Down
184 changes: 71 additions & 113 deletions src/VHACD_Lib/src/VHACD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
#include "vhacdVector.h"
#include "vhacdVolume.h"
#include "FloatMath.h"
#include <unordered_map>

#define DEBUG_VISUALIZE_CONSTRAINTS 1

#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))
Expand Down Expand Up @@ -1567,6 +1569,8 @@ 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
Expand All @@ -1578,102 +1582,60 @@ uint32_t VHACD::ComputeConstraints(void)
return 0;
#if DEBUG_VISUALIZE_CONSTRAINTS
gRenderDebug->pushRenderState();
gRenderDebug->setCurrentDisplayTime(5.0f);
gRenderDebug->setCurrentDisplayTime(10);
#endif

typedef std::vector<uint32_t> TriangleIndexVector;

class PlaneTriangles
// We voxelize the convex hull
class HullData
{
public:
PlaneTriangles(void)
HullData(void)
{
mBmin[0] = FLT_MAX;
mBmin[1] = FLT_MAX;
mBmin[2] = FLT_MAX;
mBmax[0] = -FLT_MAX;
mBmax[1] = -FLT_MAX;
mBmax[2] = -FLT_MAX;
FLOAT_MATH::fm_initMinMax(mBmin, mBmax);
}

bool planeMatch(const double *planeEquation, double distanceEpsilon) const
~HullData(void)
{
bool ret = false;

// Compute the absolute value difference of the D plane co-efficient
double diff = fabs(planeEquation[3] - mPlaneEquation[3]);
if (diff < distanceEpsilon) // if it's close enough... continue and test the vector normal
{
// Compute the squared distance between the two vector normals of the plane
// equations
// The valid epsilon distance for two normals to be considered co-planar is 0.01
double normalDiff = FLOAT_MATH::fm_distanceSquared(planeEquation, mPlaneEquation);
if (normalDiff < (0.01*0.01))
{
ret = true;
}
}

return ret;
FLOAT_MATH::fm_releaseVertexIndex(mVertexIndex);
FLOAT_MATH::fm_releaseTesselate(mTesselate);
delete[]mIndices;
}

void addTriangle(uint32_t index, const double *p1, const double *p2, const double *p3)
void computeResolution(void)
{
// Add the triangle index; base index in the triangle mesh of this convex hull
mTriangles.push_back(index);
// Adjust the bounding box for the triangles which match this plane equation..
FLOAT_MATH::fm_minmax(p1, mBmin, mBmax);
FLOAT_MATH::fm_minmax(p2, mBmin, mBmax);
FLOAT_MATH::fm_minmax(p3, mBmin, mBmax);
mDiagonalDistance = FLOAT_MATH::fm_distance(mBmin, mBmax);
mTessellateDistance = mDiagonalDistance / 10;
mPointResolution = mDiagonalDistance / 100;
mVertexIndex = FLOAT_MATH::fm_createVertexIndex(mPointResolution, false);
mTesselate = FLOAT_MATH::fm_createTesselate();
}

void setPlaneEquation(const double *p)
void computeTesselation(void)
{
mPlaneEquation[0] = p[0];
mPlaneEquation[1] = p[1];
mPlaneEquation[2] = p[2];
mPlaneEquation[3] = p[3];
}
mTesselationIndices = mTesselate->tesselate(mVertexIndex, mSourceTriangleCount, mIndices, mTessellateDistance, 6, mTessellateTriangleCount);

double mPlaneEquation[4]; // the plane equation
double mBmin[3]; // The AABB for the triangles at this plane equation
double mBmax[3];
TriangleIndexVector mTriangles; // the triangles associated with this plane equation
};

typedef std::vector< PlaneTriangles > PlaneTrianglesVector;

// Ok, the algorithm to compute constraints is kind of involved.
// What we are looking for is wherever two convex hulls 'touch'. However, 'touching' is
// an inexact thing; so what we really mean is 'pretty close to touching'.
class HullData
{
public:
HullData(void)
{
mBmin[0] = FLT_MAX;
mBmin[1] = FLT_MAX;
mBmin[2] = FLT_MAX;
mBmax[0] = -FLT_MAX;
mBmax[1] = -FLT_MAX;
mBmax[2] = -FLT_MAX;
}
uint32_t vcount = mVertexIndex->getVcount();
for (uint32_t i = 0; i < vcount; i++)
{
const double *p = mVertexIndex->getVertexDouble(i);
float fp[3];
FLOAT_MATH::fm_doubleToFloat3(p, fp);
gRenderDebug->debugPoint(fp, 0.05f);
}

void computeEpsilon(void)
{
// Compute the diagonal distance of the bounding box of this convex hull.
mLongEdge = FLOAT_MATH::fm_distance(mBmin, mBmax);
// Compute the distance epsilon as 1/100th the diagonal length.
// The purpose here is to keep epsilon computations somewhat unitless.
mDistanceEpsilon = mLongEdge / 100.0;
}

double mBmin[3];
double mBmax[3];
double mLongEdge;
double mDistanceEpsilon;
// Plane equations of this convex hull and the triangles which intersect it...
PlaneTrianglesVector mPlaneTriangles;
double mBmin[3];
double mBmax[3];
double mDiagonalDistance;
double mTessellateDistance;
double mPointResolution;
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];
Expand All @@ -1688,52 +1650,48 @@ uint32_t VHACD::ComputeConstraints(void)
const double *p = &ch.m_points[j * 3];
FLOAT_MATH::fm_minmax(p, hd.mBmin, hd.mBmax);
}

// Compute the epsilon distance threshold for this convex hull based on the diagonal distance of the bounding box
hd.computeEpsilon();

// Now compute plane equations and triangle statistics...
for (uint32_t j = 0; j < ch.m_nTriangles; j++)
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++)
{
const uint32_t *tri = (const uint32_t *)&ch.m_triangles[j * 3];
uint32_t i1 = tri[0];
uint32_t i2 = tri[1];
uint32_t i3 = tri[2];
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();
}

double planeEquation[4];
planeEquation[3] = FLOAT_MATH::fm_computePlane(p1, p2, p3, planeEquation);
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);
}

// ok... we now need to see if this plane equation matches any existing plane
bool foundPlane = false;
for (size_t k = 0; k < hd.mPlaneTriangles.size(); k++)
{
PlaneTriangles &pt = hd.mPlaneTriangles[k];
if (pt.planeMatch(planeEquation, hd.mDistanceEpsilon))
{
pt.addTriangle(j,p1, p2, p3);
foundPlane = true;
break;
}
}
if (!foundPlane)
// 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))
{
PlaneTriangles pt;
pt.setPlaneEquation(planeEquation);
pt.addTriangle(j, p1, p2, p3);
hd.mPlaneTriangles.push_back(pt);
}
}
#if DEBUG_VISUALIZE_CONSTRAINTS
if ( gRenderDebug )
{

}
#endif
}


#if DEBUG_VISUALIZE_CONSTRAINTS
gRenderDebug->popRenderState();
#endif
Expand Down

0 comments on commit f86204d

Please sign in to comment.