Merge pull request #1895 from erwincoumans/master
Code-style consistency improvement: _clang-format applied
This commit is contained in:
@@ -8,34 +8,32 @@
|
|||||||
#include "fitsphere.h"
|
#include "fitsphere.h"
|
||||||
#include "bestfitobb.h"
|
#include "bestfitobb.h"
|
||||||
|
|
||||||
unsigned int MAXDEPTH = 8 ;
|
unsigned int MAXDEPTH = 8;
|
||||||
float CONCAVE_PERCENT = 1.0f ;
|
float CONCAVE_PERCENT = 1.0f;
|
||||||
float MERGE_PERCENT = 2.0f ;
|
float MERGE_PERCENT = 2.0f;
|
||||||
|
|
||||||
CHull::CHull(const ConvexDecomposition::ConvexResult &result)
|
CHull::CHull(const ConvexDecomposition::ConvexResult &result)
|
||||||
{
|
{
|
||||||
mResult = new ConvexDecomposition::ConvexResult(result);
|
mResult = new ConvexDecomposition::ConvexResult(result);
|
||||||
mVolume = computeMeshVolume( result.mHullVertices, result.mHullTcount, result.mHullIndices );
|
mVolume = computeMeshVolume(result.mHullVertices, result.mHullTcount, result.mHullIndices);
|
||||||
|
|
||||||
mDiagonal = getBoundingRegion( result.mHullVcount, result.mHullVertices, sizeof(float)*3, mMin, mMax );
|
mDiagonal = getBoundingRegion(result.mHullVcount, result.mHullVertices, sizeof(float) * 3, mMin, mMax);
|
||||||
|
|
||||||
float dx = mMax[0] - mMin[0];
|
float dx = mMax[0] - mMin[0];
|
||||||
float dy = mMax[1] - mMin[1];
|
float dy = mMax[1] - mMin[1];
|
||||||
float dz = mMax[2] - mMin[2];
|
float dz = mMax[2] - mMin[2];
|
||||||
|
|
||||||
dx*=0.1f; // inflate 1/10th on each edge
|
dx *= 0.1f; // inflate 1/10th on each edge
|
||||||
dy*=0.1f; // inflate 1/10th on each edge
|
dy *= 0.1f; // inflate 1/10th on each edge
|
||||||
dz*=0.1f; // inflate 1/10th on each edge
|
dz *= 0.1f; // inflate 1/10th on each edge
|
||||||
|
|
||||||
mMin[0]-=dx;
|
|
||||||
mMin[1]-=dy;
|
|
||||||
mMin[2]-=dz;
|
|
||||||
|
|
||||||
mMax[0]+=dx;
|
|
||||||
mMax[1]+=dy;
|
|
||||||
mMax[2]+=dz;
|
|
||||||
|
|
||||||
|
mMin[0] -= dx;
|
||||||
|
mMin[1] -= dy;
|
||||||
|
mMin[2] -= dz;
|
||||||
|
|
||||||
|
mMax[0] += dx;
|
||||||
|
mMax[1] += dy;
|
||||||
|
mMax[2] += dz;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHull::~CHull(void)
|
CHull::~CHull(void)
|
||||||
@@ -45,12 +43,9 @@ CHull::~CHull(void)
|
|||||||
|
|
||||||
bool CHull::overlap(const CHull &h) const
|
bool CHull::overlap(const CHull &h) const
|
||||||
{
|
{
|
||||||
return overlapAABB(mMin,mMax, h.mMin, h.mMax );
|
return overlapAABB(mMin, mMax, h.mMin, h.mMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback)
|
ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback)
|
||||||
{
|
{
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
@@ -59,45 +54,45 @@ ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback)
|
|||||||
ConvexBuilder::~ConvexBuilder(void)
|
ConvexBuilder::~ConvexBuilder(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<mChulls.size();i++)
|
for (i = 0; i < mChulls.size(); i++)
|
||||||
{
|
{
|
||||||
CHull *cr = mChulls[i];
|
CHull *cr = mChulls[i];
|
||||||
delete cr;
|
delete cr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConvexBuilder::isDuplicate(unsigned int i1,unsigned int i2,unsigned int i3,
|
bool ConvexBuilder::isDuplicate(unsigned int i1, unsigned int i2, unsigned int i3,
|
||||||
unsigned int ci1,unsigned int ci2,unsigned int ci3)
|
unsigned int ci1, unsigned int ci2, unsigned int ci3)
|
||||||
{
|
{
|
||||||
unsigned int dcount = 0;
|
unsigned int dcount = 0;
|
||||||
|
|
||||||
assert( i1 != i2 && i1 != i3 && i2 != i3 );
|
assert(i1 != i2 && i1 != i3 && i2 != i3);
|
||||||
assert( ci1 != ci2 && ci1 != ci3 && ci2 != ci3 );
|
assert(ci1 != ci2 && ci1 != ci3 && ci2 != ci3);
|
||||||
|
|
||||||
if ( i1 == ci1 || i1 == ci2 || i1 == ci3 ) dcount++;
|
if (i1 == ci1 || i1 == ci2 || i1 == ci3) dcount++;
|
||||||
if ( i2 == ci1 || i2 == ci2 || i2 == ci3 ) dcount++;
|
if (i2 == ci1 || i2 == ci2 || i2 == ci3) dcount++;
|
||||||
if ( i3 == ci1 || i3 == ci2 || i3 == ci3 ) dcount++;
|
if (i3 == ci1 || i3 == ci2 || i3 == ci3) dcount++;
|
||||||
|
|
||||||
return dcount == 3;
|
return dcount == 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvexBuilder::getMesh(const ConvexDecomposition::ConvexResult &cr,VertexLookup vc,UintVector &indices)
|
void ConvexBuilder::getMesh(const ConvexDecomposition::ConvexResult &cr, VertexLookup vc, UintVector &indices)
|
||||||
{
|
{
|
||||||
unsigned int *src = cr.mHullIndices;
|
unsigned int *src = cr.mHullIndices;
|
||||||
|
|
||||||
for (unsigned int i=0; i<cr.mHullTcount; i++)
|
for (unsigned int i = 0; i < cr.mHullTcount; i++)
|
||||||
{
|
{
|
||||||
unsigned int i1 = *src++;
|
unsigned int i1 = *src++;
|
||||||
unsigned int i2 = *src++;
|
unsigned int i2 = *src++;
|
||||||
unsigned int i3 = *src++;
|
unsigned int i3 = *src++;
|
||||||
|
|
||||||
const float *p1 = &cr.mHullVertices[i1*3];
|
const float *p1 = &cr.mHullVertices[i1 * 3];
|
||||||
const float *p2 = &cr.mHullVertices[i2*3];
|
const float *p2 = &cr.mHullVertices[i2 * 3];
|
||||||
const float *p3 = &cr.mHullVertices[i3*3];
|
const float *p3 = &cr.mHullVertices[i3 * 3];
|
||||||
|
|
||||||
i1 = Vl_getIndex(vc,p1);
|
i1 = Vl_getIndex(vc, p1);
|
||||||
i2 = Vl_getIndex(vc,p2);
|
i2 = Vl_getIndex(vc, p2);
|
||||||
i3 = Vl_getIndex(vc,p3);
|
i3 = Vl_getIndex(vc, p3);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
bool duplicate = false;
|
bool duplicate = false;
|
||||||
@@ -122,14 +117,12 @@ void ConvexBuilder::getMesh(const ConvexDecomposition::ConvexResult &cr,VertexLo
|
|||||||
indices.push_back(i3);
|
indices.push_back(i3);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHull * ConvexBuilder::canMerge(CHull *a,CHull *b)
|
CHull *ConvexBuilder::canMerge(CHull *a, CHull *b)
|
||||||
{
|
{
|
||||||
|
if (!a->overlap(*b)) return 0; // if their AABB's (with a little slop) don't overlap, then return.
|
||||||
if ( !a->overlap(*b) ) return 0; // if their AABB's (with a little slop) don't overlap, then return.
|
|
||||||
|
|
||||||
CHull *ret = 0;
|
CHull *ret = 0;
|
||||||
|
|
||||||
@@ -140,17 +133,17 @@ CHull * ConvexBuilder::canMerge(CHull *a,CHull *b)
|
|||||||
|
|
||||||
UintVector indices;
|
UintVector indices;
|
||||||
|
|
||||||
getMesh( *a->mResult, vc, indices );
|
getMesh(*a->mResult, vc, indices);
|
||||||
getMesh( *b->mResult, vc, indices );
|
getMesh(*b->mResult, vc, indices);
|
||||||
|
|
||||||
unsigned int vcount = Vl_getVcount(vc);
|
unsigned int vcount = Vl_getVcount(vc);
|
||||||
const float *vertices = Vl_getVertices(vc);
|
const float *vertices = Vl_getVertices(vc);
|
||||||
unsigned int tcount = indices.size()/3;
|
unsigned int tcount = indices.size() / 3;
|
||||||
|
|
||||||
//don't do anything if hull is empty
|
//don't do anything if hull is empty
|
||||||
if (!tcount)
|
if (!tcount)
|
||||||
{
|
{
|
||||||
Vl_releaseVertexLookup (vc);
|
Vl_releaseVertexLookup(vc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,25 +155,23 @@ CHull * ConvexBuilder::canMerge(CHull *a,CHull *b)
|
|||||||
|
|
||||||
desc.mVcount = vcount;
|
desc.mVcount = vcount;
|
||||||
desc.mVertices = vertices;
|
desc.mVertices = vertices;
|
||||||
desc.mVertexStride = sizeof(float)*3;
|
desc.mVertexStride = sizeof(float) * 3;
|
||||||
|
|
||||||
ConvexDecomposition::HullError hret = hl.CreateConvexHull(desc,hresult);
|
ConvexDecomposition::HullError hret = hl.CreateConvexHull(desc, hresult);
|
||||||
|
|
||||||
if ( hret == ConvexDecomposition::QE_OK )
|
if (hret == ConvexDecomposition::QE_OK)
|
||||||
{
|
{
|
||||||
|
float combineVolume = computeMeshVolume(hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices);
|
||||||
float combineVolume = computeMeshVolume( hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices );
|
|
||||||
float sumVolume = a->mVolume + b->mVolume;
|
float sumVolume = a->mVolume + b->mVolume;
|
||||||
|
|
||||||
float percent = (sumVolume*100) / combineVolume;
|
float percent = (sumVolume * 100) / combineVolume;
|
||||||
if ( percent >= (100.0f-MERGE_PERCENT) )
|
if (percent >= (100.0f - MERGE_PERCENT))
|
||||||
{
|
{
|
||||||
ConvexDecomposition::ConvexResult cr(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices);
|
ConvexDecomposition::ConvexResult cr(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices);
|
||||||
ret = new CHull(cr);
|
ret = new CHull(cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vl_releaseVertexLookup(vc);
|
Vl_releaseVertexLookup(vc);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -188,41 +179,36 @@ CHull * ConvexBuilder::canMerge(CHull *a,CHull *b)
|
|||||||
|
|
||||||
bool ConvexBuilder::combineHulls(void)
|
bool ConvexBuilder::combineHulls(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool combine = false;
|
bool combine = false;
|
||||||
|
|
||||||
sortChulls(mChulls); // sort the convex hulls, largest volume to least...
|
sortChulls(mChulls); // sort the convex hulls, largest volume to least...
|
||||||
|
|
||||||
CHullVector output; // the output hulls...
|
CHullVector output; // the output hulls...
|
||||||
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0;i<mChulls.size() && !combine; ++i)
|
for (i = 0; i < mChulls.size() && !combine; ++i)
|
||||||
{
|
{
|
||||||
CHull *cr = mChulls[i];
|
CHull *cr = mChulls[i];
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for (j=0;j<mChulls.size();j++)
|
for (j = 0; j < mChulls.size(); j++)
|
||||||
{
|
{
|
||||||
CHull *match = mChulls[j];
|
CHull *match = mChulls[j];
|
||||||
|
|
||||||
if ( cr != match ) // don't try to merge a hull with itself, that be stoopid
|
if (cr != match) // don't try to merge a hull with itself, that be stoopid
|
||||||
{
|
{
|
||||||
|
CHull *merge = canMerge(cr, match); // if we can merge these two....
|
||||||
|
|
||||||
CHull *merge = canMerge(cr,match); // if we can merge these two....
|
if (merge)
|
||||||
|
|
||||||
if ( merge )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
output.push_back(merge);
|
output.push_back(merge);
|
||||||
|
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
while ( i != mChulls.size() )
|
while (i != mChulls.size())
|
||||||
{
|
{
|
||||||
CHull *cr = mChulls[i];
|
CHull *cr = mChulls[i];
|
||||||
if ( cr != match )
|
if (cr != match)
|
||||||
{
|
{
|
||||||
output.push_back(cr);
|
output.push_back(cr);
|
||||||
}
|
}
|
||||||
@@ -237,7 +223,7 @@ bool ConvexBuilder::combineHulls(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( combine )
|
if (combine)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -245,37 +231,33 @@ bool ConvexBuilder::combineHulls(void)
|
|||||||
{
|
{
|
||||||
output.push_back(cr);
|
output.push_back(cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( combine )
|
if (combine)
|
||||||
{
|
{
|
||||||
mChulls.clear();
|
mChulls.clear();
|
||||||
mChulls.copyFromArray(output);
|
mChulls.copyFromArray(output);
|
||||||
output.clear();
|
output.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return combine;
|
return combine;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ConvexBuilder::process(const ConvexDecomposition::DecompDesc &desc)
|
unsigned int ConvexBuilder::process(const ConvexDecomposition::DecompDesc &desc)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
|
|
||||||
MAXDEPTH = desc.mDepth;
|
MAXDEPTH = desc.mDepth;
|
||||||
CONCAVE_PERCENT = desc.mCpercent;
|
CONCAVE_PERCENT = desc.mCpercent;
|
||||||
MERGE_PERCENT = desc.mPpercent;
|
MERGE_PERCENT = desc.mPpercent;
|
||||||
|
|
||||||
|
calcConvexDecomposition(desc.mVcount, desc.mVertices, desc.mTcount, desc.mIndices, this, 0, 0);
|
||||||
|
|
||||||
calcConvexDecomposition(desc.mVcount, desc.mVertices, desc.mTcount, desc.mIndices,this,0,0);
|
while (combineHulls())
|
||||||
|
; // keep combinging hulls until I can't combine any more...
|
||||||
|
|
||||||
while ( combineHulls() ); // keep combinging hulls until I can't combine any more...
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<mChulls.size();i++)
|
for (i = 0; i < mChulls.size(); i++)
|
||||||
{
|
{
|
||||||
CHull *cr = mChulls[i];
|
CHull *cr = mChulls[i];
|
||||||
|
|
||||||
@@ -292,41 +274,39 @@ unsigned int ConvexBuilder::process(const ConvexDecomposition::DecompDesc &desc)
|
|||||||
|
|
||||||
hdesc.mVcount = c.mHullVcount;
|
hdesc.mVcount = c.mHullVcount;
|
||||||
hdesc.mVertices = c.mHullVertices;
|
hdesc.mVertices = c.mHullVertices;
|
||||||
hdesc.mVertexStride = sizeof(float)*3;
|
hdesc.mVertexStride = sizeof(float) * 3;
|
||||||
hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output
|
hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output
|
||||||
|
|
||||||
if ( desc.mSkinWidth )
|
if (desc.mSkinWidth)
|
||||||
{
|
{
|
||||||
hdesc.mSkinWidth = desc.mSkinWidth;
|
hdesc.mSkinWidth = desc.mSkinWidth;
|
||||||
hdesc.SetHullFlag(ConvexDecomposition::QF_SKIN_WIDTH); // do skin width computation.
|
hdesc.SetHullFlag(ConvexDecomposition::QF_SKIN_WIDTH); // do skin width computation.
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvexDecomposition::HullError ret = hl.CreateConvexHull(hdesc,result);
|
ConvexDecomposition::HullError ret = hl.CreateConvexHull(hdesc, result);
|
||||||
|
|
||||||
if ( ret == ConvexDecomposition::QE_OK )
|
if (ret == ConvexDecomposition::QE_OK)
|
||||||
{
|
{
|
||||||
ConvexDecomposition::ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);
|
ConvexDecomposition::ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);
|
||||||
|
|
||||||
r.mHullVolume = computeMeshVolume( result.mOutputVertices, result.mNumFaces, result.mIndices ); // the volume of the hull.
|
r.mHullVolume = computeMeshVolume(result.mOutputVertices, result.mNumFaces, result.mIndices); // the volume of the hull.
|
||||||
|
|
||||||
// compute the best fit OBB
|
// compute the best fit OBB
|
||||||
computeBestFitOBB( result.mNumOutputVertices, result.mOutputVertices, sizeof(float)*3, r.mOBBSides, r.mOBBTransform );
|
computeBestFitOBB(result.mNumOutputVertices, result.mOutputVertices, sizeof(float) * 3, r.mOBBSides, r.mOBBTransform);
|
||||||
|
|
||||||
r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] *r.mOBBSides[2]; // compute the OBB volume.
|
r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] * r.mOBBSides[2]; // compute the OBB volume.
|
||||||
|
|
||||||
fm_getTranslation( r.mOBBTransform, r.mOBBCenter ); // get the translation component of the 4x4 matrix.
|
fm_getTranslation(r.mOBBTransform, r.mOBBCenter); // get the translation component of the 4x4 matrix.
|
||||||
|
|
||||||
fm_matrixToQuat( r.mOBBTransform, r.mOBBOrientation ); // extract the orientation as a quaternion.
|
fm_matrixToQuat(r.mOBBTransform, r.mOBBOrientation); // extract the orientation as a quaternion.
|
||||||
|
|
||||||
r.mSphereRadius = computeBoundingSphere( result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter );
|
|
||||||
r.mSphereVolume = fm_sphereVolume( r.mSphereRadius );
|
|
||||||
|
|
||||||
|
r.mSphereRadius = computeBoundingSphere(result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter);
|
||||||
|
r.mSphereVolume = fm_sphereVolume(r.mSphereRadius);
|
||||||
|
|
||||||
mCallback->ConvexDecompResult(r);
|
mCallback->ConvexDecompResult(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
hl.ReleaseResult (result);
|
hl.ReleaseResult(result);
|
||||||
|
|
||||||
|
|
||||||
delete cr;
|
delete cr;
|
||||||
}
|
}
|
||||||
@@ -338,24 +318,23 @@ unsigned int ConvexBuilder::process(const ConvexDecomposition::DecompDesc &desc)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConvexBuilder::ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color)
|
||||||
void ConvexBuilder::ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color)
|
|
||||||
{
|
{
|
||||||
mCallback->ConvexDebugTri(p1,p2,p3,color);
|
mCallback->ConvexDebugTri(p1, p2, p3, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvexBuilder::ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color)
|
void ConvexBuilder::ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color)
|
||||||
{
|
{
|
||||||
mCallback->ConvexDebugOBB(sides,matrix,color);
|
mCallback->ConvexDebugOBB(sides, matrix, color);
|
||||||
}
|
}
|
||||||
void ConvexBuilder::ConvexDebugPoint(const float *p,float dist,unsigned int color)
|
void ConvexBuilder::ConvexDebugPoint(const float *p, float dist, unsigned int color)
|
||||||
{
|
{
|
||||||
mCallback->ConvexDebugPoint(p,dist,color);
|
mCallback->ConvexDebugPoint(p, dist, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvexBuilder::ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color)
|
void ConvexBuilder::ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color)
|
||||||
{
|
{
|
||||||
mCallback->ConvexDebugBound(bmin,bmax,color);
|
mCallback->ConvexDebugBound(bmin, bmax, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvexBuilder::ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
|
void ConvexBuilder::ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
|
||||||
@@ -369,5 +348,3 @@ void ConvexBuilder::sortChulls(CHullVector &hulls)
|
|||||||
hulls.quickSort(CHullSort());
|
hulls.quickSort(CHullSort());
|
||||||
//hulls.heapSort(CHullSort());
|
//hulls.heapSort(CHullSort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,12 +35,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "ConvexDecomposition.h"
|
#include "ConvexDecomposition.h"
|
||||||
#include "vlookup.h"
|
#include "vlookup.h"
|
||||||
#include "LinearMath/btAlignedObjectArray.h"
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
|
|
||||||
|
|
||||||
class CHull
|
class CHull
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -61,17 +59,13 @@ public:
|
|||||||
class CHullSort
|
class CHullSort
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
inline bool operator()(const CHull *a, const CHull *b) const
|
||||||
inline bool operator()(const CHull *a,const CHull *b) const
|
|
||||||
{
|
{
|
||||||
return a->mVolume < b->mVolume;
|
return a->mVolume < b->mVolume;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef btAlignedObjectArray<CHull *> CHullVector;
|
||||||
typedef btAlignedObjectArray< CHull * > CHullVector;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ConvexBuilder : public ConvexDecomposition::ConvexDecompInterface
|
class ConvexBuilder : public ConvexDecomposition::ConvexDecompInterface
|
||||||
{
|
{
|
||||||
@@ -80,23 +74,23 @@ public:
|
|||||||
|
|
||||||
virtual ~ConvexBuilder(void);
|
virtual ~ConvexBuilder(void);
|
||||||
|
|
||||||
bool isDuplicate(unsigned int i1,unsigned int i2,unsigned int i3,
|
bool isDuplicate(unsigned int i1, unsigned int i2, unsigned int i3,
|
||||||
unsigned int ci1,unsigned int ci2,unsigned int ci3);
|
unsigned int ci1, unsigned int ci2, unsigned int ci3);
|
||||||
|
|
||||||
void getMesh(const ConvexDecomposition::ConvexResult &cr,VertexLookup vc,UintVector &indices);
|
void getMesh(const ConvexDecomposition::ConvexResult &cr, VertexLookup vc, UintVector &indices);
|
||||||
|
|
||||||
CHull * canMerge(CHull *a,CHull *b);
|
CHull *canMerge(CHull *a, CHull *b);
|
||||||
|
|
||||||
bool combineHulls(void);
|
bool combineHulls(void);
|
||||||
|
|
||||||
unsigned int process(const ConvexDecomposition::DecompDesc &desc);
|
unsigned int process(const ConvexDecomposition::DecompDesc &desc);
|
||||||
|
|
||||||
virtual void ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color);
|
virtual void ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color);
|
||||||
|
|
||||||
virtual void ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color);
|
virtual void ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color);
|
||||||
virtual void ConvexDebugPoint(const float *p,float dist,unsigned int color);
|
virtual void ConvexDebugPoint(const float *p, float dist, unsigned int color);
|
||||||
|
|
||||||
virtual void ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color);
|
virtual void ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color);
|
||||||
|
|
||||||
virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result);
|
virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result);
|
||||||
|
|
||||||
@@ -107,4 +101,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif //CONVEX_BUILDER_H
|
#endif //CONVEX_BUILDER_H
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -56,42 +55,36 @@
|
|||||||
#define SHOW_MESH 0
|
#define SHOW_MESH 0
|
||||||
#define MAKE_MESH 1
|
#define MAKE_MESH 1
|
||||||
|
|
||||||
|
|
||||||
using namespace ConvexDecomposition;
|
using namespace ConvexDecomposition;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
|
||||||
class FaceTri
|
class FaceTri
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FaceTri(void) { };
|
FaceTri(void){};
|
||||||
FaceTri(const float *vertices,unsigned int i1,unsigned int i2,unsigned int i3)
|
FaceTri(const float *vertices, unsigned int i1, unsigned int i2, unsigned int i3)
|
||||||
{
|
{
|
||||||
mP1.Set( &vertices[i1*3] );
|
mP1.Set(&vertices[i1 * 3]);
|
||||||
mP2.Set( &vertices[i2*3] );
|
mP2.Set(&vertices[i2 * 3]);
|
||||||
mP3.Set( &vertices[i3*3] );
|
mP3.Set(&vertices[i3 * 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d mP1;
|
Vector3d mP1;
|
||||||
Vector3d mP2;
|
Vector3d mP2;
|
||||||
Vector3d mP3;
|
Vector3d mP3;
|
||||||
Vector3d mNormal;
|
Vector3d mNormal;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void addTri(VertexLookup vl, UintVector &list, const Vector3d &p1, const Vector3d &p2, const Vector3d &p3)
|
||||||
void addTri(VertexLookup vl,UintVector &list,const Vector3d &p1,const Vector3d &p2,const Vector3d &p3)
|
|
||||||
{
|
{
|
||||||
unsigned int i1 = Vl_getIndex(vl, p1.Ptr() );
|
unsigned int i1 = Vl_getIndex(vl, p1.Ptr());
|
||||||
unsigned int i2 = Vl_getIndex(vl, p2.Ptr() );
|
unsigned int i2 = Vl_getIndex(vl, p2.Ptr());
|
||||||
unsigned int i3 = Vl_getIndex(vl, p3.Ptr() );
|
unsigned int i3 = Vl_getIndex(vl, p3.Ptr());
|
||||||
|
|
||||||
// do *not* process degenerate triangles!
|
// do *not* process degenerate triangles!
|
||||||
|
|
||||||
if ( i1 != i2 && i1 != i3 && i2 != i3 )
|
if (i1 != i2 && i1 != i3 && i2 != i3)
|
||||||
{
|
{
|
||||||
list.push_back(i1);
|
list.push_back(i1);
|
||||||
list.push_back(i2);
|
list.push_back(i2);
|
||||||
@@ -99,7 +92,6 @@ void addTri(VertexLookup vl,UintVector &list,const Vector3d &p1,const Vector3d &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void calcConvexDecomposition(unsigned int vcount,
|
void calcConvexDecomposition(unsigned int vcount,
|
||||||
const float *vertices,
|
const float *vertices,
|
||||||
unsigned int tcount,
|
unsigned int tcount,
|
||||||
@@ -109,35 +101,30 @@ void calcConvexDecomposition(unsigned int vcount,
|
|||||||
unsigned int depth)
|
unsigned int depth)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
float plane[4];
|
float plane[4];
|
||||||
|
|
||||||
bool split = false;
|
bool split = false;
|
||||||
|
|
||||||
|
if (depth < MAXDEPTH)
|
||||||
if ( depth < MAXDEPTH )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
float volume;
|
float volume;
|
||||||
float c = computeConcavity( vcount, vertices, tcount, indices, callback, plane, volume );
|
float c = computeConcavity(vcount, vertices, tcount, indices, callback, plane, volume);
|
||||||
|
|
||||||
if ( depth == 0 )
|
if (depth == 0)
|
||||||
{
|
{
|
||||||
masterVolume = volume;
|
masterVolume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
float percent = (c*100.0f)/masterVolume;
|
float percent = (c * 100.0f) / masterVolume;
|
||||||
|
|
||||||
if ( percent > CONCAVE_PERCENT ) // if great than 5% of the total volume is concave, go ahead and keep splitting.
|
if (percent > CONCAVE_PERCENT) // if great than 5% of the total volume is concave, go ahead and keep splitting.
|
||||||
{
|
{
|
||||||
split = true;
|
split = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( depth >= MAXDEPTH || !split )
|
if (depth >= MAXDEPTH || !split)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
HullResult result;
|
HullResult result;
|
||||||
@@ -148,20 +135,17 @@ void calcConvexDecomposition(unsigned int vcount,
|
|||||||
|
|
||||||
desc.mVcount = vcount;
|
desc.mVcount = vcount;
|
||||||
desc.mVertices = vertices;
|
desc.mVertices = vertices;
|
||||||
desc.mVertexStride = sizeof(float)*3;
|
desc.mVertexStride = sizeof(float) * 3;
|
||||||
|
|
||||||
HullError ret = hl.CreateConvexHull(desc,result);
|
HullError ret = hl.CreateConvexHull(desc, result);
|
||||||
|
|
||||||
if ( ret == QE_OK )
|
if (ret == QE_OK)
|
||||||
{
|
{
|
||||||
|
|
||||||
ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);
|
ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);
|
||||||
|
|
||||||
|
|
||||||
callback->ConvexDecompResult(r);
|
callback->ConvexDecompResult(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static unsigned int colors[8] =
|
static unsigned int colors[8] =
|
||||||
@@ -173,38 +157,34 @@ void calcConvexDecomposition(unsigned int vcount,
|
|||||||
0x00FFFF,
|
0x00FFFF,
|
||||||
0xFF00FF,
|
0xFF00FF,
|
||||||
0xFFFFFF,
|
0xFFFFFF,
|
||||||
0xFF8040
|
0xFF8040};
|
||||||
};
|
|
||||||
|
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if ( count == 8 ) count = 0;
|
if (count == 8) count = 0;
|
||||||
|
|
||||||
assert( count >= 0 && count < 8 );
|
assert(count >= 0 && count < 8);
|
||||||
|
|
||||||
unsigned int color = colors[count];
|
unsigned int color = colors[count];
|
||||||
|
|
||||||
const unsigned int *source = indices;
|
const unsigned int *source = indices;
|
||||||
|
|
||||||
for (unsigned int i=0; i<tcount; i++)
|
for (unsigned int i = 0; i < tcount; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned int i1 = *source++;
|
unsigned int i1 = *source++;
|
||||||
unsigned int i2 = *source++;
|
unsigned int i2 = *source++;
|
||||||
unsigned int i3 = *source++;
|
unsigned int i3 = *source++;
|
||||||
|
|
||||||
FaceTri t(vertices, i1, i2, i3 );
|
FaceTri t(vertices, i1, i2, i3);
|
||||||
|
|
||||||
callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color );
|
|
||||||
|
|
||||||
|
callback->ConvexDebugTri(t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hl.ReleaseResult (result);
|
hl.ReleaseResult(result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UintVector ifront;
|
UintVector ifront;
|
||||||
@@ -213,24 +193,23 @@ void calcConvexDecomposition(unsigned int vcount,
|
|||||||
VertexLookup vfront = Vl_createVertexLookup();
|
VertexLookup vfront = Vl_createVertexLookup();
|
||||||
VertexLookup vback = Vl_createVertexLookup();
|
VertexLookup vback = Vl_createVertexLookup();
|
||||||
|
|
||||||
|
|
||||||
bool showmesh = false;
|
bool showmesh = false;
|
||||||
#if SHOW_MESH
|
#if SHOW_MESH
|
||||||
showmesh = true;
|
showmesh = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( 0 )
|
if (0)
|
||||||
{
|
{
|
||||||
showmesh = true;
|
showmesh = true;
|
||||||
for (float x=-1; x<1; x+=0.10f)
|
for (float x = -1; x < 1; x += 0.10f)
|
||||||
{
|
{
|
||||||
for (float y=0; y<1; y+=0.10f)
|
for (float y = 0; y < 1; y += 0.10f)
|
||||||
{
|
{
|
||||||
for (float z=-1; z<1; z+=0.04f)
|
for (float z = -1; z < 1; z += 0.04f)
|
||||||
{
|
{
|
||||||
float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
|
float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3];
|
||||||
Vector3d p(x,y,z);
|
Vector3d p(x, y, z);
|
||||||
if ( d >= 0 )
|
if (d >= 0)
|
||||||
callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00);
|
callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00);
|
||||||
else
|
else
|
||||||
callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000);
|
callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000);
|
||||||
@@ -239,98 +218,96 @@ void calcConvexDecomposition(unsigned int vcount,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 1 )
|
if (1)
|
||||||
{
|
{
|
||||||
// ok..now we are going to 'split' all of the input triangles against this plane!
|
// ok..now we are going to 'split' all of the input triangles against this plane!
|
||||||
const unsigned int *source = indices;
|
const unsigned int *source = indices;
|
||||||
for (unsigned int i=0; i<tcount; i++)
|
for (unsigned int i = 0; i < tcount; i++)
|
||||||
{
|
{
|
||||||
unsigned int i1 = *source++;
|
unsigned int i1 = *source++;
|
||||||
unsigned int i2 = *source++;
|
unsigned int i2 = *source++;
|
||||||
unsigned int i3 = *source++;
|
unsigned int i3 = *source++;
|
||||||
|
|
||||||
FaceTri t(vertices, i1, i2, i3 );
|
FaceTri t(vertices, i1, i2, i3);
|
||||||
|
|
||||||
Vector3d front[4];
|
Vector3d front[4];
|
||||||
Vector3d back[4];
|
Vector3d back[4];
|
||||||
|
|
||||||
unsigned int fcount=0;
|
unsigned int fcount = 0;
|
||||||
unsigned int bcount=0;
|
unsigned int bcount = 0;
|
||||||
|
|
||||||
PlaneTriResult result;
|
PlaneTriResult result;
|
||||||
|
|
||||||
result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount );
|
result = planeTriIntersection(plane, t.mP1.Ptr(), sizeof(Vector3d), 0.00001f, front[0].Ptr(), fcount, back[0].Ptr(), bcount);
|
||||||
|
|
||||||
if( fcount > 4 || bcount > 4 )
|
if (fcount > 4 || bcount > 4)
|
||||||
{
|
{
|
||||||
result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount );
|
result = planeTriIntersection(plane, t.mP1.Ptr(), sizeof(Vector3d), 0.00001f, front[0].Ptr(), fcount, back[0].Ptr(), bcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( result )
|
switch (result)
|
||||||
{
|
{
|
||||||
case PTR_FRONT:
|
case PTR_FRONT:
|
||||||
|
|
||||||
assert( fcount == 3 );
|
assert(fcount == 3);
|
||||||
|
|
||||||
if ( showmesh )
|
if (showmesh)
|
||||||
callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00 );
|
callback->ConvexDebugTri(front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00);
|
||||||
|
|
||||||
#if MAKE_MESH
|
#if MAKE_MESH
|
||||||
|
|
||||||
addTri( vfront, ifront, front[0], front[1], front[2] );
|
addTri(vfront, ifront, front[0], front[1], front[2]);
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PTR_BACK:
|
case PTR_BACK:
|
||||||
assert( bcount == 3 );
|
assert(bcount == 3);
|
||||||
|
|
||||||
if ( showmesh )
|
if (showmesh)
|
||||||
callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00 );
|
callback->ConvexDebugTri(back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00);
|
||||||
|
|
||||||
#if MAKE_MESH
|
#if MAKE_MESH
|
||||||
|
|
||||||
addTri( vback, iback, back[0], back[1], back[2] );
|
addTri(vback, iback, back[0], back[1], back[2]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PTR_SPLIT:
|
case PTR_SPLIT:
|
||||||
|
|
||||||
assert( fcount >= 3 && fcount <= 4);
|
assert(fcount >= 3 && fcount <= 4);
|
||||||
assert( bcount >= 3 && bcount <= 4);
|
assert(bcount >= 3 && bcount <= 4);
|
||||||
|
|
||||||
#if MAKE_MESH
|
#if MAKE_MESH
|
||||||
|
|
||||||
addTri( vfront, ifront, front[0], front[1], front[2] );
|
addTri(vfront, ifront, front[0], front[1], front[2]);
|
||||||
addTri( vback, iback, back[0], back[1], back[2] );
|
addTri(vback, iback, back[0], back[1], back[2]);
|
||||||
|
|
||||||
|
if (fcount == 4)
|
||||||
if ( fcount == 4 )
|
|
||||||
{
|
{
|
||||||
addTri( vfront, ifront, front[0], front[2], front[3] );
|
addTri(vfront, ifront, front[0], front[2], front[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bcount == 4 )
|
if (bcount == 4)
|
||||||
{
|
{
|
||||||
addTri( vback, iback, back[0], back[2], back[3] );
|
addTri(vback, iback, back[0], back[2], back[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( showmesh )
|
if (showmesh)
|
||||||
{
|
{
|
||||||
callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000 );
|
callback->ConvexDebugTri(front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000);
|
||||||
callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000 );
|
callback->ConvexDebugTri(back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000);
|
||||||
|
|
||||||
if ( fcount == 4 )
|
if (fcount == 4)
|
||||||
{
|
{
|
||||||
callback->ConvexDebugTri( front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000 );
|
callback->ConvexDebugTri(front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000);
|
||||||
}
|
}
|
||||||
if ( bcount == 4 )
|
if (bcount == 4)
|
||||||
{
|
{
|
||||||
callback->ConvexDebugTri( back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000 );
|
callback->ConvexDebugTri(back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,37 +316,31 @@ void calcConvexDecomposition(unsigned int vcount,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ok... here we recursively call
|
// ok... here we recursively call
|
||||||
if ( ifront.size() )
|
if (ifront.size())
|
||||||
{
|
{
|
||||||
unsigned int vcount = Vl_getVcount(vfront);
|
unsigned int vcount = Vl_getVcount(vfront);
|
||||||
const float *vertices = Vl_getVertices(vfront);
|
const float *vertices = Vl_getVertices(vfront);
|
||||||
unsigned int tcount = ifront.size()/3;
|
unsigned int tcount = ifront.size() / 3;
|
||||||
|
|
||||||
calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth+1);
|
|
||||||
|
|
||||||
|
calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ifront.clear();
|
ifront.clear();
|
||||||
|
|
||||||
Vl_releaseVertexLookup(vfront);
|
Vl_releaseVertexLookup(vfront);
|
||||||
|
|
||||||
if ( iback.size() )
|
if (iback.size())
|
||||||
{
|
{
|
||||||
unsigned int vcount = Vl_getVcount(vback);
|
unsigned int vcount = Vl_getVcount(vback);
|
||||||
const float *vertices = Vl_getVertices(vback);
|
const float *vertices = Vl_getVertices(vback);
|
||||||
unsigned int tcount = iback.size()/3;
|
unsigned int tcount = iback.size() / 3;
|
||||||
|
|
||||||
calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth+1);
|
|
||||||
|
|
||||||
|
calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
iback.clear();
|
iback.clear();
|
||||||
Vl_releaseVertexLookup(vback);
|
Vl_releaseVertexLookup(vback);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace ConvexDecomposition
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <memory.h> //memcpy
|
#include <memory.h> //memcpy
|
||||||
#endif
|
#endif
|
||||||
@@ -44,23 +43,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "LinearMath/btAlignedObjectArray.h"
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
|
|
||||||
|
extern unsigned int MAXDEPTH;
|
||||||
|
extern float CONCAVE_PERCENT;
|
||||||
|
extern float MERGE_PERCENT;
|
||||||
|
|
||||||
|
typedef btAlignedObjectArray<unsigned int> UintVector;
|
||||||
extern unsigned int MAXDEPTH ;
|
|
||||||
extern float CONCAVE_PERCENT ;
|
|
||||||
extern float MERGE_PERCENT ;
|
|
||||||
|
|
||||||
|
|
||||||
typedef btAlignedObjectArray< unsigned int > UintVector;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
class ConvexResult
|
||||||
class ConvexResult
|
{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
ConvexResult(void)
|
ConvexResult(void)
|
||||||
{
|
{
|
||||||
mHullVcount = 0;
|
mHullVcount = 0;
|
||||||
@@ -69,13 +62,13 @@ namespace ConvexDecomposition
|
|||||||
mHullIndices = 0;
|
mHullIndices = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvexResult(unsigned int hvcount,const float *hvertices,unsigned int htcount,const unsigned int *hindices)
|
ConvexResult(unsigned int hvcount, const float *hvertices, unsigned int htcount, const unsigned int *hindices)
|
||||||
{
|
{
|
||||||
mHullVcount = hvcount;
|
mHullVcount = hvcount;
|
||||||
if ( mHullVcount )
|
if (mHullVcount)
|
||||||
{
|
{
|
||||||
mHullVertices = new float[mHullVcount*sizeof(float)*3];
|
mHullVertices = new float[mHullVcount * sizeof(float) * 3];
|
||||||
memcpy(mHullVertices, hvertices, sizeof(float)*3*mHullVcount );
|
memcpy(mHullVertices, hvertices, sizeof(float) * 3 * mHullVcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -84,35 +77,34 @@ namespace ConvexDecomposition
|
|||||||
|
|
||||||
mHullTcount = htcount;
|
mHullTcount = htcount;
|
||||||
|
|
||||||
if ( mHullTcount )
|
if (mHullTcount)
|
||||||
{
|
{
|
||||||
mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3];
|
mHullIndices = new unsigned int[sizeof(unsigned int) * mHullTcount * 3];
|
||||||
memcpy(mHullIndices,hindices, sizeof(unsigned int)*mHullTcount*3 );
|
memcpy(mHullIndices, hindices, sizeof(unsigned int) * mHullTcount * 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mHullIndices = 0;
|
mHullIndices = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvexResult(const ConvexResult &r)
|
ConvexResult(const ConvexResult &r)
|
||||||
{
|
{
|
||||||
mHullVcount = r.mHullVcount;
|
mHullVcount = r.mHullVcount;
|
||||||
if ( mHullVcount )
|
if (mHullVcount)
|
||||||
{
|
{
|
||||||
mHullVertices = new float[mHullVcount*sizeof(float)*3];
|
mHullVertices = new float[mHullVcount * sizeof(float) * 3];
|
||||||
memcpy(mHullVertices, r.mHullVertices, sizeof(float)*3*mHullVcount );
|
memcpy(mHullVertices, r.mHullVertices, sizeof(float) * 3 * mHullVcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mHullVertices = 0;
|
mHullVertices = 0;
|
||||||
}
|
}
|
||||||
mHullTcount = r.mHullTcount;
|
mHullTcount = r.mHullTcount;
|
||||||
if ( mHullTcount )
|
if (mHullTcount)
|
||||||
{
|
{
|
||||||
mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3];
|
mHullIndices = new unsigned int[sizeof(unsigned int) * mHullTcount * 3];
|
||||||
memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int)*mHullTcount*3 );
|
memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int) * mHullTcount * 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -122,13 +114,13 @@ namespace ConvexDecomposition
|
|||||||
|
|
||||||
~ConvexResult(void)
|
~ConvexResult(void)
|
||||||
{
|
{
|
||||||
delete [] mHullVertices;
|
delete[] mHullVertices;
|
||||||
delete [] mHullIndices;
|
delete[] mHullIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the convex hull.
|
// the convex hull.
|
||||||
unsigned int mHullVcount;
|
unsigned int mHullVcount;
|
||||||
float * mHullVertices;
|
float *mHullVertices;
|
||||||
unsigned int mHullTcount;
|
unsigned int mHullTcount;
|
||||||
unsigned int *mHullIndices;
|
unsigned int *mHullIndices;
|
||||||
|
|
||||||
@@ -143,31 +135,25 @@ namespace ConvexDecomposition
|
|||||||
float mSphereRadius; // radius and center of best fit sphere
|
float mSphereRadius; // radius and center of best fit sphere
|
||||||
float mSphereCenter[3];
|
float mSphereCenter[3];
|
||||||
float mSphereVolume; // volume of the best fit sphere
|
float mSphereVolume; // volume of the best fit sphere
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConvexDecompInterface
|
||||||
|
{
|
||||||
};
|
public:
|
||||||
|
virtual ~ConvexDecompInterface(){};
|
||||||
class ConvexDecompInterface
|
virtual void ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color){};
|
||||||
{
|
virtual void ConvexDebugPoint(const float *p, float dist, unsigned int color){};
|
||||||
public:
|
virtual void ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color){};
|
||||||
virtual ~ConvexDecompInterface() {};
|
virtual void ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color){};
|
||||||
virtual void ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color) { };
|
|
||||||
virtual void ConvexDebugPoint(const float *p,float dist,unsigned int color) { };
|
|
||||||
virtual void ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color) { };
|
|
||||||
virtual void ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color) { };
|
|
||||||
|
|
||||||
virtual void ConvexDecompResult(ConvexResult &result) = 0;
|
virtual void ConvexDecompResult(ConvexResult &result) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// just to avoid passing a zillion parameters to the method the
|
||||||
|
// options are packed into this descriptor.
|
||||||
};
|
class DecompDesc
|
||||||
|
{
|
||||||
// just to avoid passing a zillion parameters to the method the
|
public:
|
||||||
// options are packed into this descriptor.
|
|
||||||
class DecompDesc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DecompDesc(void)
|
DecompDesc(void)
|
||||||
{
|
{
|
||||||
mVcount = 0;
|
mVcount = 0;
|
||||||
@@ -198,14 +184,12 @@ namespace ConvexDecomposition
|
|||||||
float mSkinWidth; // a skin width to apply to the output hulls.
|
float mSkinWidth; // a skin width to apply to the output hulls.
|
||||||
|
|
||||||
ConvexDecompInterface *mCallback; // the interface to receive back the results.
|
ConvexDecompInterface *mCallback; // the interface to receive back the results.
|
||||||
|
};
|
||||||
|
|
||||||
};
|
// perform approximate convex decomposition on a mesh.
|
||||||
|
unsigned int performConvexDecomposition(const DecompDesc &desc); // returns the number of hulls produced.
|
||||||
|
|
||||||
// perform approximate convex decomposition on a mesh.
|
void calcConvexDecomposition(unsigned int vcount,
|
||||||
unsigned int performConvexDecomposition(const DecompDesc &desc); // returns the number of hulls produced.
|
|
||||||
|
|
||||||
|
|
||||||
void calcConvexDecomposition(unsigned int vcount,
|
|
||||||
const float *vertices,
|
const float *vertices,
|
||||||
unsigned int tcount,
|
unsigned int tcount,
|
||||||
const unsigned int *indices,
|
const unsigned int *indices,
|
||||||
@@ -213,8 +197,6 @@ namespace ConvexDecomposition
|
|||||||
float masterVolume,
|
float masterVolume,
|
||||||
unsigned int depth);
|
unsigned int depth);
|
||||||
|
|
||||||
|
} // namespace ConvexDecomposition
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -52,17 +52,20 @@
|
|||||||
|
|
||||||
namespace BestFit
|
namespace BestFit
|
||||||
{
|
{
|
||||||
|
|
||||||
class Vec3
|
class Vec3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Vec3(void) { };
|
Vec3(void){};
|
||||||
Vec3(float _x,float _y,float _z) { x = _x; y = _y; z = _z; };
|
Vec3(float _x, float _y, float _z)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
z = _z;
|
||||||
|
};
|
||||||
|
|
||||||
float dot(const Vec3 &v)
|
float dot(const Vec3 &v)
|
||||||
{
|
{
|
||||||
return x*v.x + y*v.y + z*v.z; // the dot product
|
return x * v.x + y * v.y + z * v.z; // the dot product
|
||||||
}
|
}
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
@@ -70,12 +73,9 @@ public:
|
|||||||
float z;
|
float z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Eigen
|
class Eigen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
void DecrSortEigenStuff(void)
|
void DecrSortEigenStuff(void)
|
||||||
{
|
{
|
||||||
Tridiagonal(); //diagonalize the matrix.
|
Tridiagonal(); //diagonalize the matrix.
|
||||||
@@ -97,15 +97,15 @@ public:
|
|||||||
m_afSubd[2] = 0;
|
m_afSubd[2] = 0;
|
||||||
if (fM02 != (float)0.0)
|
if (fM02 != (float)0.0)
|
||||||
{
|
{
|
||||||
float fLength = sqrtf(fM01*fM01+fM02*fM02);
|
float fLength = sqrtf(fM01 * fM01 + fM02 * fM02);
|
||||||
float fInvLength = ((float)1.0)/fLength;
|
float fInvLength = ((float)1.0) / fLength;
|
||||||
fM01 *= fInvLength;
|
fM01 *= fInvLength;
|
||||||
fM02 *= fInvLength;
|
fM02 *= fInvLength;
|
||||||
float fQ = ((float)2.0)*fM01*fM12+fM02*(fM22-fM11);
|
float fQ = ((float)2.0) * fM01 * fM12 + fM02 * (fM22 - fM11);
|
||||||
m_afDiag[1] = fM11+fM02*fQ;
|
m_afDiag[1] = fM11 + fM02 * fQ;
|
||||||
m_afDiag[2] = fM22-fM02*fQ;
|
m_afDiag[2] = fM22 - fM02 * fQ;
|
||||||
m_afSubd[0] = fLength;
|
m_afSubd[0] = fLength;
|
||||||
m_afSubd[1] = fM12-fM01*fQ;
|
m_afSubd[1] = fM12 - fM01 * fQ;
|
||||||
mElement[0][0] = (float)1.0;
|
mElement[0][0] = (float)1.0;
|
||||||
mElement[0][1] = (float)0.0;
|
mElement[0][1] = (float)0.0;
|
||||||
mElement[0][2] = (float)0.0;
|
mElement[0][2] = (float)0.0;
|
||||||
@@ -140,16 +140,16 @@ public:
|
|||||||
{
|
{
|
||||||
const int iMaxIter = 32;
|
const int iMaxIter = 32;
|
||||||
|
|
||||||
for (int i0 = 0; i0 <3; i0++)
|
for (int i0 = 0; i0 < 3; i0++)
|
||||||
{
|
{
|
||||||
int i1;
|
int i1;
|
||||||
for (i1 = 0; i1 < iMaxIter; i1++)
|
for (i1 = 0; i1 < iMaxIter; i1++)
|
||||||
{
|
{
|
||||||
int i2;
|
int i2;
|
||||||
for (i2 = i0; i2 <= (3-2); i2++)
|
for (i2 = i0; i2 <= (3 - 2); i2++)
|
||||||
{
|
{
|
||||||
float fTmp = fabsf(m_afDiag[i2]) + fabsf(m_afDiag[i2+1]);
|
float fTmp = fabsf(m_afDiag[i2]) + fabsf(m_afDiag[i2 + 1]);
|
||||||
if ( fabsf(m_afSubd[i2]) + fTmp == fTmp )
|
if (fabsf(m_afSubd[i2]) + fTmp == fTmp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i2 == i0)
|
if (i2 == i0)
|
||||||
@@ -157,47 +157,47 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float fG = (m_afDiag[i0+1] - m_afDiag[i0])/(((float)2.0) * m_afSubd[i0]);
|
float fG = (m_afDiag[i0 + 1] - m_afDiag[i0]) / (((float)2.0) * m_afSubd[i0]);
|
||||||
float fR = sqrtf(fG*fG+(float)1.0);
|
float fR = sqrtf(fG * fG + (float)1.0);
|
||||||
if (fG < (float)0.0)
|
if (fG < (float)0.0)
|
||||||
{
|
{
|
||||||
fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR);
|
fG = m_afDiag[i2] - m_afDiag[i0] + m_afSubd[i0] / (fG - fR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR);
|
fG = m_afDiag[i2] - m_afDiag[i0] + m_afSubd[i0] / (fG + fR);
|
||||||
}
|
}
|
||||||
float fSin = (float)1.0, fCos = (float)1.0, fP = (float)0.0;
|
float fSin = (float)1.0, fCos = (float)1.0, fP = (float)0.0;
|
||||||
for (int i3 = i2-1; i3 >= i0; i3--)
|
for (int i3 = i2 - 1; i3 >= i0; i3--)
|
||||||
{
|
{
|
||||||
float fF = fSin*m_afSubd[i3];
|
float fF = fSin * m_afSubd[i3];
|
||||||
float fB = fCos*m_afSubd[i3];
|
float fB = fCos * m_afSubd[i3];
|
||||||
if (fabsf(fF) >= fabsf(fG))
|
if (fabsf(fF) >= fabsf(fG))
|
||||||
{
|
{
|
||||||
fCos = fG/fF;
|
fCos = fG / fF;
|
||||||
fR = sqrtf(fCos*fCos+(float)1.0);
|
fR = sqrtf(fCos * fCos + (float)1.0);
|
||||||
m_afSubd[i3+1] = fF*fR;
|
m_afSubd[i3 + 1] = fF * fR;
|
||||||
fSin = ((float)1.0)/fR;
|
fSin = ((float)1.0) / fR;
|
||||||
fCos *= fSin;
|
fCos *= fSin;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fSin = fF/fG;
|
fSin = fF / fG;
|
||||||
fR = sqrtf(fSin*fSin+(float)1.0);
|
fR = sqrtf(fSin * fSin + (float)1.0);
|
||||||
m_afSubd[i3+1] = fG*fR;
|
m_afSubd[i3 + 1] = fG * fR;
|
||||||
fCos = ((float)1.0)/fR;
|
fCos = ((float)1.0) / fR;
|
||||||
fSin *= fCos;
|
fSin *= fCos;
|
||||||
}
|
}
|
||||||
fG = m_afDiag[i3+1]-fP;
|
fG = m_afDiag[i3 + 1] - fP;
|
||||||
fR = (m_afDiag[i3]-fG)*fSin+((float)2.0)*fB*fCos;
|
fR = (m_afDiag[i3] - fG) * fSin + ((float)2.0) * fB * fCos;
|
||||||
fP = fSin*fR;
|
fP = fSin * fR;
|
||||||
m_afDiag[i3+1] = fG+fP;
|
m_afDiag[i3 + 1] = fG + fP;
|
||||||
fG = fCos*fR-fB;
|
fG = fCos * fR - fB;
|
||||||
for (int i4 = 0; i4 < 3; i4++)
|
for (int i4 = 0; i4 < 3; i4++)
|
||||||
{
|
{
|
||||||
fF = mElement[i4][i3+1];
|
fF = mElement[i4][i3 + 1];
|
||||||
mElement[i4][i3+1] = fSin*mElement[i4][i3]+fCos*fF;
|
mElement[i4][i3 + 1] = fSin * mElement[i4][i3] + fCos * fF;
|
||||||
mElement[i4][i3] = fCos*mElement[i4][i3]-fSin*fF;
|
mElement[i4][i3] = fCos * mElement[i4][i3] - fSin * fF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_afDiag[i0] -= fP;
|
m_afDiag[i0] -= fP;
|
||||||
@@ -215,13 +215,13 @@ public:
|
|||||||
void DecreasingSort(void)
|
void DecreasingSort(void)
|
||||||
{
|
{
|
||||||
//sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1]
|
//sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1]
|
||||||
for (int i0 = 0, i1; i0 <= 3-2; i0++)
|
for (int i0 = 0, i1; i0 <= 3 - 2; i0++)
|
||||||
{
|
{
|
||||||
// locate maximum eigenvalue
|
// locate maximum eigenvalue
|
||||||
i1 = i0;
|
i1 = i0;
|
||||||
float fMax = m_afDiag[i1];
|
float fMax = m_afDiag[i1];
|
||||||
int i2;
|
int i2;
|
||||||
for (i2 = i0+1; i2 < 3; i2++)
|
for (i2 = i0 + 1; i2 < 3; i2++)
|
||||||
{
|
{
|
||||||
if (m_afDiag[i2] > fMax)
|
if (m_afDiag[i2] > fMax)
|
||||||
{
|
{
|
||||||
@@ -247,13 +247,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuaranteeRotation(void)
|
void GuaranteeRotation(void)
|
||||||
{
|
{
|
||||||
if (!m_bIsRotation)
|
if (!m_bIsRotation)
|
||||||
{
|
{
|
||||||
// change sign on the first column
|
// change sign on the first column
|
||||||
for (int iRow = 0; iRow <3; iRow++)
|
for (int iRow = 0; iRow < 3; iRow++)
|
||||||
{
|
{
|
||||||
mElement[iRow][0] = -mElement[iRow][0];
|
mElement[iRow][0] = -mElement[iRow][0];
|
||||||
}
|
}
|
||||||
@@ -266,12 +265,10 @@ public:
|
|||||||
bool m_bIsRotation;
|
bool m_bIsRotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace BestFit
|
||||||
|
|
||||||
|
|
||||||
using namespace BestFit;
|
using namespace BestFit;
|
||||||
|
|
||||||
|
|
||||||
bool getBestFitPlane(unsigned int vcount,
|
bool getBestFitPlane(unsigned int vcount,
|
||||||
const float *points,
|
const float *points,
|
||||||
unsigned int vstride,
|
unsigned int vstride,
|
||||||
@@ -281,90 +278,85 @@ bool getBestFitPlane(unsigned int vcount,
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
Vec3 kOrigin(0,0,0);
|
Vec3 kOrigin(0, 0, 0);
|
||||||
|
|
||||||
float wtotal = 0;
|
float wtotal = 0;
|
||||||
|
|
||||||
if ( 1 )
|
if (1)
|
||||||
{
|
{
|
||||||
const char *source = (const char *) points;
|
const char *source = (const char *)points;
|
||||||
const char *wsource = (const char *) weights;
|
const char *wsource = (const char *)weights;
|
||||||
|
|
||||||
for (unsigned int i=0; i<vcount; i++)
|
for (unsigned int i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
|
const float *p = (const float *)source;
|
||||||
const float *p = (const float *) source;
|
|
||||||
|
|
||||||
float w = 1;
|
float w = 1;
|
||||||
|
|
||||||
if ( wsource )
|
if (wsource)
|
||||||
{
|
{
|
||||||
const float *ws = (const float *) wsource;
|
const float *ws = (const float *)wsource;
|
||||||
w = *ws; //
|
w = *ws; //
|
||||||
wsource+=wstride;
|
wsource += wstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
kOrigin.x+=p[0]*w;
|
kOrigin.x += p[0] * w;
|
||||||
kOrigin.y+=p[1]*w;
|
kOrigin.y += p[1] * w;
|
||||||
kOrigin.z+=p[2]*w;
|
kOrigin.z += p[2] * w;
|
||||||
|
|
||||||
wtotal+=w;
|
wtotal += w;
|
||||||
|
|
||||||
source+=vstride;
|
source += vstride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float recip = 1.0f / wtotal; // reciprocol of total weighting
|
float recip = 1.0f / wtotal; // reciprocol of total weighting
|
||||||
|
|
||||||
kOrigin.x*=recip;
|
kOrigin.x *= recip;
|
||||||
kOrigin.y*=recip;
|
kOrigin.y *= recip;
|
||||||
kOrigin.z*=recip;
|
kOrigin.z *= recip;
|
||||||
|
|
||||||
|
float fSumXX = 0;
|
||||||
|
float fSumXY = 0;
|
||||||
|
float fSumXZ = 0;
|
||||||
|
|
||||||
float fSumXX=0;
|
float fSumYY = 0;
|
||||||
float fSumXY=0;
|
float fSumYZ = 0;
|
||||||
float fSumXZ=0;
|
float fSumZZ = 0;
|
||||||
|
|
||||||
float fSumYY=0;
|
if (1)
|
||||||
float fSumYZ=0;
|
|
||||||
float fSumZZ=0;
|
|
||||||
|
|
||||||
|
|
||||||
if ( 1 )
|
|
||||||
{
|
{
|
||||||
const char *source = (const char *) points;
|
const char *source = (const char *)points;
|
||||||
const char *wsource = (const char *) weights;
|
const char *wsource = (const char *)weights;
|
||||||
|
|
||||||
for (unsigned int i=0; i<vcount; i++)
|
for (unsigned int i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
|
const float *p = (const float *)source;
|
||||||
const float *p = (const float *) source;
|
|
||||||
|
|
||||||
float w = 1;
|
float w = 1;
|
||||||
|
|
||||||
if ( wsource )
|
if (wsource)
|
||||||
{
|
{
|
||||||
const float *ws = (const float *) wsource;
|
const float *ws = (const float *)wsource;
|
||||||
w = *ws; //
|
w = *ws; //
|
||||||
wsource+=wstride;
|
wsource += wstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 kDiff;
|
Vec3 kDiff;
|
||||||
|
|
||||||
kDiff.x = w*(p[0] - kOrigin.x); // apply vertex weighting!
|
kDiff.x = w * (p[0] - kOrigin.x); // apply vertex weighting!
|
||||||
kDiff.y = w*(p[1] - kOrigin.y);
|
kDiff.y = w * (p[1] - kOrigin.y);
|
||||||
kDiff.z = w*(p[2] - kOrigin.z);
|
kDiff.z = w * (p[2] - kOrigin.z);
|
||||||
|
|
||||||
fSumXX+= kDiff.x * kDiff.x; // sume of the squares of the differences.
|
fSumXX += kDiff.x * kDiff.x; // sume of the squares of the differences.
|
||||||
fSumXY+= kDiff.x * kDiff.y; // sume of the squares of the differences.
|
fSumXY += kDiff.x * kDiff.y; // sume of the squares of the differences.
|
||||||
fSumXZ+= kDiff.x * kDiff.z; // sume of the squares of the differences.
|
fSumXZ += kDiff.x * kDiff.z; // sume of the squares of the differences.
|
||||||
|
|
||||||
fSumYY+= kDiff.y * kDiff.y;
|
fSumYY += kDiff.y * kDiff.y;
|
||||||
fSumYZ+= kDiff.y * kDiff.z;
|
fSumYZ += kDiff.y * kDiff.z;
|
||||||
fSumZZ+= kDiff.z * kDiff.z;
|
fSumZZ += kDiff.z * kDiff.z;
|
||||||
|
|
||||||
|
source += vstride;
|
||||||
source+=vstride;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,12 +401,9 @@ bool getBestFitPlane(unsigned int vcount,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getBoundingRegion(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax) // returns the diagonal distance
|
||||||
|
|
||||||
float getBoundingRegion(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax) // returns the diagonal distance
|
|
||||||
{
|
{
|
||||||
|
const unsigned char *source = (const unsigned char *)points;
|
||||||
const unsigned char *source = (const unsigned char *) points;
|
|
||||||
|
|
||||||
bmin[0] = points[0];
|
bmin[0] = points[0];
|
||||||
bmin[1] = points[1];
|
bmin[1] = points[1];
|
||||||
@@ -424,43 +413,36 @@ float getBoundingRegion(unsigned int vcount,const float *points,unsigned int pst
|
|||||||
bmax[1] = points[1];
|
bmax[1] = points[1];
|
||||||
bmax[2] = points[2];
|
bmax[2] = points[2];
|
||||||
|
|
||||||
|
for (unsigned int i = 1; i < vcount; i++)
|
||||||
for (unsigned int i=1; i<vcount; i++)
|
|
||||||
{
|
{
|
||||||
source+=pstride;
|
source += pstride;
|
||||||
const float *p = (const float *) source;
|
const float *p = (const float *)source;
|
||||||
|
|
||||||
if ( p[0] < bmin[0] ) bmin[0] = p[0];
|
if (p[0] < bmin[0]) bmin[0] = p[0];
|
||||||
if ( p[1] < bmin[1] ) bmin[1] = p[1];
|
if (p[1] < bmin[1]) bmin[1] = p[1];
|
||||||
if ( p[2] < bmin[2] ) bmin[2] = p[2];
|
if (p[2] < bmin[2]) bmin[2] = p[2];
|
||||||
|
|
||||||
if ( p[0] > bmax[0] ) bmax[0] = p[0];
|
|
||||||
if ( p[1] > bmax[1] ) bmax[1] = p[1];
|
|
||||||
if ( p[2] > bmax[2] ) bmax[2] = p[2];
|
|
||||||
|
|
||||||
|
if (p[0] > bmax[0]) bmax[0] = p[0];
|
||||||
|
if (p[1] > bmax[1]) bmax[1] = p[1];
|
||||||
|
if (p[2] > bmax[2]) bmax[2] = p[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float dx = bmax[0] - bmin[0];
|
float dx = bmax[0] - bmin[0];
|
||||||
float dy = bmax[1] - bmin[1];
|
float dy = bmax[1] - bmin[1];
|
||||||
float dz = bmax[2] - bmin[2];
|
float dz = bmax[2] - bmin[2];
|
||||||
|
|
||||||
return sqrtf( dx*dx + dy*dy + dz*dz );
|
return sqrtf(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool overlapAABB(const float *bmin1, const float *bmax1, const float *bmin2, const float *bmax2) // return true if the two AABB's overlap.
|
||||||
bool overlapAABB(const float *bmin1,const float *bmax1,const float *bmin2,const float *bmax2) // return true if the two AABB's overlap.
|
|
||||||
{
|
{
|
||||||
if ( bmax2[0] < bmin1[0] ) return false; // if the maximum is less than our minimum on any axis
|
if (bmax2[0] < bmin1[0]) return false; // if the maximum is less than our minimum on any axis
|
||||||
if ( bmax2[1] < bmin1[1] ) return false;
|
if (bmax2[1] < bmin1[1]) return false;
|
||||||
if ( bmax2[2] < bmin1[2] ) return false;
|
if (bmax2[2] < bmin1[2]) return false;
|
||||||
|
|
||||||
if ( bmin2[0] > bmax1[0] ) return false; // if the minimum is greater than our maximum on any axis
|
|
||||||
if ( bmin2[1] > bmax1[1] ) return false; // if the minimum is greater than our maximum on any axis
|
|
||||||
if ( bmin2[2] > bmax1[2] ) return false; // if the minimum is greater than our maximum on any axis
|
|
||||||
|
|
||||||
|
if (bmin2[0] > bmax1[0]) return false; // if the minimum is greater than our maximum on any axis
|
||||||
|
if (bmin2[1] > bmax1[1]) return false; // if the minimum is greater than our maximum on any axis
|
||||||
|
if (bmin2[2] > bmax1[2]) return false; // if the minimum is greater than our maximum on any axis
|
||||||
|
|
||||||
return true; // the extents overlap
|
return true; // the extents overlap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
// This routine was released in 'snippet' form
|
// This routine was released in 'snippet' form
|
||||||
// by John W. Ratcliff mailto:jratcliff@infiniplex.net
|
// by John W. Ratcliff mailto:jratcliff@infiniplex.net
|
||||||
// on March 22, 2006.
|
// on March 22, 2006.
|
||||||
@@ -58,8 +57,7 @@ bool getBestFitPlane(unsigned int vcount, // number of input data points
|
|||||||
unsigned int wstride, // weight stride for each vertex.
|
unsigned int wstride, // weight stride for each vertex.
|
||||||
float *plane);
|
float *plane);
|
||||||
|
|
||||||
|
float getBoundingRegion(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax); // returns the diagonal distance
|
||||||
float getBoundingRegion(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax); // returns the diagonal distance
|
bool overlapAABB(const float *bmin1, const float *bmax1, const float *bmin2, const float *bmax2); // return true if the two AABB's overlap.
|
||||||
bool overlapAABB(const float *bmin1,const float *bmax1,const float *bmin2,const float *bmax2); // return true if the two AABB's overlap.
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,59 +44,56 @@
|
|||||||
#include "float_math.h"
|
#include "float_math.h"
|
||||||
|
|
||||||
// computes the OBB for this set of points relative to this transform matrix.
|
// computes the OBB for this set of points relative to this transform matrix.
|
||||||
void computeOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,const float *matrix)
|
void computeOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, const float *matrix)
|
||||||
{
|
{
|
||||||
const char *src = (const char *) points;
|
const char *src = (const char *)points;
|
||||||
|
|
||||||
float bmin[3] = { 1e9, 1e9, 1e9 };
|
float bmin[3] = {1e9, 1e9, 1e9};
|
||||||
float bmax[3] = { -1e9, -1e9, -1e9 };
|
float bmax[3] = {-1e9, -1e9, -1e9};
|
||||||
|
|
||||||
for (unsigned int i=0; i<vcount; i++)
|
for (unsigned int i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
const float *p = (const float *) src;
|
const float *p = (const float *)src;
|
||||||
float t[3];
|
float t[3];
|
||||||
|
|
||||||
fm_inverseRT(matrix, p, t ); // inverse rotate translate
|
fm_inverseRT(matrix, p, t); // inverse rotate translate
|
||||||
|
|
||||||
if ( t[0] < bmin[0] ) bmin[0] = t[0];
|
if (t[0] < bmin[0]) bmin[0] = t[0];
|
||||||
if ( t[1] < bmin[1] ) bmin[1] = t[1];
|
if (t[1] < bmin[1]) bmin[1] = t[1];
|
||||||
if ( t[2] < bmin[2] ) bmin[2] = t[2];
|
if (t[2] < bmin[2]) bmin[2] = t[2];
|
||||||
|
|
||||||
if ( t[0] > bmax[0] ) bmax[0] = t[0];
|
if (t[0] > bmax[0]) bmax[0] = t[0];
|
||||||
if ( t[1] > bmax[1] ) bmax[1] = t[1];
|
if (t[1] > bmax[1]) bmax[1] = t[1];
|
||||||
if ( t[2] > bmax[2] ) bmax[2] = t[2];
|
if (t[2] > bmax[2]) bmax[2] = t[2];
|
||||||
|
|
||||||
src+=pstride;
|
src += pstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sides[0] = bmax[0];
|
sides[0] = bmax[0];
|
||||||
sides[1] = bmax[1];
|
sides[1] = bmax[1];
|
||||||
sides[2] = bmax[2];
|
sides[2] = bmax[2];
|
||||||
|
|
||||||
if ( fabsf(bmin[0]) > sides[0] ) sides[0] = fabsf(bmin[0]);
|
if (fabsf(bmin[0]) > sides[0]) sides[0] = fabsf(bmin[0]);
|
||||||
if ( fabsf(bmin[1]) > sides[1] ) sides[1] = fabsf(bmin[1]);
|
if (fabsf(bmin[1]) > sides[1]) sides[1] = fabsf(bmin[1]);
|
||||||
if ( fabsf(bmin[2]) > sides[2] ) sides[2] = fabsf(bmin[2]);
|
if (fabsf(bmin[2]) > sides[2]) sides[2] = fabsf(bmin[2]);
|
||||||
|
|
||||||
sides[0]*=2.0f;
|
|
||||||
sides[1]*=2.0f;
|
|
||||||
sides[2]*=2.0f;
|
|
||||||
|
|
||||||
|
sides[0] *= 2.0f;
|
||||||
|
sides[1] *= 2.0f;
|
||||||
|
sides[2] *= 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *matrix)
|
void computeBestFitOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, float *matrix)
|
||||||
{
|
{
|
||||||
|
|
||||||
float bmin[3];
|
float bmin[3];
|
||||||
float bmax[3];
|
float bmax[3];
|
||||||
|
|
||||||
fm_getAABB(vcount,points,pstride,bmin,bmax);
|
fm_getAABB(vcount, points, pstride, bmin, bmax);
|
||||||
|
|
||||||
float center[3];
|
float center[3];
|
||||||
|
|
||||||
center[0] = (bmax[0]-bmin[0])*0.5f + bmin[0];
|
center[0] = (bmax[0] - bmin[0]) * 0.5f + bmin[0];
|
||||||
center[1] = (bmax[1]-bmin[1])*0.5f + bmin[1];
|
center[1] = (bmax[1] - bmin[1]) * 0.5f + bmin[1];
|
||||||
center[2] = (bmax[2]-bmin[2])*0.5f + bmin[2];
|
center[2] = (bmax[2] - bmin[2]) * 0.5f + bmin[2];
|
||||||
|
|
||||||
float ax = 0;
|
float ax = 0;
|
||||||
float ay = 0;
|
float ay = 0;
|
||||||
@@ -106,36 +103,35 @@ void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstr
|
|||||||
float steps = 8.0f; // 16 steps on each axis.
|
float steps = 8.0f; // 16 steps on each axis.
|
||||||
|
|
||||||
float bestVolume = 1e9;
|
float bestVolume = 1e9;
|
||||||
float angle[3]={0.f,0.f,0.f};
|
float angle[3] = {0.f, 0.f, 0.f};
|
||||||
|
|
||||||
while ( sweep >= 1 )
|
while (sweep >= 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
float stepsize = sweep / steps;
|
float stepsize = sweep / steps;
|
||||||
|
|
||||||
for (float x=ax-sweep; x<=ax+sweep; x+=stepsize)
|
for (float x = ax - sweep; x <= ax + sweep; x += stepsize)
|
||||||
{
|
{
|
||||||
for (float y=ay-sweep; y<=ay+sweep; y+=stepsize)
|
for (float y = ay - sweep; y <= ay + sweep; y += stepsize)
|
||||||
{
|
{
|
||||||
for (float z=az-sweep; z<=az+sweep; z+=stepsize)
|
for (float z = az - sweep; z <= az + sweep; z += stepsize)
|
||||||
{
|
{
|
||||||
float pmatrix[16];
|
float pmatrix[16];
|
||||||
|
|
||||||
fm_eulerMatrix( x*FM_DEG_TO_RAD, y*FM_DEG_TO_RAD, z*FM_DEG_TO_RAD, pmatrix );
|
fm_eulerMatrix(x * FM_DEG_TO_RAD, y * FM_DEG_TO_RAD, z * FM_DEG_TO_RAD, pmatrix);
|
||||||
|
|
||||||
pmatrix[3*4+0] = center[0];
|
pmatrix[3 * 4 + 0] = center[0];
|
||||||
pmatrix[3*4+1] = center[1];
|
pmatrix[3 * 4 + 1] = center[1];
|
||||||
pmatrix[3*4+2] = center[2];
|
pmatrix[3 * 4 + 2] = center[2];
|
||||||
|
|
||||||
float psides[3];
|
float psides[3];
|
||||||
|
|
||||||
computeOBB( vcount, points, pstride, psides, pmatrix );
|
computeOBB(vcount, points, pstride, psides, pmatrix);
|
||||||
|
|
||||||
float volume = psides[0]*psides[1]*psides[2]; // the volume of the cube
|
float volume = psides[0] * psides[1] * psides[2]; // the volume of the cube
|
||||||
|
|
||||||
if ( volume <= bestVolume )
|
if (volume <= bestVolume)
|
||||||
{
|
{
|
||||||
bestVolume = volume;
|
bestVolume = volume;
|
||||||
|
|
||||||
@@ -147,27 +143,24 @@ void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstr
|
|||||||
angle[1] = ay;
|
angle[1] = ay;
|
||||||
angle[2] = az;
|
angle[2] = az;
|
||||||
|
|
||||||
memcpy(matrix,pmatrix,sizeof(float)*16);
|
memcpy(matrix, pmatrix, sizeof(float) * 16);
|
||||||
found = true; // yes, we found an improvement.
|
found = true; // yes, we found an improvement.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( found )
|
if (found)
|
||||||
{
|
{
|
||||||
|
|
||||||
ax = angle[0];
|
ax = angle[0];
|
||||||
ay = angle[1];
|
ay = angle[1];
|
||||||
az = angle[2];
|
az = angle[2];
|
||||||
|
|
||||||
sweep*=0.5f; // sweep 1/2 the distance as the last time.
|
sweep *= 0.5f; // sweep 1/2 the distance as the last time.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break; // no improvement, so just
|
break; // no improvement, so just
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
void computeBestFitOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, float *matrix);
|
||||||
|
|
||||||
void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *matrix);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
|
||||||
class HullResult
|
class HullResult
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -51,19 +50,18 @@ public:
|
|||||||
unsigned int mNumIndices; // the total number of indices
|
unsigned int mNumIndices; // the total number of indices
|
||||||
unsigned int *mIndices; // pointer to indices.
|
unsigned int *mIndices; // pointer to indices.
|
||||||
|
|
||||||
// If triangles, then indices are array indexes into the vertex list.
|
// If triangles, then indices are array indexes into the vertex list.
|
||||||
// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
|
// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HullFlag
|
enum HullFlag
|
||||||
{
|
{
|
||||||
QF_TRIANGLES = (1<<0), // report results as triangles, not polygons.
|
QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons.
|
||||||
QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices.
|
QF_REVERSE_ORDER = (1 << 1), // reverse order of the triangle indices.
|
||||||
QF_SKIN_WIDTH = (1<<2), // extrude hull based on this skin width
|
QF_SKIN_WIDTH = (1 << 2), // extrude hull based on this skin width
|
||||||
QF_DEFAULT = 0
|
QF_DEFAULT = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class HullDesc
|
class HullDesc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -72,7 +70,7 @@ public:
|
|||||||
mFlags = QF_DEFAULT;
|
mFlags = QF_DEFAULT;
|
||||||
mVcount = 0;
|
mVcount = 0;
|
||||||
mVertices = 0;
|
mVertices = 0;
|
||||||
mVertexStride = sizeof(float)*3;
|
mVertexStride = sizeof(float) * 3;
|
||||||
mNormalEpsilon = 0.001f;
|
mNormalEpsilon = 0.001f;
|
||||||
mMaxVertices = 4096; // maximum number of points to be considered for a convex hull.
|
mMaxVertices = 4096; // maximum number of points to be considered for a convex hull.
|
||||||
mMaxFaces = 4096;
|
mMaxFaces = 4096;
|
||||||
@@ -95,18 +93,18 @@ public:
|
|||||||
|
|
||||||
bool HasHullFlag(HullFlag flag) const
|
bool HasHullFlag(HullFlag flag) const
|
||||||
{
|
{
|
||||||
if ( mFlags & flag ) return true;
|
if (mFlags & flag) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHullFlag(HullFlag flag)
|
void SetHullFlag(HullFlag flag)
|
||||||
{
|
{
|
||||||
mFlags|=flag;
|
mFlags |= flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearHullFlag(HullFlag flag)
|
void ClearHullFlag(HullFlag flag)
|
||||||
{
|
{
|
||||||
mFlags&=~flag;
|
mFlags &= ~flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int mFlags; // flags to use when generating the convex hull.
|
unsigned int mFlags; // flags to use when generating the convex hull.
|
||||||
@@ -128,15 +126,13 @@ enum HullError
|
|||||||
class HullLibrary
|
class HullLibrary
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HullError CreateConvexHull(const HullDesc &desc, // describes the input request
|
HullError CreateConvexHull(const HullDesc &desc, // describes the input request
|
||||||
HullResult &result); // contains the resulst
|
HullResult &result); // contains the resulst
|
||||||
|
|
||||||
HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
|
HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void BringOutYourDead(const float *verts, unsigned int vcount, float *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount);
|
||||||
void BringOutYourDead(const float *verts,unsigned int vcount, float *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount);
|
|
||||||
|
|
||||||
bool CleanupVertices(unsigned int svcount,
|
bool CleanupVertices(unsigned int svcount,
|
||||||
const float *svertices,
|
const float *svertices,
|
||||||
@@ -147,7 +143,6 @@ private:
|
|||||||
float *scale);
|
float *scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace ConvexDecomposition
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,6 @@
|
|||||||
|
|
||||||
#include "cd_wavefront.h"
|
#include "cd_wavefront.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace ConvexDecomposition;
|
using namespace ConvexDecomposition;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
@@ -75,9 +74,8 @@ using namespace ConvexDecomposition;
|
|||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
typedef std::vector<int> IntVector;
|
||||||
typedef std::vector< int > IntVector;
|
typedef std::vector<float> FloatVector;
|
||||||
typedef std::vector< float > FloatVector;
|
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__CELLOS_LV2__)
|
#if defined(__APPLE__) || defined(__CELLOS_LV2__)
|
||||||
#define stricmp(a, b) strcasecmp((a), (b))
|
#define stricmp(a, b) strcasecmp((a), (b))
|
||||||
@@ -89,9 +87,9 @@ typedef std::vector< float > FloatVector;
|
|||||||
class InPlaceParserInterface
|
class InPlaceParserInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~InPlaceParserInterface () {} ;
|
virtual ~InPlaceParserInterface(){};
|
||||||
|
|
||||||
virtual int ParseLine(int lineno,int argc,const char **argv) =0; // return TRUE to continue parsing, return FALSE to abort parsing process
|
virtual int ParseLine(int lineno, int argc, const char **argv) = 0; // return TRUE to continue parsing, return FALSE to abort parsing process
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SeparatorType
|
enum SeparatorType
|
||||||
@@ -110,10 +108,10 @@ public:
|
|||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
InPlaceParser(char *data,int len)
|
InPlaceParser(char *data, int len)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
SetSourceData(data,len);
|
SetSourceData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
InPlaceParser(const char *fname)
|
InPlaceParser(const char *fname)
|
||||||
@@ -130,11 +128,11 @@ public:
|
|||||||
mData = 0;
|
mData = 0;
|
||||||
mLen = 0;
|
mLen = 0;
|
||||||
mMyAlloc = false;
|
mMyAlloc = false;
|
||||||
for (int i=0; i<256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
mHard[i] = ST_DATA;
|
mHard[i] = ST_DATA;
|
||||||
mHardString[i*2] = i;
|
mHardString[i * 2] = i;
|
||||||
mHardString[i*2+1] = 0;
|
mHardString[i * 2 + 1] = 0;
|
||||||
}
|
}
|
||||||
mHard[0] = ST_EOS;
|
mHard[0] = ST_EOS;
|
||||||
mHard[32] = ST_SOFT;
|
mHard[32] = ST_SOFT;
|
||||||
@@ -145,7 +143,7 @@ public:
|
|||||||
|
|
||||||
void SetFile(const char *fname); // use this file as source data to parse.
|
void SetFile(const char *fname); // use this file as source data to parse.
|
||||||
|
|
||||||
void SetSourceData(char *data,int len)
|
void SetSourceData(char *data, int len)
|
||||||
{
|
{
|
||||||
mData = data;
|
mData = data;
|
||||||
mLen = len;
|
mLen = len;
|
||||||
@@ -154,9 +152,9 @@ public:
|
|||||||
|
|
||||||
int Parse(InPlaceParserInterface *callback); // returns true if entire file was parsed, false if it aborted for some reason
|
int Parse(InPlaceParserInterface *callback); // returns true if entire file was parsed, false if it aborted for some reason
|
||||||
|
|
||||||
int ProcessLine(int lineno,char *line,InPlaceParserInterface *callback);
|
int ProcessLine(int lineno, char *line, InPlaceParserInterface *callback);
|
||||||
|
|
||||||
const char ** GetArglist(char *source,int &count); // convert source string into an arg list, this is a destructive parse.
|
const char **GetArglist(char *source, int &count); // convert source string into an arg list, this is a destructive parse.
|
||||||
|
|
||||||
void SetHardSeparator(char c) // add a hard separator
|
void SetHardSeparator(char c) // add a hard separator
|
||||||
{
|
{
|
||||||
@@ -168,7 +166,6 @@ public:
|
|||||||
mHard[(int)c] = ST_HARD;
|
mHard[(int)c] = ST_HARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetCommentSymbol(char c) // comment character, treated as 'end of string'
|
void SetCommentSymbol(char c) // comment character, treated as 'end of string'
|
||||||
{
|
{
|
||||||
mHard[(int)c] = ST_EOS;
|
mHard[(int)c] = ST_EOS;
|
||||||
@@ -179,12 +176,11 @@ public:
|
|||||||
mHard[(int)c] = ST_DATA;
|
mHard[(int)c] = ST_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character.
|
void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character.
|
||||||
|
|
||||||
bool EOS(char c)
|
bool EOS(char c)
|
||||||
{
|
{
|
||||||
if ( mHard[(int)c] == ST_EOS )
|
if (mHard[(int)c] == ST_EOS)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -197,11 +193,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline char *AddHard(int &argc, const char **argv, char *foo);
|
||||||
|
|
||||||
inline char * AddHard(int &argc,const char **argv,char *foo);
|
|
||||||
inline bool IsHard(char c);
|
inline bool IsHard(char c);
|
||||||
inline char * SkipSpaces(char *foo);
|
inline char *SkipSpaces(char *foo);
|
||||||
inline bool IsWhiteSpace(char c);
|
inline bool IsWhiteSpace(char c);
|
||||||
inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft
|
inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft
|
||||||
|
|
||||||
@@ -209,7 +203,7 @@ private:
|
|||||||
char *mData; // ascii data to parse.
|
char *mData; // ascii data to parse.
|
||||||
int mLen; // length of data
|
int mLen; // length of data
|
||||||
SeparatorType mHard[256];
|
SeparatorType mHard[256];
|
||||||
char mHardString[256*2];
|
char mHardString[256 * 2];
|
||||||
char mQuoteChar;
|
char mQuoteChar;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -218,7 +212,7 @@ private:
|
|||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
void InPlaceParser::SetFile(const char *fname)
|
void InPlaceParser::SetFile(const char *fname)
|
||||||
{
|
{
|
||||||
if ( mMyAlloc )
|
if (mMyAlloc)
|
||||||
{
|
{
|
||||||
free(mData);
|
free(mData);
|
||||||
}
|
}
|
||||||
@@ -226,18 +220,17 @@ void InPlaceParser::SetFile(const char *fname)
|
|||||||
mLen = 0;
|
mLen = 0;
|
||||||
mMyAlloc = false;
|
mMyAlloc = false;
|
||||||
|
|
||||||
|
FILE *fph = fopen(fname, "rb");
|
||||||
FILE *fph = fopen(fname,"rb");
|
if (fph)
|
||||||
if ( fph )
|
|
||||||
{
|
{
|
||||||
fseek(fph,0L,SEEK_END);
|
fseek(fph, 0L, SEEK_END);
|
||||||
mLen = ftell(fph);
|
mLen = ftell(fph);
|
||||||
fseek(fph,0L,SEEK_SET);
|
fseek(fph, 0L, SEEK_SET);
|
||||||
if ( mLen )
|
if (mLen)
|
||||||
{
|
{
|
||||||
mData = (char *) malloc(sizeof(char)*(mLen+1));
|
mData = (char *)malloc(sizeof(char) * (mLen + 1));
|
||||||
int ok = fread(mData, mLen, 1, fph);
|
int ok = fread(mData, mLen, 1, fph);
|
||||||
if ( !ok )
|
if (!ok)
|
||||||
{
|
{
|
||||||
free(mData);
|
free(mData);
|
||||||
mData = 0;
|
mData = 0;
|
||||||
@@ -254,7 +247,7 @@ void InPlaceParser::SetFile(const char *fname)
|
|||||||
|
|
||||||
InPlaceParser::~InPlaceParser(void)
|
InPlaceParser::~InPlaceParser(void)
|
||||||
{
|
{
|
||||||
if ( mMyAlloc )
|
if (mMyAlloc)
|
||||||
{
|
{
|
||||||
free(mData);
|
free(mData);
|
||||||
}
|
}
|
||||||
@@ -267,12 +260,12 @@ bool InPlaceParser::IsHard(char c)
|
|||||||
return mHard[(int)c] == ST_HARD;
|
return mHard[(int)c] == ST_HARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * InPlaceParser::AddHard(int &argc,const char **argv,char *foo)
|
char *InPlaceParser::AddHard(int &argc, const char **argv, char *foo)
|
||||||
{
|
{
|
||||||
while ( IsHard(*foo) )
|
while (IsHard(*foo))
|
||||||
{
|
{
|
||||||
const char *hard = &mHardString[*foo*2];
|
const char *hard = &mHardString[*foo * 2];
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = hard;
|
argv[argc++] = hard;
|
||||||
}
|
}
|
||||||
@@ -286,20 +279,19 @@ bool InPlaceParser::IsWhiteSpace(char c)
|
|||||||
return mHard[(int)c] == ST_SOFT;
|
return mHard[(int)c] == ST_SOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * InPlaceParser::SkipSpaces(char *foo)
|
char *InPlaceParser::SkipSpaces(char *foo)
|
||||||
{
|
{
|
||||||
while ( !EOS(*foo) && IsWhiteSpace(*foo) ) foo++;
|
while (!EOS(*foo) && IsWhiteSpace(*foo)) foo++;
|
||||||
return foo;
|
return foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InPlaceParser::IsNonSeparator(char c)
|
bool InPlaceParser::IsNonSeparator(char c)
|
||||||
{
|
{
|
||||||
if ( !IsHard(c) && !IsWhiteSpace(c) && c != 0 ) return true;
|
if (!IsHard(c) && !IsWhiteSpace(c) && c != 0) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InPlaceParser::ProcessLine(int lineno, char *line, InPlaceParserInterface *callback)
|
||||||
int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *callback)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -308,22 +300,21 @@ int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *cal
|
|||||||
|
|
||||||
char *foo = line;
|
char *foo = line;
|
||||||
|
|
||||||
while ( !EOS(*foo) && argc < MAXARGS )
|
while (!EOS(*foo) && argc < MAXARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
foo = SkipSpaces(foo); // skip any leading spaces
|
foo = SkipSpaces(foo); // skip any leading spaces
|
||||||
|
|
||||||
if ( EOS(*foo) ) break;
|
if (EOS(*foo)) break;
|
||||||
|
|
||||||
if ( *foo == mQuoteChar ) // if it is an open quote
|
if (*foo == mQuoteChar) // if it is an open quote
|
||||||
{
|
{
|
||||||
foo++;
|
foo++;
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = foo;
|
argv[argc++] = foo;
|
||||||
}
|
}
|
||||||
while ( !EOS(*foo) && *foo != mQuoteChar ) foo++;
|
while (!EOS(*foo) && *foo != mQuoteChar) foo++;
|
||||||
if ( !EOS(*foo) )
|
if (!EOS(*foo))
|
||||||
{
|
{
|
||||||
*foo = 0; // replace close quote with zero byte EOS
|
*foo = 0; // replace close quote with zero byte EOS
|
||||||
foo++;
|
foo++;
|
||||||
@@ -331,43 +322,42 @@ int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *cal
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
foo = AddHard(argc, argv, foo); // add any hard separators, skip any spaces
|
||||||
|
|
||||||
foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces
|
if (IsNonSeparator(*foo)) // add non-hard argument.
|
||||||
|
|
||||||
if ( IsNonSeparator(*foo) ) // add non-hard argument.
|
|
||||||
{
|
{
|
||||||
bool quote = false;
|
bool quote = false;
|
||||||
if ( *foo == mQuoteChar )
|
if (*foo == mQuoteChar)
|
||||||
{
|
{
|
||||||
foo++;
|
foo++;
|
||||||
quote = true;
|
quote = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = foo;
|
argv[argc++] = foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( quote )
|
if (quote)
|
||||||
{
|
{
|
||||||
while (*foo && *foo != mQuoteChar ) foo++;
|
while (*foo && *foo != mQuoteChar) foo++;
|
||||||
if ( *foo ) *foo = 32;
|
if (*foo) *foo = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue..until we hit an eos ..
|
// continue..until we hit an eos ..
|
||||||
while ( !EOS(*foo) ) // until we hit EOS
|
while (!EOS(*foo)) // until we hit EOS
|
||||||
{
|
{
|
||||||
if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit
|
if (IsWhiteSpace(*foo)) // if we hit a space, stomp a zero byte, and exit
|
||||||
{
|
{
|
||||||
*foo = 0;
|
*foo = 0;
|
||||||
foo++;
|
foo++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument
|
else if (IsHard(*foo)) // if we hit a hard separator, stomp a zero byte and store the hard separator argument
|
||||||
{
|
{
|
||||||
const char *hard = &mHardString[*foo*2];
|
const char *hard = &mHardString[*foo * 2];
|
||||||
*foo = 0;
|
*foo = 0;
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = hard;
|
argv[argc++] = hard;
|
||||||
}
|
}
|
||||||
@@ -380,9 +370,9 @@ int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *cal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( argc )
|
if (argc)
|
||||||
{
|
{
|
||||||
ret = callback->ParseLine(lineno, argc, argv );
|
ret = callback->ParseLine(lineno, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -390,8 +380,8 @@ int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *cal
|
|||||||
|
|
||||||
int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason
|
int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason
|
||||||
{
|
{
|
||||||
assert( callback );
|
assert(callback);
|
||||||
if ( !mData ) return 0;
|
if (!mData) return 0;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -400,22 +390,21 @@ int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if e
|
|||||||
char *foo = mData;
|
char *foo = mData;
|
||||||
char *begin = foo;
|
char *begin = foo;
|
||||||
|
|
||||||
|
while (*foo)
|
||||||
while ( *foo )
|
|
||||||
{
|
{
|
||||||
if ( *foo == 10 || *foo == 13 )
|
if (*foo == 10 || *foo == 13)
|
||||||
{
|
{
|
||||||
lineno++;
|
lineno++;
|
||||||
*foo = 0;
|
*foo = 0;
|
||||||
|
|
||||||
if ( *begin ) // if there is any data to parse at all...
|
if (*begin) // if there is any data to parse at all...
|
||||||
{
|
{
|
||||||
int v = ProcessLine(lineno,begin,callback);
|
int v = ProcessLine(lineno, begin, callback);
|
||||||
if ( v ) ret = v;
|
if (v) ret = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
foo++;
|
foo++;
|
||||||
if ( *foo == 10 ) foo++; // skip line feed, if it is in the carraige-return line-feed format...
|
if (*foo == 10) foo++; // skip line feed, if it is in the carraige-return line-feed format...
|
||||||
begin = foo;
|
begin = foo;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -426,12 +415,11 @@ int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if e
|
|||||||
|
|
||||||
lineno++; // lasst line.
|
lineno++; // lasst line.
|
||||||
|
|
||||||
int v = ProcessLine(lineno,begin,callback);
|
int v = ProcessLine(lineno, begin, callback);
|
||||||
if ( v ) ret = v;
|
if (v) ret = v;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InPlaceParser::DefaultSymbols(void)
|
void InPlaceParser::DefaultSymbols(void)
|
||||||
{
|
{
|
||||||
SetHardSeparator(',');
|
SetHardSeparator(',');
|
||||||
@@ -445,8 +433,7 @@ void InPlaceParser::DefaultSymbols(void)
|
|||||||
SetCommentSymbol('#');
|
SetCommentSymbol('#');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char **InPlaceParser::GetArglist(char *line, int &count) // convert source string into an arg list, this is a destructive parse.
|
||||||
const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source string into an arg list, this is a destructive parse.
|
|
||||||
{
|
{
|
||||||
const char **ret = 0;
|
const char **ret = 0;
|
||||||
|
|
||||||
@@ -455,22 +442,21 @@ const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source
|
|||||||
|
|
||||||
char *foo = line;
|
char *foo = line;
|
||||||
|
|
||||||
while ( !EOS(*foo) && argc < MAXARGS )
|
while (!EOS(*foo) && argc < MAXARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
foo = SkipSpaces(foo); // skip any leading spaces
|
foo = SkipSpaces(foo); // skip any leading spaces
|
||||||
|
|
||||||
if ( EOS(*foo) ) break;
|
if (EOS(*foo)) break;
|
||||||
|
|
||||||
if ( *foo == mQuoteChar ) // if it is an open quote
|
if (*foo == mQuoteChar) // if it is an open quote
|
||||||
{
|
{
|
||||||
foo++;
|
foo++;
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = foo;
|
argv[argc++] = foo;
|
||||||
}
|
}
|
||||||
while ( !EOS(*foo) && *foo != mQuoteChar ) foo++;
|
while (!EOS(*foo) && *foo != mQuoteChar) foo++;
|
||||||
if ( !EOS(*foo) )
|
if (!EOS(*foo))
|
||||||
{
|
{
|
||||||
*foo = 0; // replace close quote with zero byte EOS
|
*foo = 0; // replace close quote with zero byte EOS
|
||||||
foo++;
|
foo++;
|
||||||
@@ -478,43 +464,42 @@ const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
foo = AddHard(argc, argv, foo); // add any hard separators, skip any spaces
|
||||||
|
|
||||||
foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces
|
if (IsNonSeparator(*foo)) // add non-hard argument.
|
||||||
|
|
||||||
if ( IsNonSeparator(*foo) ) // add non-hard argument.
|
|
||||||
{
|
{
|
||||||
bool quote = false;
|
bool quote = false;
|
||||||
if ( *foo == mQuoteChar )
|
if (*foo == mQuoteChar)
|
||||||
{
|
{
|
||||||
foo++;
|
foo++;
|
||||||
quote = true;
|
quote = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = foo;
|
argv[argc++] = foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( quote )
|
if (quote)
|
||||||
{
|
{
|
||||||
while (*foo && *foo != mQuoteChar ) foo++;
|
while (*foo && *foo != mQuoteChar) foo++;
|
||||||
if ( *foo ) *foo = 32;
|
if (*foo) *foo = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue..until we hit an eos ..
|
// continue..until we hit an eos ..
|
||||||
while ( !EOS(*foo) ) // until we hit EOS
|
while (!EOS(*foo)) // until we hit EOS
|
||||||
{
|
{
|
||||||
if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit
|
if (IsWhiteSpace(*foo)) // if we hit a space, stomp a zero byte, and exit
|
||||||
{
|
{
|
||||||
*foo = 0;
|
*foo = 0;
|
||||||
foo++;
|
foo++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument
|
else if (IsHard(*foo)) // if we hit a hard separator, stomp a zero byte and store the hard separator argument
|
||||||
{
|
{
|
||||||
const char *hard = &mHardString[*foo*2];
|
const char *hard = &mHardString[*foo * 2];
|
||||||
*foo = 0;
|
*foo = 0;
|
||||||
if ( argc < MAXARGS )
|
if (argc < MAXARGS)
|
||||||
{
|
{
|
||||||
argv[argc++] = hard;
|
argv[argc++] = hard;
|
||||||
}
|
}
|
||||||
@@ -528,7 +513,7 @@ const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source
|
|||||||
}
|
}
|
||||||
|
|
||||||
count = argc;
|
count = argc;
|
||||||
if ( argc )
|
if (argc)
|
||||||
{
|
{
|
||||||
ret = argv;
|
ret = argv;
|
||||||
}
|
}
|
||||||
@@ -548,30 +533,25 @@ public:
|
|||||||
float mTexel[2];
|
float mTexel[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class GeometryInterface
|
class GeometryInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual void NodeTriangle(const GeometryVertex *v1, const GeometryVertex *v2, const GeometryVertex *v3) {}
|
||||||
|
|
||||||
virtual void NodeTriangle(const GeometryVertex *v1,const GeometryVertex *v2,const GeometryVertex *v3) {}
|
virtual ~GeometryInterface() {}
|
||||||
|
|
||||||
virtual ~GeometryInterface () {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/******************** Obj.h ********************************/
|
/******************** Obj.h ********************************/
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
class OBJ : public InPlaceParserInterface
|
class OBJ : public InPlaceParserInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int LoadMesh(const char *fname,GeometryInterface *callback);
|
int LoadMesh(const char *fname, GeometryInterface *callback);
|
||||||
int ParseLine(int lineno,int argc,const char **argv); // return TRUE to continue parsing, return FALSE to abort parsing process
|
int ParseLine(int lineno, int argc, const char **argv); // return TRUE to continue parsing, return FALSE to abort parsing process
|
||||||
private:
|
private:
|
||||||
|
void getVertex(GeometryVertex &v, const char *face) const;
|
||||||
void getVertex(GeometryVertex &v,const char *face) const;
|
|
||||||
|
|
||||||
FloatVector mVerts;
|
FloatVector mVerts;
|
||||||
FloatVector mTexels;
|
FloatVector mTexels;
|
||||||
@@ -580,12 +560,11 @@ private:
|
|||||||
GeometryInterface *mCallback;
|
GeometryInterface *mCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/******************** Obj.cpp ********************************/
|
/******************** Obj.cpp ********************************/
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
|
|
||||||
int OBJ::LoadMesh(const char *fname,GeometryInterface *iface)
|
int OBJ::LoadMesh(const char *fname, GeometryInterface *iface)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -599,18 +578,17 @@ int OBJ::LoadMesh(const char *fname,GeometryInterface *iface)
|
|||||||
|
|
||||||
ipp.Parse(this);
|
ipp.Parse(this);
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static const char * GetArg(const char **argv,int i,int argc)
|
//static const char * GetArg(const char **argv,int i,int argc)
|
||||||
//{
|
//{
|
||||||
// const char * ret = 0;
|
// const char * ret = 0;
|
||||||
// if ( i < argc ) ret = argv[i];
|
// if ( i < argc ) ret = argv[i];
|
||||||
// return ret;
|
// return ret;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void OBJ::getVertex(GeometryVertex &v,const char *face) const
|
void OBJ::getVertex(GeometryVertex &v, const char *face) const
|
||||||
{
|
{
|
||||||
v.mPos[0] = 0;
|
v.mPos[0] = 0;
|
||||||
v.mPos[1] = 0;
|
v.mPos[1] = 0;
|
||||||
@@ -623,31 +601,30 @@ void OBJ::getVertex(GeometryVertex &v,const char *face) const
|
|||||||
v.mNormal[1] = 1;
|
v.mNormal[1] = 1;
|
||||||
v.mNormal[2] = 0;
|
v.mNormal[2] = 0;
|
||||||
|
|
||||||
int index = atoi( face )-1;
|
int index = atoi(face) - 1;
|
||||||
|
|
||||||
const char *texel = strstr(face,"/");
|
const char *texel = strstr(face, "/");
|
||||||
|
|
||||||
if ( texel )
|
if (texel)
|
||||||
{
|
{
|
||||||
int tindex = atoi( texel+1) - 1;
|
int tindex = atoi(texel + 1) - 1;
|
||||||
|
|
||||||
if ( tindex >=0 && tindex < (int)(mTexels.size()/2) )
|
if (tindex >= 0 && tindex < (int)(mTexels.size() / 2))
|
||||||
{
|
{
|
||||||
const float *t = &mTexels[tindex*2];
|
const float *t = &mTexels[tindex * 2];
|
||||||
|
|
||||||
v.mTexel[0] = t[0];
|
v.mTexel[0] = t[0];
|
||||||
v.mTexel[1] = t[1];
|
v.mTexel[1] = t[1];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *normal = strstr(texel+1,"/");
|
const char *normal = strstr(texel + 1, "/");
|
||||||
if ( normal )
|
if (normal)
|
||||||
{
|
{
|
||||||
int nindex = atoi( normal+1 ) - 1;
|
int nindex = atoi(normal + 1) - 1;
|
||||||
|
|
||||||
if (nindex >= 0 && nindex < (int)(mNormals.size()/3) )
|
if (nindex >= 0 && nindex < (int)(mNormals.size() / 3))
|
||||||
{
|
{
|
||||||
const float *n = &mNormals[nindex*3];
|
const float *n = &mNormals[nindex * 3];
|
||||||
|
|
||||||
v.mNormal[0] = n[0];
|
v.mNormal[0] = n[0];
|
||||||
v.mNormal[1] = n[1];
|
v.mNormal[1] = n[1];
|
||||||
@@ -656,69 +633,67 @@ void OBJ::getVertex(GeometryVertex &v,const char *face) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( index >= 0 && index < (int)(mVerts.size()/3) )
|
if (index >= 0 && index < (int)(mVerts.size() / 3))
|
||||||
{
|
{
|
||||||
|
const float *p = &mVerts[index * 3];
|
||||||
const float *p = &mVerts[index*3];
|
|
||||||
|
|
||||||
v.mPos[0] = p[0];
|
v.mPos[0] = p[0];
|
||||||
v.mPos[1] = p[1];
|
v.mPos[1] = p[1];
|
||||||
v.mPos[2] = p[2];
|
v.mPos[2] = p[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to continue parsing, return FALSE to abort parsing process
|
int OBJ::ParseLine(int lineno, int argc, const char **argv) // return TRUE to continue parsing, return FALSE to abort parsing process
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if ( argc >= 1 )
|
if (argc >= 1)
|
||||||
{
|
{
|
||||||
const char *foo = argv[0];
|
const char *foo = argv[0];
|
||||||
if ( *foo != '#' )
|
if (*foo != '#')
|
||||||
{
|
{
|
||||||
if ( strcmp(argv[0],"v") == 0 && argc == 4 )
|
if (strcmp(argv[0], "v") == 0 && argc == 4)
|
||||||
|
|
||||||
//if ( stricmp(argv[0],"v") == 0 && argc == 4 )
|
//if ( stricmp(argv[0],"v") == 0 && argc == 4 )
|
||||||
{
|
{
|
||||||
float vx = (float) atof( argv[1] );
|
float vx = (float)atof(argv[1]);
|
||||||
float vy = (float) atof( argv[2] );
|
float vy = (float)atof(argv[2]);
|
||||||
float vz = (float) atof( argv[3] );
|
float vz = (float)atof(argv[3]);
|
||||||
mVerts.push_back(vx);
|
mVerts.push_back(vx);
|
||||||
mVerts.push_back(vy);
|
mVerts.push_back(vy);
|
||||||
mVerts.push_back(vz);
|
mVerts.push_back(vz);
|
||||||
}
|
}
|
||||||
else if ( strcmp(argv[0],"vt") == 0 && argc == 3 )
|
else if (strcmp(argv[0], "vt") == 0 && argc == 3)
|
||||||
|
|
||||||
// else if ( stricmp(argv[0],"vt") == 0 && argc == 3 )
|
// else if ( stricmp(argv[0],"vt") == 0 && argc == 3 )
|
||||||
{
|
{
|
||||||
float tx = (float) atof( argv[1] );
|
float tx = (float)atof(argv[1]);
|
||||||
float ty = (float) atof( argv[2] );
|
float ty = (float)atof(argv[2]);
|
||||||
mTexels.push_back(tx);
|
mTexels.push_back(tx);
|
||||||
mTexels.push_back(ty);
|
mTexels.push_back(ty);
|
||||||
}
|
}
|
||||||
// else if ( stricmp(argv[0],"vn") == 0 && argc == 4 )
|
// else if ( stricmp(argv[0],"vn") == 0 && argc == 4 )
|
||||||
|
|
||||||
else if ( strcmp(argv[0],"vn") == 0 && argc == 4 )
|
else if (strcmp(argv[0], "vn") == 0 && argc == 4)
|
||||||
{
|
{
|
||||||
float normalx = (float) atof(argv[1]);
|
float normalx = (float)atof(argv[1]);
|
||||||
float normaly = (float) atof(argv[2]);
|
float normaly = (float)atof(argv[2]);
|
||||||
float normalz = (float) atof(argv[3]);
|
float normalz = (float)atof(argv[3]);
|
||||||
mNormals.push_back(normalx);
|
mNormals.push_back(normalx);
|
||||||
mNormals.push_back(normaly);
|
mNormals.push_back(normaly);
|
||||||
mNormals.push_back(normalz);
|
mNormals.push_back(normalz);
|
||||||
}
|
}
|
||||||
// else if ( stricmp(argv[0],"f") == 0 && argc >= 4 )
|
// else if ( stricmp(argv[0],"f") == 0 && argc >= 4 )
|
||||||
|
|
||||||
else if ( strcmp(argv[0],"f") == 0 && argc >= 4 )
|
else if (strcmp(argv[0], "f") == 0 && argc >= 4)
|
||||||
{
|
{
|
||||||
GeometryVertex v[32];
|
GeometryVertex v[32];
|
||||||
|
|
||||||
int vcount = argc-1;
|
int vcount = argc - 1;
|
||||||
|
|
||||||
for (int i=1; i<argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
getVertex(v[i-1],argv[i] );
|
getVertex(v[i - 1], argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to generate a normal!
|
// need to generate a normal!
|
||||||
@@ -742,16 +717,15 @@ int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to con
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mCallback->NodeTriangle(&v[0],&v[1],&v[2]);
|
mCallback->NodeTriangle(&v[0], &v[1], &v[2]);
|
||||||
|
|
||||||
if ( vcount >=3 ) // do the fan
|
if (vcount >= 3) // do the fan
|
||||||
{
|
{
|
||||||
for (int i=2; i<(vcount-1); i++)
|
for (int i = 2; i < (vcount - 1); i++)
|
||||||
{
|
{
|
||||||
mCallback->NodeTriangle(&v[0],&v[i],&v[i+1]);
|
mCallback->NodeTriangle(&v[0], &v[i], &v[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -759,53 +733,47 @@ int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to con
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BuildMesh : public GeometryInterface
|
class BuildMesh : public GeometryInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int getIndex(const float *p)
|
int getIndex(const float *p)
|
||||||
{
|
{
|
||||||
|
int vcount = mVertices.size() / 3;
|
||||||
|
|
||||||
int vcount = mVertices.size()/3;
|
if (vcount > 0)
|
||||||
|
|
||||||
if(vcount>0)
|
|
||||||
{
|
{
|
||||||
//New MS STL library checks indices in debug build, so zero causes an assert if it is empty.
|
//New MS STL library checks indices in debug build, so zero causes an assert if it is empty.
|
||||||
const float *v = &mVertices[0];
|
const float *v = &mVertices[0];
|
||||||
|
|
||||||
for (int i=0; i<vcount; i++)
|
for (int i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
if ( v[0] == p[0] && v[1] == p[1] && v[2] == p[2] ) return i;
|
if (v[0] == p[0] && v[1] == p[1] && v[2] == p[2]) return i;
|
||||||
v+=3;
|
v += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mVertices.push_back( p[0] );
|
mVertices.push_back(p[0]);
|
||||||
mVertices.push_back( p[1] );
|
mVertices.push_back(p[1]);
|
||||||
mVertices.push_back( p[2] );
|
mVertices.push_back(p[2]);
|
||||||
|
|
||||||
return vcount;
|
return vcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void NodeTriangle(const GeometryVertex *v1,const GeometryVertex *v2,const GeometryVertex *v3)
|
virtual void NodeTriangle(const GeometryVertex *v1, const GeometryVertex *v2, const GeometryVertex *v3)
|
||||||
{
|
{
|
||||||
mIndices.push_back( getIndex(v1->mPos) );
|
mIndices.push_back(getIndex(v1->mPos));
|
||||||
mIndices.push_back( getIndex(v2->mPos) );
|
mIndices.push_back(getIndex(v2->mPos));
|
||||||
mIndices.push_back( getIndex(v3->mPos) );
|
mIndices.push_back(getIndex(v3->mPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
const FloatVector& GetVertices(void) const { return mVertices; };
|
const FloatVector &GetVertices(void) const { return mVertices; };
|
||||||
const IntVector& GetIndices(void) const { return mIndices; };
|
const IntVector &GetIndices(void) const { return mIndices; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FloatVector mVertices;
|
FloatVector mVertices;
|
||||||
IntVector mIndices;
|
IntVector mIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
WavefrontObj::WavefrontObj(void)
|
WavefrontObj::WavefrontObj(void)
|
||||||
{
|
{
|
||||||
mVertexCount = 0;
|
mVertexCount = 0;
|
||||||
@@ -816,45 +784,41 @@ WavefrontObj::WavefrontObj(void)
|
|||||||
|
|
||||||
WavefrontObj::~WavefrontObj(void)
|
WavefrontObj::~WavefrontObj(void)
|
||||||
{
|
{
|
||||||
delete [] mIndices;
|
delete[] mIndices;
|
||||||
delete [] mVertices;
|
delete[] mVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int WavefrontObj::loadObj(const char *fname) // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed.
|
unsigned int WavefrontObj::loadObj(const char *fname) // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed.
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
|
|
||||||
delete [] mVertices;
|
delete[] mVertices;
|
||||||
mVertices = 0;
|
mVertices = 0;
|
||||||
delete [] mIndices;
|
delete[] mIndices;
|
||||||
mIndices = 0;
|
mIndices = 0;
|
||||||
mVertexCount = 0;
|
mVertexCount = 0;
|
||||||
mTriCount = 0;
|
mTriCount = 0;
|
||||||
|
|
||||||
|
|
||||||
BuildMesh bm;
|
BuildMesh bm;
|
||||||
|
|
||||||
OBJ obj;
|
OBJ obj;
|
||||||
|
|
||||||
obj.LoadMesh(fname,&bm);
|
obj.LoadMesh(fname, &bm);
|
||||||
|
|
||||||
|
|
||||||
const FloatVector &vlist = bm.GetVertices();
|
const FloatVector &vlist = bm.GetVertices();
|
||||||
const IntVector &indices = bm.GetIndices();
|
const IntVector &indices = bm.GetIndices();
|
||||||
if ( vlist.size() )
|
if (vlist.size())
|
||||||
{
|
{
|
||||||
mVertexCount = vlist.size()/3;
|
mVertexCount = vlist.size() / 3;
|
||||||
mVertices = new float[mVertexCount*3];
|
mVertices = new float[mVertexCount * 3];
|
||||||
memcpy( mVertices, &vlist[0], sizeof(float)*mVertexCount*3 );
|
memcpy(mVertices, &vlist[0], sizeof(float) * mVertexCount * 3);
|
||||||
mTriCount = indices.size()/3;
|
mTriCount = indices.size() / 3;
|
||||||
mIndices = new int[mTriCount*3*sizeof(int)];
|
mIndices = new int[mTriCount * 3 * sizeof(int)];
|
||||||
memcpy(mIndices, &indices[0], sizeof(int)*mTriCount*3);
|
memcpy(mIndices, &indices[0], sizeof(int) * mTriCount * 3);
|
||||||
ret = mTriCount;
|
ret = mTriCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ConvexDecomposition
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#ifndef CD_WAVEFRONT_OBJ_H
|
#ifndef CD_WAVEFRONT_OBJ_H
|
||||||
|
|
||||||
|
|
||||||
#define CD_WAVEFRONT_OBJ_H
|
#define CD_WAVEFRONT_OBJ_H
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -38,14 +36,11 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
|
||||||
class WavefrontObj
|
class WavefrontObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WavefrontObj(void);
|
WavefrontObj(void);
|
||||||
~WavefrontObj(void);
|
~WavefrontObj(void);
|
||||||
|
|
||||||
@@ -57,6 +52,6 @@ public:
|
|||||||
float *mVertices;
|
float *mVertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace ConvexDecomposition
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -49,13 +49,11 @@
|
|||||||
#include "splitplane.h"
|
#include "splitplane.h"
|
||||||
#include "ConvexDecomposition.h"
|
#include "ConvexDecomposition.h"
|
||||||
|
|
||||||
|
|
||||||
#define WSCALE 4
|
#define WSCALE 4
|
||||||
#define CONCAVE_THRESH 0.05f
|
#define CONCAVE_THRESH 0.05f
|
||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned int getDebugColor(void)
|
unsigned int getDebugColor(void)
|
||||||
{
|
{
|
||||||
static unsigned int colors[8] =
|
static unsigned int colors[8] =
|
||||||
@@ -67,27 +65,25 @@ unsigned int getDebugColor(void)
|
|||||||
0x00FFFF,
|
0x00FFFF,
|
||||||
0xFF00FF,
|
0xFF00FF,
|
||||||
0xFFFFFF,
|
0xFFFFFF,
|
||||||
0xFF8040
|
0xFF8040};
|
||||||
};
|
|
||||||
|
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if ( count == 8 ) count = 0;
|
if (count == 8) count = 0;
|
||||||
|
|
||||||
assert( count >= 0 && count < 8 );
|
assert(count >= 0 && count < 8);
|
||||||
|
|
||||||
unsigned int color = colors[count];
|
unsigned int color = colors[count];
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Wpoint
|
class Wpoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Wpoint(const Vector3d &p,float w)
|
Wpoint(const Vector3d &p, float w)
|
||||||
{
|
{
|
||||||
mPoint = p;
|
mPoint = p;
|
||||||
mWeight = w;
|
mWeight = w;
|
||||||
@@ -97,23 +93,20 @@ public:
|
|||||||
float mWeight;
|
float mWeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< Wpoint > WpointVector;
|
typedef std::vector<Wpoint> WpointVector;
|
||||||
|
|
||||||
|
static inline float DistToPt(const float *p, const float *plane)
|
||||||
static inline float DistToPt(const float *p,const float *plane)
|
|
||||||
{
|
{
|
||||||
float x = p[0];
|
float x = p[0];
|
||||||
float y = p[1];
|
float y = p[1];
|
||||||
float z = p[2];
|
float z = p[2];
|
||||||
float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
|
float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3];
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intersect(const float *p1, const float *p2, float *split, const float *plane)
|
||||||
static void intersect(const float *p1,const float *p2,float *split,const float *plane)
|
|
||||||
{
|
{
|
||||||
|
float dp1 = DistToPt(p1, plane);
|
||||||
float dp1 = DistToPt(p1,plane);
|
|
||||||
|
|
||||||
float dir[3];
|
float dir[3];
|
||||||
|
|
||||||
@@ -121,23 +114,22 @@ static void intersect(const float *p1,const float *p2,float *split,const float *
|
|||||||
dir[1] = p2[1] - p1[1];
|
dir[1] = p2[1] - p1[1];
|
||||||
dir[2] = p2[2] - p1[2];
|
dir[2] = p2[2] - p1[2];
|
||||||
|
|
||||||
float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
|
float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2];
|
||||||
float dot2 = dp1 - plane[3];
|
float dot2 = dp1 - plane[3];
|
||||||
|
|
||||||
float t = -(plane[3] + dot2 ) / dot1;
|
float t = -(plane[3] + dot2) / dot1;
|
||||||
|
|
||||||
split[0] = (dir[0]*t)+p1[0];
|
split[0] = (dir[0] * t) + p1[0];
|
||||||
split[1] = (dir[1]*t)+p1[1];
|
split[1] = (dir[1] * t) + p1[1];
|
||||||
split[2] = (dir[2]*t)+p1[2];
|
split[2] = (dir[2] * t) + p1[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CTri
|
class CTri
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CTri(void) { };
|
CTri(void){};
|
||||||
|
|
||||||
CTri(const float *p1,const float *p2,const float *p3,unsigned int i1,unsigned int i2,unsigned int i3)
|
CTri(const float *p1, const float *p2, const float *p3, unsigned int i1, unsigned int i2, unsigned int i3)
|
||||||
{
|
{
|
||||||
mProcessed = 0;
|
mProcessed = 0;
|
||||||
mI1 = i1;
|
mI1 = i1;
|
||||||
@@ -148,7 +140,7 @@ public:
|
|||||||
mP2.Set(p2);
|
mP2.Set(p2);
|
||||||
mP3.Set(p3);
|
mP3.Set(p3);
|
||||||
|
|
||||||
mPlaneD = mNormal.ComputePlane(mP1,mP2,mP3);
|
mPlaneD = mNormal.ComputePlane(mP1, mP2, mP3);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Facing(const CTri &t)
|
float Facing(const CTri &t)
|
||||||
@@ -158,56 +150,55 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clip this line segment against this triangle.
|
// clip this line segment against this triangle.
|
||||||
bool clip(const Vector3d &start,Vector3d &end) const
|
bool clip(const Vector3d &start, Vector3d &end) const
|
||||||
{
|
{
|
||||||
Vector3d sect;
|
Vector3d sect;
|
||||||
|
|
||||||
bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr() );
|
bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr());
|
||||||
|
|
||||||
if ( hit )
|
if (hit)
|
||||||
{
|
{
|
||||||
end = sect;
|
end = sect;
|
||||||
}
|
}
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Concave(const Vector3d &p,float &distance,Vector3d &n) const
|
bool Concave(const Vector3d &p, float &distance, Vector3d &n) const
|
||||||
{
|
{
|
||||||
n.NearestPointInTriangle(p,mP1,mP2,mP3);
|
n.NearestPointInTriangle(p, mP1, mP2, mP3);
|
||||||
distance = p.Distance(n);
|
distance = p.Distance(n);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTri(unsigned int *indices,unsigned int i1,unsigned int i2,unsigned int i3,unsigned int &tcount) const
|
void addTri(unsigned int *indices, unsigned int i1, unsigned int i2, unsigned int i3, unsigned int &tcount) const
|
||||||
{
|
{
|
||||||
indices[tcount*3+0] = i1;
|
indices[tcount * 3 + 0] = i1;
|
||||||
indices[tcount*3+1] = i2;
|
indices[tcount * 3 + 1] = i2;
|
||||||
indices[tcount*3+2] = i3;
|
indices[tcount * 3 + 2] = i3;
|
||||||
tcount++;
|
tcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getVolume(ConvexDecompInterface *callback) const
|
float getVolume(ConvexDecompInterface *callback) const
|
||||||
{
|
{
|
||||||
unsigned int indices[8*3];
|
unsigned int indices[8 * 3];
|
||||||
|
|
||||||
|
|
||||||
unsigned int tcount = 0;
|
unsigned int tcount = 0;
|
||||||
|
|
||||||
addTri(indices,0,1,2,tcount);
|
addTri(indices, 0, 1, 2, tcount);
|
||||||
addTri(indices,3,4,5,tcount);
|
addTri(indices, 3, 4, 5, tcount);
|
||||||
|
|
||||||
addTri(indices,0,3,4,tcount);
|
addTri(indices, 0, 3, 4, tcount);
|
||||||
addTri(indices,0,4,1,tcount);
|
addTri(indices, 0, 4, 1, tcount);
|
||||||
|
|
||||||
addTri(indices,1,4,5,tcount);
|
addTri(indices, 1, 4, 5, tcount);
|
||||||
addTri(indices,1,5,2,tcount);
|
addTri(indices, 1, 5, 2, tcount);
|
||||||
|
|
||||||
addTri(indices,0,3,5,tcount);
|
addTri(indices, 0, 3, 5, tcount);
|
||||||
addTri(indices,0,5,2,tcount);
|
addTri(indices, 0, 5, 2, tcount);
|
||||||
|
|
||||||
const float *vertices = mP1.Ptr();
|
const float *vertices = mP1.Ptr();
|
||||||
|
|
||||||
if ( callback )
|
if (callback)
|
||||||
{
|
{
|
||||||
unsigned int color = getDebugColor();
|
unsigned int color = getDebugColor();
|
||||||
|
|
||||||
@@ -228,29 +219,27 @@ public:
|
|||||||
callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00);
|
callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
for (unsigned int i=0; i<tcount; i++)
|
for (unsigned int i = 0; i < tcount; i++)
|
||||||
{
|
{
|
||||||
unsigned int i1 = indices[i*3+0];
|
unsigned int i1 = indices[i * 3 + 0];
|
||||||
unsigned int i2 = indices[i*3+1];
|
unsigned int i2 = indices[i * 3 + 1];
|
||||||
unsigned int i3 = indices[i*3+2];
|
unsigned int i3 = indices[i * 3 + 2];
|
||||||
|
|
||||||
const float *p1 = &vertices[ i1*3 ];
|
const float *p1 = &vertices[i1 * 3];
|
||||||
const float *p2 = &vertices[ i2*3 ];
|
const float *p2 = &vertices[i2 * 3];
|
||||||
const float *p3 = &vertices[ i3*3 ];
|
const float *p3 = &vertices[i3 * 3];
|
||||||
|
|
||||||
callback->ConvexDebugTri(p1,p2,p3,color);
|
|
||||||
|
|
||||||
|
callback->ConvexDebugTri(p1, p2, p3, color);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float v = computeMeshVolume(mP1.Ptr(), tcount, indices );
|
float v = computeMeshVolume(mP1.Ptr(), tcount, indices);
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float raySect(const Vector3d &p,const Vector3d &dir,Vector3d §) const
|
float raySect(const Vector3d &p, const Vector3d &dir, Vector3d §) const
|
||||||
{
|
{
|
||||||
float plane[4];
|
float plane[4];
|
||||||
|
|
||||||
@@ -259,12 +248,11 @@ public:
|
|||||||
plane[2] = mNormal.z;
|
plane[2] = mNormal.z;
|
||||||
plane[3] = mPlaneD;
|
plane[3] = mPlaneD;
|
||||||
|
|
||||||
Vector3d dest = p+dir*100000;
|
Vector3d dest = p + dir * 100000;
|
||||||
|
|
||||||
intersect( p.Ptr(), dest.Ptr(), sect.Ptr(), plane );
|
intersect(p.Ptr(), dest.Ptr(), sect.Ptr(), plane);
|
||||||
|
|
||||||
return sect.Distance(p); // return the intersection distance.
|
return sect.Distance(p); // return the intersection distance.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float planeDistance(const Vector3d &p) const
|
float planeDistance(const Vector3d &p) const
|
||||||
@@ -276,27 +264,26 @@ public:
|
|||||||
plane[2] = mNormal.z;
|
plane[2] = mNormal.z;
|
||||||
plane[3] = mPlaneD;
|
plane[3] = mPlaneD;
|
||||||
|
|
||||||
return DistToPt( p.Ptr(), plane );
|
return DistToPt(p.Ptr(), plane);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool samePlane(const CTri &t) const
|
bool samePlane(const CTri &t) const
|
||||||
{
|
{
|
||||||
const float THRESH = 0.001f;
|
const float THRESH = 0.001f;
|
||||||
float dd = fabsf( t.mPlaneD - mPlaneD );
|
float dd = fabsf(t.mPlaneD - mPlaneD);
|
||||||
if ( dd > THRESH ) return false;
|
if (dd > THRESH) return false;
|
||||||
dd = fabsf( t.mNormal.x - mNormal.x );
|
dd = fabsf(t.mNormal.x - mNormal.x);
|
||||||
if ( dd > THRESH ) return false;
|
if (dd > THRESH) return false;
|
||||||
dd = fabsf( t.mNormal.y - mNormal.y );
|
dd = fabsf(t.mNormal.y - mNormal.y);
|
||||||
if ( dd > THRESH ) return false;
|
if (dd > THRESH) return false;
|
||||||
dd = fabsf( t.mNormal.z - mNormal.z );
|
dd = fabsf(t.mNormal.z - mNormal.z);
|
||||||
if ( dd > THRESH ) return false;
|
if (dd > THRESH) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasIndex(unsigned int i) const
|
bool hasIndex(unsigned int i) const
|
||||||
{
|
{
|
||||||
if ( i == mI1 || i == mI2 || i == mI3 ) return true;
|
if (i == mI1 || i == mI2 || i == mI3) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,54 +292,53 @@ public:
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
if ( t.hasIndex(mI1) ) count++;
|
if (t.hasIndex(mI1)) count++;
|
||||||
if ( t.hasIndex(mI2) ) count++;
|
if (t.hasIndex(mI2)) count++;
|
||||||
if ( t.hasIndex(mI3) ) count++;
|
if (t.hasIndex(mI3)) count++;
|
||||||
|
|
||||||
if ( count >= 2 ) ret = true;
|
if (count >= 2) ret = true;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug(unsigned int color,ConvexDecompInterface *callback)
|
void debug(unsigned int color, ConvexDecompInterface *callback)
|
||||||
{
|
{
|
||||||
callback->ConvexDebugTri( mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color );
|
callback->ConvexDebugTri(mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color);
|
||||||
callback->ConvexDebugTri( mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000 );
|
callback->ConvexDebugTri(mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000);
|
||||||
callback->ConvexDebugTri( mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000 );
|
callback->ConvexDebugTri(mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000);
|
||||||
callback->ConvexDebugTri( mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000 );
|
callback->ConvexDebugTri(mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000);
|
||||||
callback->ConvexDebugPoint( mNear1.Ptr(), 0.01f, 0xFF0000 );
|
callback->ConvexDebugPoint(mNear1.Ptr(), 0.01f, 0xFF0000);
|
||||||
callback->ConvexDebugPoint( mNear2.Ptr(), 0.01f, 0xFF0000 );
|
callback->ConvexDebugPoint(mNear2.Ptr(), 0.01f, 0xFF0000);
|
||||||
callback->ConvexDebugPoint( mNear3.Ptr(), 0.01f, 0xFF0000 );
|
callback->ConvexDebugPoint(mNear3.Ptr(), 0.01f, 0xFF0000);
|
||||||
}
|
}
|
||||||
|
|
||||||
float area(void)
|
float area(void)
|
||||||
{
|
{
|
||||||
float a = mConcavity*mP1.Area(mP2,mP3);
|
float a = mConcavity * mP1.Area(mP2, mP3);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addWeighted(WpointVector &list,ConvexDecompInterface *callback)
|
void addWeighted(WpointVector &list, ConvexDecompInterface *callback)
|
||||||
{
|
{
|
||||||
|
Wpoint p1(mP1, mC1);
|
||||||
Wpoint p1(mP1,mC1);
|
Wpoint p2(mP2, mC2);
|
||||||
Wpoint p2(mP2,mC2);
|
Wpoint p3(mP3, mC3);
|
||||||
Wpoint p3(mP3,mC3);
|
|
||||||
|
|
||||||
Vector3d d1 = mNear1 - mP1;
|
Vector3d d1 = mNear1 - mP1;
|
||||||
Vector3d d2 = mNear2 - mP2;
|
Vector3d d2 = mNear2 - mP2;
|
||||||
Vector3d d3 = mNear3 - mP3;
|
Vector3d d3 = mNear3 - mP3;
|
||||||
|
|
||||||
d1*=WSCALE;
|
d1 *= WSCALE;
|
||||||
d2*=WSCALE;
|
d2 *= WSCALE;
|
||||||
d3*=WSCALE;
|
d3 *= WSCALE;
|
||||||
|
|
||||||
d1 = d1 + mP1;
|
d1 = d1 + mP1;
|
||||||
d2 = d2 + mP2;
|
d2 = d2 + mP2;
|
||||||
d3 = d3 + mP3;
|
d3 = d3 + mP3;
|
||||||
|
|
||||||
Wpoint p4(d1,mC1);
|
Wpoint p4(d1, mC1);
|
||||||
Wpoint p5(d2,mC2);
|
Wpoint p5(d2, mC2);
|
||||||
Wpoint p6(d3,mC3);
|
Wpoint p6(d3, mC3);
|
||||||
|
|
||||||
list.push_back(p1);
|
list.push_back(p1);
|
||||||
list.push_back(p2);
|
list.push_back(p2);
|
||||||
@@ -387,9 +373,6 @@ public:
|
|||||||
callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF );
|
callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d mP1;
|
Vector3d mP1;
|
||||||
@@ -410,11 +393,10 @@ public:
|
|||||||
int mProcessed; // already been added...
|
int mProcessed; // already been added...
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< CTri > CTriVector;
|
typedef std::vector<CTri> CTriVector;
|
||||||
|
|
||||||
bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback,const CTriVector &input_mesh)
|
bool featureMatch(CTri &m, const CTriVector &tris, ConvexDecompInterface *callback, const CTriVector &input_mesh)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
float neardot = 0.707f;
|
float neardot = 0.707f;
|
||||||
@@ -429,15 +411,13 @@ bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback
|
|||||||
|
|
||||||
CTri nearest;
|
CTri nearest;
|
||||||
|
|
||||||
|
for (i = tris.begin(); i != tris.end(); ++i)
|
||||||
for (i=tris.begin(); i!=tris.end(); ++i)
|
|
||||||
{
|
{
|
||||||
const CTri &t = (*i);
|
const CTri &t = (*i);
|
||||||
|
|
||||||
|
|
||||||
//gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD );
|
//gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD );
|
||||||
|
|
||||||
if ( t.samePlane(m) )
|
if (t.samePlane(m))
|
||||||
{
|
{
|
||||||
//gLog->Display("*** PLANE MATCH!!!\r\n");
|
//gLog->Display("*** PLANE MATCH!!!\r\n");
|
||||||
ret = false;
|
ret = false;
|
||||||
@@ -446,45 +426,42 @@ bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback
|
|||||||
|
|
||||||
float dot = t.mNormal.Dot(m.mNormal);
|
float dot = t.mNormal.Dot(m.mNormal);
|
||||||
|
|
||||||
if ( dot > neardot )
|
if (dot > neardot)
|
||||||
{
|
{
|
||||||
|
float d1 = t.planeDistance(m.mP1);
|
||||||
|
float d2 = t.planeDistance(m.mP2);
|
||||||
|
float d3 = t.planeDistance(m.mP3);
|
||||||
|
|
||||||
float d1 = t.planeDistance( m.mP1 );
|
if (d1 > 0.001f || d2 > 0.001f || d3 > 0.001f) // can't be near coplaner!
|
||||||
float d2 = t.planeDistance( m.mP2 );
|
|
||||||
float d3 = t.planeDistance( m.mP3 );
|
|
||||||
|
|
||||||
if ( d1 > 0.001f || d2 > 0.001f || d3 > 0.001f ) // can't be near coplaner!
|
|
||||||
{
|
{
|
||||||
|
|
||||||
neardot = dot;
|
neardot = dot;
|
||||||
|
|
||||||
Vector3d n1,n2,n3;
|
Vector3d n1, n2, n3;
|
||||||
|
|
||||||
t.raySect( m.mP1, m.mNormal, m.mNear1 );
|
t.raySect(m.mP1, m.mNormal, m.mNear1);
|
||||||
t.raySect( m.mP2, m.mNormal, m.mNear2 );
|
t.raySect(m.mP2, m.mNormal, m.mNear2);
|
||||||
t.raySect( m.mP3, m.mNormal, m.mNear3 );
|
t.raySect(m.mP3, m.mNormal, m.mNear3);
|
||||||
|
|
||||||
nearest = t;
|
nearest = t;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret )
|
if (ret)
|
||||||
{
|
{
|
||||||
if ( 0 )
|
if (0)
|
||||||
{
|
{
|
||||||
CTriVector::const_iterator i;
|
CTriVector::const_iterator i;
|
||||||
for (i=input_mesh.begin(); i!=input_mesh.end(); ++i)
|
for (i = input_mesh.begin(); i != input_mesh.end(); ++i)
|
||||||
{
|
{
|
||||||
const CTri &c = (*i);
|
const CTri &c = (*i);
|
||||||
if ( c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3 )
|
if (c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3)
|
||||||
{
|
{
|
||||||
c.clip( m.mP1, m.mNear1 );
|
c.clip(m.mP1, m.mNear1);
|
||||||
c.clip( m.mP2, m.mNear2 );
|
c.clip(m.mP2, m.mNear2);
|
||||||
c.clip( m.mP3, m.mNear3 );
|
c.clip(m.mP3, m.mNear3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,24 +469,23 @@ bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback
|
|||||||
//gLog->Display("*********************************************\r\n");
|
//gLog->Display("*********************************************\r\n");
|
||||||
//gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD );
|
//gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD );
|
||||||
|
|
||||||
m.mC1 = m.mP1.Distance( m.mNear1 );
|
m.mC1 = m.mP1.Distance(m.mNear1);
|
||||||
m.mC2 = m.mP2.Distance( m.mNear2 );
|
m.mC2 = m.mP2.Distance(m.mNear2);
|
||||||
m.mC3 = m.mP3.Distance( m.mNear3 );
|
m.mC3 = m.mP3.Distance(m.mNear3);
|
||||||
|
|
||||||
m.mConcavity = m.mC1;
|
m.mConcavity = m.mC1;
|
||||||
|
|
||||||
if ( m.mC2 > m.mConcavity ) m.mConcavity = m.mC2;
|
if (m.mC2 > m.mConcavity) m.mConcavity = m.mC2;
|
||||||
if ( m.mC3 > m.mConcavity ) m.mConcavity = m.mC3;
|
if (m.mC3 > m.mConcavity) m.mConcavity = m.mC3;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
callback->ConvexDebugTri( m.mP1.Ptr(), m.mP2.Ptr(), m.mP3.Ptr(), 0x00FF00 );
|
callback->ConvexDebugTri( m.mP1.Ptr(), m.mP2.Ptr(), m.mP3.Ptr(), 0x00FF00 );
|
||||||
callback->ConvexDebugTri( m.mNear1.Ptr(), m.mNear2.Ptr(), m.mNear3.Ptr(), 0xFF0000 );
|
callback->ConvexDebugTri( m.mNear1.Ptr(), m.mNear2.Ptr(), m.mNear3.Ptr(), 0xFF0000 );
|
||||||
|
|
||||||
callback->ConvexDebugTri( m.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.Ptr(), 0xFFFF00 );
|
callback->ConvexDebugTri( m.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.Ptr(), 0xFFFF00 );
|
||||||
callback->ConvexDebugTri( m.mP2.Ptr(), m.mP2.Ptr(), m.mNear2.Ptr(), 0xFFFF00 );
|
callback->ConvexDebugTri( m.mP2.Ptr(), m.mP2.Ptr(), m.mNear2.Ptr(), 0xFFFF00 );
|
||||||
callback->ConvexDebugTri( m.mP3.Ptr(), m.mP3.Ptr(), m.mNear3.Ptr(), 0xFFFF00 );
|
callback->ConvexDebugTri( m.mP3.Ptr(), m.mP3.Ptr(), m.mNear3.Ptr(), 0xFFFF00 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -520,31 +496,30 @@ bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFeatureTri(CTri &t,CTriVector &flist,float fc,ConvexDecompInterface *callback,unsigned int color)
|
bool isFeatureTri(CTri &t, CTriVector &flist, float fc, ConvexDecompInterface *callback, unsigned int color)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if ( t.mProcessed == 0 ) // if not already processed
|
if (t.mProcessed == 0) // if not already processed
|
||||||
{
|
{
|
||||||
|
|
||||||
float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent.
|
float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent.
|
||||||
|
|
||||||
if ( c > 0.85f )
|
if (c > 0.85f)
|
||||||
{
|
{
|
||||||
// see if this triangle is a 'feature' triangle. Meaning it shares an
|
// see if this triangle is a 'feature' triangle. Meaning it shares an
|
||||||
// edge with any existing feature triangle and is within roughly the same
|
// edge with any existing feature triangle and is within roughly the same
|
||||||
// concavity of the parent.
|
// concavity of the parent.
|
||||||
if ( flist.size() )
|
if (flist.size())
|
||||||
{
|
{
|
||||||
CTriVector::iterator i;
|
CTriVector::iterator i;
|
||||||
for (i=flist.begin(); i!=flist.end(); ++i)
|
for (i = flist.begin(); i != flist.end(); ++i)
|
||||||
{
|
{
|
||||||
CTri &ftri = (*i);
|
CTri &ftri = (*i);
|
||||||
if ( ftri.sharesEdge(t) )
|
if (ftri.sharesEdge(t))
|
||||||
{
|
{
|
||||||
t.mProcessed = 2; // it is now part of a feature.
|
t.mProcessed = 2; // it is now part of a feature.
|
||||||
flist.push_back(t); // add it to the feature list.
|
flist.push_back(t); // add it to the feature list.
|
||||||
// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
|
// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -554,7 +529,7 @@ bool isFeatureTri(CTri &t,CTriVector &flist,float fc,ConvexDecompInterface *call
|
|||||||
{
|
{
|
||||||
t.mProcessed = 2;
|
t.mProcessed = 2;
|
||||||
flist.push_back(t); // add it to the feature list.
|
flist.push_back(t); // add it to the feature list.
|
||||||
// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
|
// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +537,6 @@ bool isFeatureTri(CTri &t,CTriVector &flist,float fc,ConvexDecompInterface *call
|
|||||||
{
|
{
|
||||||
t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one..
|
t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one..
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -575,8 +549,6 @@ float computeConcavity(unsigned int vcount,
|
|||||||
float *plane, // plane equation to split on
|
float *plane, // plane equation to split on
|
||||||
float &volume)
|
float &volume)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
float cret = 0;
|
float cret = 0;
|
||||||
volume = 1;
|
volume = 1;
|
||||||
|
|
||||||
@@ -588,14 +560,13 @@ float computeConcavity(unsigned int vcount,
|
|||||||
desc.mMaxVertices = 256;
|
desc.mMaxVertices = 256;
|
||||||
desc.SetHullFlag(QF_TRIANGLES);
|
desc.SetHullFlag(QF_TRIANGLES);
|
||||||
|
|
||||||
|
|
||||||
desc.mVcount = vcount;
|
desc.mVcount = vcount;
|
||||||
desc.mVertices = vertices;
|
desc.mVertices = vertices;
|
||||||
desc.mVertexStride = sizeof(float)*3;
|
desc.mVertexStride = sizeof(float) * 3;
|
||||||
|
|
||||||
HullError ret = hl.CreateConvexHull(desc,result);
|
HullError ret = hl.CreateConvexHull(desc, result);
|
||||||
|
|
||||||
if ( ret == QE_OK )
|
if (ret == QE_OK)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
float bmin[3];
|
float bmin[3];
|
||||||
@@ -612,7 +583,7 @@ float computeConcavity(unsigned int vcount,
|
|||||||
center.z = bmin[2] + dz*0.5f;
|
center.z = bmin[2] + dz*0.5f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
volume = computeMeshVolume2( result.mOutputVertices, result.mNumFaces, result.mIndices );
|
volume = computeMeshVolume2(result.mOutputVertices, result.mNumFaces, result.mIndices);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// ok..now..for each triangle on the original mesh..
|
// ok..now..for each triangle on the original mesh..
|
||||||
@@ -621,19 +592,19 @@ float computeConcavity(unsigned int vcount,
|
|||||||
|
|
||||||
CTriVector tris;
|
CTriVector tris;
|
||||||
|
|
||||||
for (unsigned int i=0; i<result.mNumFaces; i++)
|
for (unsigned int i = 0; i < result.mNumFaces; i++)
|
||||||
{
|
{
|
||||||
unsigned int i1 = *source++;
|
unsigned int i1 = *source++;
|
||||||
unsigned int i2 = *source++;
|
unsigned int i2 = *source++;
|
||||||
unsigned int i3 = *source++;
|
unsigned int i3 = *source++;
|
||||||
|
|
||||||
const float *p1 = &result.mOutputVertices[i1*3];
|
const float *p1 = &result.mOutputVertices[i1 * 3];
|
||||||
const float *p2 = &result.mOutputVertices[i2*3];
|
const float *p2 = &result.mOutputVertices[i2 * 3];
|
||||||
const float *p3 = &result.mOutputVertices[i3*3];
|
const float *p3 = &result.mOutputVertices[i3 * 3];
|
||||||
|
|
||||||
// callback->ConvexDebugTri(p1,p2,p3,0xFFFFFF);
|
// callback->ConvexDebugTri(p1,p2,p3,0xFFFFFF);
|
||||||
|
|
||||||
CTri t(p1,p2,p3,i1,i2,i3); //
|
CTri t(p1, p2, p3, i1, i2, i3); //
|
||||||
tris.push_back(t);
|
tris.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,63 +616,57 @@ float computeConcavity(unsigned int vcount,
|
|||||||
|
|
||||||
const unsigned int *src = indices;
|
const unsigned int *src = indices;
|
||||||
|
|
||||||
|
float maxc = 0;
|
||||||
|
|
||||||
float maxc=0;
|
if (1)
|
||||||
|
|
||||||
|
|
||||||
if ( 1 )
|
|
||||||
{
|
{
|
||||||
CTriVector input_mesh;
|
CTriVector input_mesh;
|
||||||
if ( 1 )
|
if (1)
|
||||||
{
|
{
|
||||||
const unsigned int *src = indices;
|
const unsigned int *src = indices;
|
||||||
for (unsigned int i=0; i<tcount; i++)
|
for (unsigned int i = 0; i < tcount; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned int i1 = *src++;
|
unsigned int i1 = *src++;
|
||||||
unsigned int i2 = *src++;
|
unsigned int i2 = *src++;
|
||||||
unsigned int i3 = *src++;
|
unsigned int i3 = *src++;
|
||||||
|
|
||||||
const float *p1 = &vertices[i1*3];
|
const float *p1 = &vertices[i1 * 3];
|
||||||
const float *p2 = &vertices[i2*3];
|
const float *p2 = &vertices[i2 * 3];
|
||||||
const float *p3 = &vertices[i3*3];
|
const float *p3 = &vertices[i3 * 3];
|
||||||
|
|
||||||
CTri t(p1,p2,p3,i1,i2,i3);
|
CTri t(p1, p2, p3, i1, i2, i3);
|
||||||
input_mesh.push_back(t);
|
input_mesh.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CTri maxctri;
|
CTri maxctri;
|
||||||
|
|
||||||
for (unsigned int i=0; i<tcount; i++)
|
for (unsigned int i = 0; i < tcount; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned int i1 = *src++;
|
unsigned int i1 = *src++;
|
||||||
unsigned int i2 = *src++;
|
unsigned int i2 = *src++;
|
||||||
unsigned int i3 = *src++;
|
unsigned int i3 = *src++;
|
||||||
|
|
||||||
const float *p1 = &vertices[i1*3];
|
const float *p1 = &vertices[i1 * 3];
|
||||||
const float *p2 = &vertices[i2*3];
|
const float *p2 = &vertices[i2 * 3];
|
||||||
const float *p3 = &vertices[i3*3];
|
const float *p3 = &vertices[i3 * 3];
|
||||||
|
|
||||||
CTri t(p1,p2,p3,i1,i2,i3);
|
CTri t(p1, p2, p3, i1, i2, i3);
|
||||||
|
|
||||||
featureMatch(t, tris, callback, input_mesh );
|
featureMatch(t, tris, callback, input_mesh);
|
||||||
|
|
||||||
if ( t.mConcavity > CONCAVE_THRESH )
|
if (t.mConcavity > CONCAVE_THRESH)
|
||||||
{
|
{
|
||||||
|
if (t.mConcavity > maxc)
|
||||||
if ( t.mConcavity > maxc )
|
|
||||||
{
|
{
|
||||||
maxc = t.mConcavity;
|
maxc = t.mConcavity;
|
||||||
maxctri = t;
|
maxctri = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
float v = t.getVolume(0);
|
float v = t.getVolume(0);
|
||||||
totalVolume+=v;
|
totalVolume += v;
|
||||||
ftris.push_back(t);
|
ftris.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,5 +758,4 @@ float computeConcavity(unsigned int vcount,
|
|||||||
return cret;
|
return cret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace ConvexDecomposition
|
||||||
}
|
|
||||||
|
|||||||
@@ -36,11 +36,8 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
|
||||||
class ConvexDecompInterface;
|
class ConvexDecompInterface;
|
||||||
|
|
||||||
// compute's how 'concave' this object is and returns the total volume of the
|
// compute's how 'concave' this object is and returns the total volume of the
|
||||||
@@ -53,8 +50,6 @@ float computeConcavity(unsigned int vcount,
|
|||||||
float *plane,
|
float *plane,
|
||||||
float &volume);
|
float &volume);
|
||||||
|
|
||||||
|
} // namespace ConvexDecomposition
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "fitsphere.h"
|
#include "fitsphere.h"
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -55,23 +54,22 @@ from "Graphics Gems", Academic Press, 1990
|
|||||||
|
|
||||||
#define BIGNUMBER 100000000.0 /* hundred million */
|
#define BIGNUMBER 100000000.0 /* hundred million */
|
||||||
|
|
||||||
static inline void Set(float *n,float x,float y,float z)
|
static inline void Set(float *n, float x, float y, float z)
|
||||||
{
|
{
|
||||||
n[0] = x;
|
n[0] = x;
|
||||||
n[1] = y;
|
n[1] = y;
|
||||||
n[2] = z;
|
n[2] = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void Copy(float *dest,const float *source)
|
static inline void Copy(float *dest, const float *source)
|
||||||
{
|
{
|
||||||
dest[0] = source[0];
|
dest[0] = source[0];
|
||||||
dest[1] = source[1];
|
dest[1] = source[1];
|
||||||
dest[2] = source[2];
|
dest[2] = source[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float computeBoundingSphere(unsigned int vcount,const float *points,float *center)
|
float computeBoundingSphere(unsigned int vcount, const float *points, float *center)
|
||||||
{
|
{
|
||||||
|
|
||||||
float mRadius;
|
float mRadius;
|
||||||
float mRadius2;
|
float mRadius2;
|
||||||
|
|
||||||
@@ -85,118 +83,115 @@ float computeBoundingSphere(unsigned int vcount,const float *points,float *cente
|
|||||||
float dia2[3];
|
float dia2[3];
|
||||||
|
|
||||||
/* FIRST PASS: find 6 minima/maxima points */
|
/* FIRST PASS: find 6 minima/maxima points */
|
||||||
Set(xmin,BIGNUMBER,BIGNUMBER,BIGNUMBER);
|
Set(xmin, BIGNUMBER, BIGNUMBER, BIGNUMBER);
|
||||||
Set(xmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
|
Set(xmax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER);
|
||||||
Set(ymin,BIGNUMBER,BIGNUMBER,BIGNUMBER);
|
Set(ymin, BIGNUMBER, BIGNUMBER, BIGNUMBER);
|
||||||
Set(ymax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
|
Set(ymax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER);
|
||||||
Set(zmin,BIGNUMBER,BIGNUMBER,BIGNUMBER);
|
Set(zmin, BIGNUMBER, BIGNUMBER, BIGNUMBER);
|
||||||
Set(zmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
|
Set(zmax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER);
|
||||||
|
|
||||||
for (unsigned i=0; i<vcount; i++)
|
for (unsigned i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
const float *caller_p = &points[i*3];
|
const float *caller_p = &points[i * 3];
|
||||||
|
|
||||||
if (caller_p[0]<xmin[0])
|
if (caller_p[0] < xmin[0])
|
||||||
Copy(xmin,caller_p); /* New xminimum point */
|
Copy(xmin, caller_p); /* New xminimum point */
|
||||||
if (caller_p[0]>xmax[0])
|
if (caller_p[0] > xmax[0])
|
||||||
Copy(xmax,caller_p);
|
Copy(xmax, caller_p);
|
||||||
if (caller_p[1]<ymin[1])
|
if (caller_p[1] < ymin[1])
|
||||||
Copy(ymin,caller_p);
|
Copy(ymin, caller_p);
|
||||||
if (caller_p[1]>ymax[1])
|
if (caller_p[1] > ymax[1])
|
||||||
Copy(ymax,caller_p);
|
Copy(ymax, caller_p);
|
||||||
if (caller_p[2]<zmin[2])
|
if (caller_p[2] < zmin[2])
|
||||||
Copy(zmin,caller_p);
|
Copy(zmin, caller_p);
|
||||||
if (caller_p[2]>zmax[2])
|
if (caller_p[2] > zmax[2])
|
||||||
Copy(zmax,caller_p);
|
Copy(zmax, caller_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set xspan = distance between the 2 points xmin & xmax (squared) */
|
/* Set xspan = distance between the 2 points xmin & xmax (squared) */
|
||||||
float dx = xmax[0] - xmin[0];
|
float dx = xmax[0] - xmin[0];
|
||||||
float dy = xmax[1] - xmin[1];
|
float dy = xmax[1] - xmin[1];
|
||||||
float dz = xmax[2] - xmin[2];
|
float dz = xmax[2] - xmin[2];
|
||||||
float xspan = dx*dx + dy*dy + dz*dz;
|
float xspan = dx * dx + dy * dy + dz * dz;
|
||||||
|
|
||||||
/* Same for y & z spans */
|
/* Same for y & z spans */
|
||||||
dx = ymax[0] - ymin[0];
|
dx = ymax[0] - ymin[0];
|
||||||
dy = ymax[1] - ymin[1];
|
dy = ymax[1] - ymin[1];
|
||||||
dz = ymax[2] - ymin[2];
|
dz = ymax[2] - ymin[2];
|
||||||
float yspan = dx*dx + dy*dy + dz*dz;
|
float yspan = dx * dx + dy * dy + dz * dz;
|
||||||
|
|
||||||
dx = zmax[0] - zmin[0];
|
dx = zmax[0] - zmin[0];
|
||||||
dy = zmax[1] - zmin[1];
|
dy = zmax[1] - zmin[1];
|
||||||
dz = zmax[2] - zmin[2];
|
dz = zmax[2] - zmin[2];
|
||||||
float zspan = dx*dx + dy*dy + dz*dz;
|
float zspan = dx * dx + dy * dy + dz * dz;
|
||||||
|
|
||||||
/* Set points dia1 & dia2 to the maximally separated pair */
|
/* Set points dia1 & dia2 to the maximally separated pair */
|
||||||
Copy(dia1,xmin);
|
Copy(dia1, xmin);
|
||||||
Copy(dia2,xmax); /* assume xspan biggest */
|
Copy(dia2, xmax); /* assume xspan biggest */
|
||||||
float maxspan = xspan;
|
float maxspan = xspan;
|
||||||
|
|
||||||
if (yspan>maxspan)
|
if (yspan > maxspan)
|
||||||
{
|
{
|
||||||
maxspan = yspan;
|
maxspan = yspan;
|
||||||
Copy(dia1,ymin);
|
Copy(dia1, ymin);
|
||||||
Copy(dia2,ymax);
|
Copy(dia2, ymax);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zspan>maxspan)
|
if (zspan > maxspan)
|
||||||
{
|
{
|
||||||
Copy(dia1,zmin);
|
Copy(dia1, zmin);
|
||||||
Copy(dia2,zmax);
|
Copy(dia2, zmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* dia1,dia2 is a diameter of initial sphere */
|
/* dia1,dia2 is a diameter of initial sphere */
|
||||||
/* calc initial center */
|
/* calc initial center */
|
||||||
center[0] = (dia1[0]+dia2[0])*0.5f;
|
center[0] = (dia1[0] + dia2[0]) * 0.5f;
|
||||||
center[1] = (dia1[1]+dia2[1])*0.5f;
|
center[1] = (dia1[1] + dia2[1]) * 0.5f;
|
||||||
center[2] = (dia1[2]+dia2[2])*0.5f;
|
center[2] = (dia1[2] + dia2[2]) * 0.5f;
|
||||||
|
|
||||||
/* calculate initial radius**2 and radius */
|
/* calculate initial radius**2 and radius */
|
||||||
|
|
||||||
dx = dia2[0]-center[0]; /* x component of radius vector */
|
dx = dia2[0] - center[0]; /* x component of radius vector */
|
||||||
dy = dia2[1]-center[1]; /* y component of radius vector */
|
dy = dia2[1] - center[1]; /* y component of radius vector */
|
||||||
dz = dia2[2]-center[2]; /* z component of radius vector */
|
dz = dia2[2] - center[2]; /* z component of radius vector */
|
||||||
|
|
||||||
mRadius2 = dx*dx + dy*dy + dz*dz;
|
mRadius2 = dx * dx + dy * dy + dz * dz;
|
||||||
mRadius = float(sqrt(mRadius2));
|
mRadius = float(sqrt(mRadius2));
|
||||||
|
|
||||||
/* SECOND PASS: increment current sphere */
|
/* SECOND PASS: increment current sphere */
|
||||||
|
|
||||||
if ( 1 )
|
if (1)
|
||||||
{
|
{
|
||||||
for (unsigned i=0; i<vcount; i++)
|
for (unsigned i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
const float *caller_p = &points[i*3];
|
const float *caller_p = &points[i * 3];
|
||||||
|
|
||||||
dx = caller_p[0]-center[0];
|
dx = caller_p[0] - center[0];
|
||||||
dy = caller_p[1]-center[1];
|
dy = caller_p[1] - center[1];
|
||||||
dz = caller_p[2]-center[2];
|
dz = caller_p[2] - center[2];
|
||||||
|
|
||||||
float old_to_p_sq = dx*dx + dy*dy + dz*dz;
|
float old_to_p_sq = dx * dx + dy * dy + dz * dz;
|
||||||
|
|
||||||
if (old_to_p_sq > mRadius2) /* do r**2 test first */
|
if (old_to_p_sq > mRadius2) /* do r**2 test first */
|
||||||
{ /* this point is outside of current sphere */
|
{ /* this point is outside of current sphere */
|
||||||
float old_to_p = float(sqrt(old_to_p_sq));
|
float old_to_p = float(sqrt(old_to_p_sq));
|
||||||
/* calc radius of new sphere */
|
/* calc radius of new sphere */
|
||||||
mRadius = (mRadius + old_to_p) * 0.5f;
|
mRadius = (mRadius + old_to_p) * 0.5f;
|
||||||
mRadius2 = mRadius*mRadius; /* for next r**2 compare */
|
mRadius2 = mRadius * mRadius; /* for next r**2 compare */
|
||||||
float old_to_new = old_to_p - mRadius;
|
float old_to_new = old_to_p - mRadius;
|
||||||
|
|
||||||
/* calc center of new sphere */
|
/* calc center of new sphere */
|
||||||
|
|
||||||
float recip = 1.0f /old_to_p;
|
float recip = 1.0f / old_to_p;
|
||||||
|
|
||||||
float cx = (mRadius*center[0] + old_to_new*caller_p[0]) * recip;
|
float cx = (mRadius * center[0] + old_to_new * caller_p[0]) * recip;
|
||||||
float cy = (mRadius*center[1] + old_to_new*caller_p[1]) * recip;
|
float cy = (mRadius * center[1] + old_to_new * caller_p[1]) * recip;
|
||||||
float cz = (mRadius*center[2] + old_to_new*caller_p[2]) * recip;
|
float cz = (mRadius * center[2] + old_to_new * caller_p[2]) * recip;
|
||||||
|
|
||||||
Set(center,cx,cy,cz);
|
Set(center, cx, cy, cz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mRadius;
|
return mRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
float computeBoundingSphere(unsigned int vcount, const float *points, float *center);
|
||||||
|
|
||||||
float computeBoundingSphere(unsigned int vcount,const float *points,float *center);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -41,58 +40,53 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
void fm_inverseRT(const float *matrix,const float *pos,float *t) // inverse rotate translate the point.
|
void fm_inverseRT(const float *matrix, const float *pos, float *t) // inverse rotate translate the point.
|
||||||
{
|
{
|
||||||
|
float _x = pos[0] - matrix[3 * 4 + 0];
|
||||||
float _x = pos[0] - matrix[3*4+0];
|
float _y = pos[1] - matrix[3 * 4 + 1];
|
||||||
float _y = pos[1] - matrix[3*4+1];
|
float _z = pos[2] - matrix[3 * 4 + 2];
|
||||||
float _z = pos[2] - matrix[3*4+2];
|
|
||||||
|
|
||||||
// Multiply inverse-translated source vector by inverted rotation transform
|
// Multiply inverse-translated source vector by inverted rotation transform
|
||||||
|
|
||||||
t[0] = (matrix[0*4+0] * _x) + (matrix[0*4+1] * _y) + (matrix[0*4+2] * _z);
|
t[0] = (matrix[0 * 4 + 0] * _x) + (matrix[0 * 4 + 1] * _y) + (matrix[0 * 4 + 2] * _z);
|
||||||
t[1] = (matrix[1*4+0] * _x) + (matrix[1*4+1] * _y) + (matrix[1*4+2] * _z);
|
t[1] = (matrix[1 * 4 + 0] * _x) + (matrix[1 * 4 + 1] * _y) + (matrix[1 * 4 + 2] * _z);
|
||||||
t[2] = (matrix[2*4+0] * _x) + (matrix[2*4+1] * _y) + (matrix[2*4+2] * _z);
|
t[2] = (matrix[2 * 4 + 0] * _x) + (matrix[2 * 4 + 1] * _y) + (matrix[2 * 4 + 2] * _z);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fm_identity(float *matrix) // set 4x4 matrix to identity.
|
void fm_identity(float *matrix) // set 4x4 matrix to identity.
|
||||||
{
|
{
|
||||||
matrix[0*4+0] = 1;
|
matrix[0 * 4 + 0] = 1;
|
||||||
matrix[1*4+1] = 1;
|
matrix[1 * 4 + 1] = 1;
|
||||||
matrix[2*4+2] = 1;
|
matrix[2 * 4 + 2] = 1;
|
||||||
matrix[3*4+3] = 1;
|
matrix[3 * 4 + 3] = 1;
|
||||||
|
|
||||||
matrix[1*4+0] = 0;
|
matrix[1 * 4 + 0] = 0;
|
||||||
matrix[2*4+0] = 0;
|
matrix[2 * 4 + 0] = 0;
|
||||||
matrix[3*4+0] = 0;
|
matrix[3 * 4 + 0] = 0;
|
||||||
|
|
||||||
matrix[0*4+1] = 0;
|
matrix[0 * 4 + 1] = 0;
|
||||||
matrix[2*4+1] = 0;
|
matrix[2 * 4 + 1] = 0;
|
||||||
matrix[3*4+1] = 0;
|
matrix[3 * 4 + 1] = 0;
|
||||||
|
|
||||||
matrix[0*4+2] = 0;
|
matrix[0 * 4 + 2] = 0;
|
||||||
matrix[1*4+2] = 0;
|
matrix[1 * 4 + 2] = 0;
|
||||||
matrix[3*4+2] = 0;
|
matrix[3 * 4 + 2] = 0;
|
||||||
|
|
||||||
matrix[0*4+3] = 0;
|
|
||||||
matrix[1*4+3] = 0;
|
|
||||||
matrix[2*4+3] = 0;
|
|
||||||
|
|
||||||
|
matrix[0 * 4 + 3] = 0;
|
||||||
|
matrix[1 * 4 + 3] = 0;
|
||||||
|
matrix[2 * 4 + 3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fm_eulerMatrix(float ax,float ay,float az,float *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero)
|
void fm_eulerMatrix(float ax, float ay, float az, float *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero)
|
||||||
{
|
{
|
||||||
float quat[4];
|
float quat[4];
|
||||||
fm_eulerToQuat(ax,ay,az,quat);
|
fm_eulerToQuat(ax, ay, az, quat);
|
||||||
fm_quatToMatrix(quat,matrix);
|
fm_quatToMatrix(quat, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax)
|
void fm_getAABB(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax)
|
||||||
{
|
{
|
||||||
|
const unsigned char *source = (const unsigned char *)points;
|
||||||
const unsigned char *source = (const unsigned char *) points;
|
|
||||||
|
|
||||||
bmin[0] = points[0];
|
bmin[0] = points[0];
|
||||||
bmin[1] = points[1];
|
bmin[1] = points[1];
|
||||||
@@ -102,25 +96,22 @@ void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,flo
|
|||||||
bmax[1] = points[1];
|
bmax[1] = points[1];
|
||||||
bmax[2] = points[2];
|
bmax[2] = points[2];
|
||||||
|
|
||||||
|
for (unsigned int i = 1; i < vcount; i++)
|
||||||
for (unsigned int i=1; i<vcount; i++)
|
|
||||||
{
|
{
|
||||||
source+=pstride;
|
source += pstride;
|
||||||
const float *p = (const float *) source;
|
const float *p = (const float *)source;
|
||||||
|
|
||||||
if ( p[0] < bmin[0] ) bmin[0] = p[0];
|
if (p[0] < bmin[0]) bmin[0] = p[0];
|
||||||
if ( p[1] < bmin[1] ) bmin[1] = p[1];
|
if (p[1] < bmin[1]) bmin[1] = p[1];
|
||||||
if ( p[2] < bmin[2] ) bmin[2] = p[2];
|
if (p[2] < bmin[2]) bmin[2] = p[2];
|
||||||
|
|
||||||
if ( p[0] > bmax[0] ) bmax[0] = p[0];
|
|
||||||
if ( p[1] > bmax[1] ) bmax[1] = p[1];
|
|
||||||
if ( p[2] > bmax[2] ) bmax[2] = p[2];
|
|
||||||
|
|
||||||
|
if (p[0] > bmax[0]) bmax[0] = p[0];
|
||||||
|
if (p[1] > bmax[1]) bmax[1] = p[1];
|
||||||
|
if (p[2] > bmax[2]) bmax[2] = p[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fm_eulerToQuat(float roll, float pitch, float yaw, float *quat) // convert euler angles to quaternion.
|
||||||
void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat) // convert euler angles to quaternion.
|
|
||||||
{
|
{
|
||||||
roll *= 0.5f;
|
roll *= 0.5f;
|
||||||
pitch *= 0.5f;
|
pitch *= 0.5f;
|
||||||
@@ -139,83 +130,76 @@ void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat) // convert eul
|
|||||||
float spcy = sp * cy;
|
float spcy = sp * cy;
|
||||||
float cpsy = cp * sy;
|
float cpsy = cp * sy;
|
||||||
|
|
||||||
quat[0] = ( sr * cpcy - cr * spsy);
|
quat[0] = (sr * cpcy - cr * spsy);
|
||||||
quat[1] = ( cr * spcy + sr * cpsy);
|
quat[1] = (cr * spcy + sr * cpsy);
|
||||||
quat[2] = ( cr * cpsy - sr * spcy);
|
quat[2] = (cr * cpsy - sr * spcy);
|
||||||
quat[3] = cr * cpcy + sr * spsy;
|
quat[3] = cr * cpcy + sr * spsy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fm_quatToMatrix(const float *quat,float *matrix) // convert quaterinion rotation to matrix, zeros out the translation component.
|
void fm_quatToMatrix(const float *quat, float *matrix) // convert quaterinion rotation to matrix, zeros out the translation component.
|
||||||
{
|
{
|
||||||
|
float xx = quat[0] * quat[0];
|
||||||
|
float yy = quat[1] * quat[1];
|
||||||
|
float zz = quat[2] * quat[2];
|
||||||
|
float xy = quat[0] * quat[1];
|
||||||
|
float xz = quat[0] * quat[2];
|
||||||
|
float yz = quat[1] * quat[2];
|
||||||
|
float wx = quat[3] * quat[0];
|
||||||
|
float wy = quat[3] * quat[1];
|
||||||
|
float wz = quat[3] * quat[2];
|
||||||
|
|
||||||
float xx = quat[0]*quat[0];
|
matrix[0 * 4 + 0] = 1 - 2 * (yy + zz);
|
||||||
float yy = quat[1]*quat[1];
|
matrix[1 * 4 + 0] = 2 * (xy - wz);
|
||||||
float zz = quat[2]*quat[2];
|
matrix[2 * 4 + 0] = 2 * (xz + wy);
|
||||||
float xy = quat[0]*quat[1];
|
|
||||||
float xz = quat[0]*quat[2];
|
|
||||||
float yz = quat[1]*quat[2];
|
|
||||||
float wx = quat[3]*quat[0];
|
|
||||||
float wy = quat[3]*quat[1];
|
|
||||||
float wz = quat[3]*quat[2];
|
|
||||||
|
|
||||||
matrix[0*4+0] = 1 - 2 * ( yy + zz );
|
matrix[0 * 4 + 1] = 2 * (xy + wz);
|
||||||
matrix[1*4+0] = 2 * ( xy - wz );
|
matrix[1 * 4 + 1] = 1 - 2 * (xx + zz);
|
||||||
matrix[2*4+0] = 2 * ( xz + wy );
|
matrix[2 * 4 + 1] = 2 * (yz - wx);
|
||||||
|
|
||||||
matrix[0*4+1] = 2 * ( xy + wz );
|
matrix[0 * 4 + 2] = 2 * (xz - wy);
|
||||||
matrix[1*4+1] = 1 - 2 * ( xx + zz );
|
matrix[1 * 4 + 2] = 2 * (yz + wx);
|
||||||
matrix[2*4+1] = 2 * ( yz - wx );
|
matrix[2 * 4 + 2] = 1 - 2 * (xx + yy);
|
||||||
|
|
||||||
matrix[0*4+2] = 2 * ( xz - wy );
|
|
||||||
matrix[1*4+2] = 2 * ( yz + wx );
|
|
||||||
matrix[2*4+2] = 1 - 2 * ( xx + yy );
|
|
||||||
|
|
||||||
matrix[3*4+0] = matrix[3*4+1] = matrix[3*4+2] = 0.0f;
|
|
||||||
matrix[0*4+3] = matrix[1*4+3] = matrix[2*4+3] = 0.0f;
|
|
||||||
matrix[3*4+3] = 1.0f;
|
|
||||||
|
|
||||||
|
matrix[3 * 4 + 0] = matrix[3 * 4 + 1] = matrix[3 * 4 + 2] = 0.0f;
|
||||||
|
matrix[0 * 4 + 3] = matrix[1 * 4 + 3] = matrix[2 * 4 + 3] = 0.0f;
|
||||||
|
matrix[3 * 4 + 3] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fm_quatRotate(const float *quat, const float *v, float *r) // rotate a vector directly by a quaternion.
|
||||||
void fm_quatRotate(const float *quat,const float *v,float *r) // rotate a vector directly by a quaternion.
|
|
||||||
{
|
{
|
||||||
float left[4];
|
float left[4];
|
||||||
|
|
||||||
left[0] = quat[3]*v[0] + quat[1]*v[2] - v[1]*quat[2];
|
left[0] = quat[3] * v[0] + quat[1] * v[2] - v[1] * quat[2];
|
||||||
left[1] = quat[3]*v[1] + quat[2]*v[0] - v[2]*quat[0];
|
left[1] = quat[3] * v[1] + quat[2] * v[0] - v[2] * quat[0];
|
||||||
left[2] = quat[3]*v[2] + quat[0]*v[1] - v[0]*quat[1];
|
left[2] = quat[3] * v[2] + quat[0] * v[1] - v[0] * quat[1];
|
||||||
left[3] = - quat[0]*v[0] - quat[1]*v[1] - quat[2]*v[2];
|
left[3] = -quat[0] * v[0] - quat[1] * v[1] - quat[2] * v[2];
|
||||||
|
|
||||||
r[0] = (left[3]*-quat[0]) + (quat[3]*left[0]) + (left[1]*-quat[2]) - (-quat[1]*left[2]);
|
|
||||||
r[1] = (left[3]*-quat[1]) + (quat[3]*left[1]) + (left[2]*-quat[0]) - (-quat[2]*left[0]);
|
|
||||||
r[2] = (left[3]*-quat[2]) + (quat[3]*left[2]) + (left[0]*-quat[1]) - (-quat[0]*left[1]);
|
|
||||||
|
|
||||||
|
r[0] = (left[3] * -quat[0]) + (quat[3] * left[0]) + (left[1] * -quat[2]) - (-quat[1] * left[2]);
|
||||||
|
r[1] = (left[3] * -quat[1]) + (quat[3] * left[1]) + (left[2] * -quat[0]) - (-quat[2] * left[0]);
|
||||||
|
r[2] = (left[3] * -quat[2]) + (quat[3] * left[2]) + (left[0] * -quat[1]) - (-quat[0] * left[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fm_getTranslation(const float *matrix, float *t)
|
||||||
void fm_getTranslation(const float *matrix,float *t)
|
|
||||||
{
|
{
|
||||||
t[0] = matrix[3*4+0];
|
t[0] = matrix[3 * 4 + 0];
|
||||||
t[1] = matrix[3*4+1];
|
t[1] = matrix[3 * 4 + 1];
|
||||||
t[2] = matrix[3*4+2];
|
t[2] = matrix[3 * 4 + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void fm_matrixToQuat(const float *matrix,float *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w
|
void fm_matrixToQuat(const float *matrix, float *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w
|
||||||
{
|
{
|
||||||
|
float tr = matrix[0 * 4 + 0] + matrix[1 * 4 + 1] + matrix[2 * 4 + 2];
|
||||||
float tr = matrix[0*4+0] + matrix[1*4+1] + matrix[2*4+2];
|
|
||||||
|
|
||||||
// check the diagonal
|
// check the diagonal
|
||||||
|
|
||||||
if (tr > 0.0f )
|
if (tr > 0.0f)
|
||||||
{
|
{
|
||||||
float s = (float) sqrt ( (double) (tr + 1.0f) );
|
float s = (float)sqrt((double)(tr + 1.0f));
|
||||||
quat[3] = s * 0.5f;
|
quat[3] = s * 0.5f;
|
||||||
s = 0.5f / s;
|
s = 0.5f / s;
|
||||||
quat[0] = (matrix[1*4+2] - matrix[2*4+1]) * s;
|
quat[0] = (matrix[1 * 4 + 2] - matrix[2 * 4 + 1]) * s;
|
||||||
quat[1] = (matrix[2*4+0] - matrix[0*4+2]) * s;
|
quat[1] = (matrix[2 * 4 + 0] - matrix[0 * 4 + 2]) * s;
|
||||||
quat[2] = (matrix[0*4+1] - matrix[1*4+0]) * s;
|
quat[2] = (matrix[0 * 4 + 1] - matrix[1 * 4 + 0]) * s;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -225,33 +209,30 @@ void fm_matrixToQuat(const float *matrix,float *quat) // convert the 3x3 portion
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (matrix[1*4+1] > matrix[0*4+0]) i = 1;
|
if (matrix[1 * 4 + 1] > matrix[0 * 4 + 0]) i = 1;
|
||||||
if (matrix[2*4+2] > matrix[i*4+i]) i = 2;
|
if (matrix[2 * 4 + 2] > matrix[i * 4 + i]) i = 2;
|
||||||
|
|
||||||
int j = nxt[i];
|
int j = nxt[i];
|
||||||
int k = nxt[j];
|
int k = nxt[j];
|
||||||
|
|
||||||
float s = sqrtf ( ((matrix[i*4+i] - (matrix[j*4+j] + matrix[k*4+k])) + 1.0f) );
|
float s = sqrtf(((matrix[i * 4 + i] - (matrix[j * 4 + j] + matrix[k * 4 + k])) + 1.0f));
|
||||||
|
|
||||||
qa[i] = s * 0.5f;
|
qa[i] = s * 0.5f;
|
||||||
|
|
||||||
if (s != 0.0f ) s = 0.5f / s;
|
if (s != 0.0f) s = 0.5f / s;
|
||||||
|
|
||||||
qa[3] = (matrix[j*4+k] - matrix[k*4+j]) * s;
|
qa[3] = (matrix[j * 4 + k] - matrix[k * 4 + j]) * s;
|
||||||
qa[j] = (matrix[i*4+j] + matrix[j*4+i]) * s;
|
qa[j] = (matrix[i * 4 + j] + matrix[j * 4 + i]) * s;
|
||||||
qa[k] = (matrix[i*4+k] + matrix[k*4+i]) * s;
|
qa[k] = (matrix[i * 4 + k] + matrix[k * 4 + i]) * s;
|
||||||
|
|
||||||
quat[0] = qa[0];
|
quat[0] = qa[0];
|
||||||
quat[1] = qa[1];
|
quat[1] = qa[1];
|
||||||
quat[2] = qa[2];
|
quat[2] = qa[2];
|
||||||
quat[3] = qa[3];
|
quat[3] = qa[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float fm_sphereVolume(float radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed )
|
float fm_sphereVolume(float radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed )
|
||||||
{
|
{
|
||||||
return (4.0f / 3.0f ) * FM_PI * radius * radius * radius;
|
return (4.0f / 3.0f) * FM_PI * radius * radius * radius;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
#define FLOAT_MATH_H
|
#define FLOAT_MATH_H
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning(disable : 4324) // disable padding warning
|
#pragma warning(disable : 4324) // disable padding warning
|
||||||
#pragma warning(disable : 4244) // disable padding warning
|
#pragma warning(disable : 4244) // disable padding warning
|
||||||
#pragma warning(disable : 4267) // possible loss of data
|
#pragma warning(disable : 4267) // possible loss of data
|
||||||
#pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
|
#pragma warning(disable : 4530) // Disable the exception disable but used in MSCV Stl warning.
|
||||||
#pragma warning(disable:4996) //Turn off warnings about deprecated C routines
|
#pragma warning(disable : 4996) //Turn off warnings about deprecated C routines
|
||||||
#pragma warning(disable:4786) // Disable the "debug name too long" warning
|
#pragma warning(disable : 4786) // Disable the "debug name too long" warning
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
@@ -45,7 +45,6 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
// a set of routines that last you do common 3d math
|
// a set of routines that last you do common 3d math
|
||||||
// operations without any vector, matrix, or quaternion
|
// operations without any vector, matrix, or quaternion
|
||||||
// classes or templates.
|
// classes or templates.
|
||||||
@@ -59,14 +58,14 @@ const float FM_DEG_TO_RAD = ((2.0f * FM_PI) / 360.0f);
|
|||||||
const float FM_RAD_TO_DEG = (360.0f / (2.0f * FM_PI));
|
const float FM_RAD_TO_DEG = (360.0f / (2.0f * FM_PI));
|
||||||
|
|
||||||
void fm_identity(float *matrix); // set 4x4 matrix to identity.
|
void fm_identity(float *matrix); // set 4x4 matrix to identity.
|
||||||
void fm_inverseRT(const float *matrix,const float *pos,float *t); // inverse rotate translate the point.
|
void fm_inverseRT(const float *matrix, const float *pos, float *t); // inverse rotate translate the point.
|
||||||
void fm_eulerMatrix(float ax,float ay,float az,float *matrix); // convert euler (in radians) to a dest 4x4 matrix (translation set to zero)
|
void fm_eulerMatrix(float ax, float ay, float az, float *matrix); // convert euler (in radians) to a dest 4x4 matrix (translation set to zero)
|
||||||
void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax);
|
void fm_getAABB(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax);
|
||||||
void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat); // convert euler angles to quaternion.
|
void fm_eulerToQuat(float roll, float pitch, float yaw, float *quat); // convert euler angles to quaternion.
|
||||||
void fm_quatToMatrix(const float *quat,float *matrix); // convert quaterinion rotation to matrix, translation set to zero.
|
void fm_quatToMatrix(const float *quat, float *matrix); // convert quaterinion rotation to matrix, translation set to zero.
|
||||||
void fm_quatRotate(const float *quat,const float *v,float *r); // rotate a vector directly by a quaternion.
|
void fm_quatRotate(const float *quat, const float *v, float *r); // rotate a vector directly by a quaternion.
|
||||||
void fm_getTranslation(const float *matrix,float *t);
|
void fm_getTranslation(const float *matrix, float *t);
|
||||||
void fm_matrixToQuat(const float *matrix,float *quat); // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w
|
void fm_matrixToQuat(const float *matrix, float *quat); // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w
|
||||||
float fm_sphereVolume(float radius); // return's the volume of a sphere of this radius (4/3 PI * R cubed )
|
float fm_sphereVolume(float radius); // return's the volume of a sphere of this radius (4/3 PI * R cubed )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -35,45 +35,43 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
inline float det(const float *p1,const float *p2,const float *p3)
|
inline float det(const float *p1, const float *p2, const float *p3)
|
||||||
{
|
{
|
||||||
return p1[0]*p2[1]*p3[2] + p2[0]*p3[1]*p1[2] + p3[0]*p1[1]*p2[2] -p1[0]*p3[1]*p2[2] - p2[0]*p1[1]*p3[2] - p3[0]*p2[1]*p1[2];
|
return p1[0] * p2[1] * p3[2] + p2[0] * p3[1] * p1[2] + p3[0] * p1[1] * p2[2] - p1[0] * p3[1] * p2[2] - p2[0] * p1[1] * p3[2] - p3[0] * p2[1] * p1[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float computeMeshVolume(const float *vertices,unsigned int tcount,const unsigned int *indices)
|
float computeMeshVolume(const float *vertices, unsigned int tcount, const unsigned int *indices)
|
||||||
{
|
{
|
||||||
float volume = 0;
|
float volume = 0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<tcount; i++,indices+=3)
|
for (unsigned int i = 0; i < tcount; i++, indices += 3)
|
||||||
{
|
{
|
||||||
|
const float *p1 = &vertices[indices[0] * 3];
|
||||||
|
const float *p2 = &vertices[indices[1] * 3];
|
||||||
|
const float *p3 = &vertices[indices[2] * 3];
|
||||||
|
|
||||||
const float *p1 = &vertices[ indices[0]*3 ];
|
volume += det(p1, p2, p3); // compute the volume of the tetrahedran relative to the origin.
|
||||||
const float *p2 = &vertices[ indices[1]*3 ];
|
|
||||||
const float *p3 = &vertices[ indices[2]*3 ];
|
|
||||||
|
|
||||||
volume+=det(p1,p2,p3); // compute the volume of the tetrahedran relative to the origin.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
volume*=(1.0f/6.0f);
|
volume *= (1.0f / 6.0f);
|
||||||
if ( volume < 0 )
|
if (volume < 0)
|
||||||
volume*=-1;
|
volume *= -1;
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CrossProduct(const float *a, const float *b, float *cross)
|
||||||
inline void CrossProduct(const float *a,const float *b,float *cross)
|
|
||||||
{
|
{
|
||||||
cross[0] = a[1]*b[2] - a[2]*b[1];
|
cross[0] = a[1] * b[2] - a[2] * b[1];
|
||||||
cross[1] = a[2]*b[0] - a[0]*b[2];
|
cross[1] = a[2] * b[0] - a[0] * b[2];
|
||||||
cross[2] = a[0]*b[1] - a[1]*b[0];
|
cross[2] = a[0] * b[1] - a[1] * b[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float DotProduct(const float *a,const float *b)
|
inline float DotProduct(const float *a, const float *b)
|
||||||
{
|
{
|
||||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float tetVolume(const float *p0,const float *p1,const float *p2,const float *p3)
|
inline float tetVolume(const float *p0, const float *p1, const float *p2, const float *p3)
|
||||||
{
|
{
|
||||||
float a[3];
|
float a[3];
|
||||||
float b[3];
|
float b[3];
|
||||||
@@ -93,36 +91,34 @@ inline float tetVolume(const float *p0,const float *p1,const float *p2,const flo
|
|||||||
|
|
||||||
float cross[3];
|
float cross[3];
|
||||||
|
|
||||||
CrossProduct( b, c, cross );
|
CrossProduct(b, c, cross);
|
||||||
|
|
||||||
float volume = DotProduct( a, cross );
|
float volume = DotProduct(a, cross);
|
||||||
|
|
||||||
if ( volume < 0 )
|
if (volume < 0)
|
||||||
return -volume;
|
return -volume;
|
||||||
|
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float det(const float *p0,const float *p1,const float *p2,const float *p3)
|
inline float det(const float *p0, const float *p1, const float *p2, const float *p3)
|
||||||
{
|
{
|
||||||
return p1[0]*p2[1]*p3[2] + p2[0]*p3[1]*p1[2] + p3[0]*p1[1]*p2[2] -p1[0]*p3[1]*p2[2] - p2[0]*p1[1]*p3[2] - p3[0]*p2[1]*p1[2];
|
return p1[0] * p2[1] * p3[2] + p2[0] * p3[1] * p1[2] + p3[0] * p1[1] * p2[2] - p1[0] * p3[1] * p2[2] - p2[0] * p1[1] * p3[2] - p3[0] * p2[1] * p1[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float computeMeshVolume2(const float *vertices,unsigned int tcount,const unsigned int *indices)
|
float computeMeshVolume2(const float *vertices, unsigned int tcount, const unsigned int *indices)
|
||||||
{
|
{
|
||||||
float volume = 0;
|
float volume = 0;
|
||||||
|
|
||||||
const float *p0 = vertices;
|
const float *p0 = vertices;
|
||||||
for (unsigned int i=0; i<tcount; i++,indices+=3)
|
for (unsigned int i = 0; i < tcount; i++, indices += 3)
|
||||||
{
|
{
|
||||||
|
const float *p1 = &vertices[indices[0] * 3];
|
||||||
|
const float *p2 = &vertices[indices[1] * 3];
|
||||||
|
const float *p3 = &vertices[indices[2] * 3];
|
||||||
|
|
||||||
const float *p1 = &vertices[ indices[0]*3 ];
|
volume += tetVolume(p0, p1, p2, p3); // compute the volume of the tetrahdren relative to the root vertice
|
||||||
const float *p2 = &vertices[ indices[1]*3 ];
|
|
||||||
const float *p3 = &vertices[ indices[2]*3 ];
|
|
||||||
|
|
||||||
volume+=tetVolume(p0,p1,p2,p3); // compute the volume of the tetrahdren relative to the root vertice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return volume * (1.0f / 6.0f );
|
return volume * (1.0f / 6.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,7 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
float computeMeshVolume(const float *vertices, unsigned int tcount, const unsigned int *indices);
|
||||||
|
float computeMeshVolume2(const float *vertices, unsigned int tcount, const unsigned int *indices);
|
||||||
float computeMeshVolume(const float *vertices,unsigned int tcount,const unsigned int *indices);
|
|
||||||
float computeMeshVolume2(const float *vertices,unsigned int tcount,const unsigned int *indices);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,45 +40,41 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
static inline float DistToPt(const float *p,const float *plane)
|
static inline float DistToPt(const float *p, const float *plane)
|
||||||
{
|
{
|
||||||
float x = p[0];
|
float x = p[0];
|
||||||
float y = p[1];
|
float y = p[1];
|
||||||
float z = p[2];
|
float z = p[2];
|
||||||
float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
|
float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3];
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PlaneTriResult getSidePlane(const float *p, const float *plane, float epsilon)
|
||||||
static PlaneTriResult getSidePlane(const float *p,const float *plane,float epsilon)
|
|
||||||
{
|
{
|
||||||
|
float d = DistToPt(p, plane);
|
||||||
|
|
||||||
float d = DistToPt(p,plane);
|
if ((d + epsilon) > 0)
|
||||||
|
|
||||||
if ( (d+epsilon) > 0 )
|
|
||||||
return PTR_FRONT; // it is 'in front' within the provided epsilon value.
|
return PTR_FRONT; // it is 'in front' within the provided epsilon value.
|
||||||
|
|
||||||
return PTR_BACK;
|
return PTR_BACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add(const float *p,float *dest,unsigned int tstride,unsigned int &pcount)
|
static void add(const float *p, float *dest, unsigned int tstride, unsigned int &pcount)
|
||||||
{
|
{
|
||||||
char *d = (char *) dest;
|
char *d = (char *)dest;
|
||||||
d = d + pcount*tstride;
|
d = d + pcount * tstride;
|
||||||
dest = (float *) d;
|
dest = (float *)d;
|
||||||
dest[0] = p[0];
|
dest[0] = p[0];
|
||||||
dest[1] = p[1];
|
dest[1] = p[1];
|
||||||
dest[2] = p[2];
|
dest[2] = p[2];
|
||||||
pcount++;
|
pcount++;
|
||||||
assert( pcount <= 4 );
|
assert(pcount <= 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// assumes that the points are on opposite sides of the plane!
|
// assumes that the points are on opposite sides of the plane!
|
||||||
static void intersect(const float *p1,const float *p2,float *split,const float *plane)
|
static void intersect(const float *p1, const float *p2, float *split, const float *plane)
|
||||||
{
|
{
|
||||||
|
float dp1 = DistToPt(p1, plane);
|
||||||
float dp1 = DistToPt(p1,plane);
|
|
||||||
|
|
||||||
float dir[3];
|
float dir[3];
|
||||||
|
|
||||||
@@ -86,15 +82,14 @@ static void intersect(const float *p1,const float *p2,float *split,const float *
|
|||||||
dir[1] = p2[1] - p1[1];
|
dir[1] = p2[1] - p1[1];
|
||||||
dir[2] = p2[2] - p1[2];
|
dir[2] = p2[2] - p1[2];
|
||||||
|
|
||||||
float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
|
float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2];
|
||||||
float dot2 = dp1 - plane[3];
|
float dot2 = dp1 - plane[3];
|
||||||
|
|
||||||
float t = -(plane[3] + dot2 ) / dot1;
|
float t = -(plane[3] + dot2) / dot1;
|
||||||
|
|
||||||
split[0] = (dir[0]*t)+p1[0];
|
|
||||||
split[1] = (dir[1]*t)+p1[1];
|
|
||||||
split[2] = (dir[2]*t)+p1[2];
|
|
||||||
|
|
||||||
|
split[0] = (dir[0] * t) + p1[0];
|
||||||
|
split[1] = (dir[1] * t) + p1[1];
|
||||||
|
split[2] = (dir[2] * t) + p1[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format
|
PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format
|
||||||
@@ -109,31 +104,30 @@ PlaneTriResult planeTriIntersection(const float *plane, // the plane equation
|
|||||||
fcount = 0;
|
fcount = 0;
|
||||||
bcount = 0;
|
bcount = 0;
|
||||||
|
|
||||||
const char *tsource = (const char *) triangle;
|
const char *tsource = (const char *)triangle;
|
||||||
|
|
||||||
// get the three vertices of the triangle.
|
// get the three vertices of the triangle.
|
||||||
const float *p1 = (const float *) (tsource);
|
const float *p1 = (const float *)(tsource);
|
||||||
const float *p2 = (const float *) (tsource+tstride);
|
const float *p2 = (const float *)(tsource + tstride);
|
||||||
const float *p3 = (const float *) (tsource+tstride*2);
|
const float *p3 = (const float *)(tsource + tstride * 2);
|
||||||
|
|
||||||
|
PlaneTriResult r1 = getSidePlane(p1, plane, epsilon); // compute the side of the plane each vertex is on
|
||||||
|
PlaneTriResult r2 = getSidePlane(p2, plane, epsilon);
|
||||||
|
PlaneTriResult r3 = getSidePlane(p3, plane, epsilon);
|
||||||
|
|
||||||
PlaneTriResult r1 = getSidePlane(p1,plane,epsilon); // compute the side of the plane each vertex is on
|
if (r1 == r2 && r1 == r3) // if all three vertices are on the same side of the plane.
|
||||||
PlaneTriResult r2 = getSidePlane(p2,plane,epsilon);
|
|
||||||
PlaneTriResult r3 = getSidePlane(p3,plane,epsilon);
|
|
||||||
|
|
||||||
if ( r1 == r2 && r1 == r3 ) // if all three vertices are on the same side of the plane.
|
|
||||||
{
|
{
|
||||||
if ( r1 == PTR_FRONT ) // if all three are in front of the plane, then copy to the 'front' output triangle.
|
if (r1 == PTR_FRONT) // if all three are in front of the plane, then copy to the 'front' output triangle.
|
||||||
{
|
{
|
||||||
add(p1,front,tstride,fcount);
|
add(p1, front, tstride, fcount);
|
||||||
add(p2,front,tstride,fcount);
|
add(p2, front, tstride, fcount);
|
||||||
add(p3,front,tstride,fcount);
|
add(p3, front, tstride, fcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add(p1,back,tstride,bcount); // if all three are in 'abck' then copy to the 'back' output triangle.
|
add(p1, back, tstride, bcount); // if all three are in 'abck' then copy to the 'back' output triangle.
|
||||||
add(p2,back,tstride,bcount);
|
add(p2, back, tstride, bcount);
|
||||||
add(p3,back,tstride,bcount);
|
add(p3, back, tstride, bcount);
|
||||||
}
|
}
|
||||||
return r1; // if all three points are on the same side of the plane return result
|
return r1; // if all three points are on the same side of the plane return result
|
||||||
}
|
}
|
||||||
@@ -141,98 +135,93 @@ PlaneTriResult planeTriIntersection(const float *plane, // the plane equation
|
|||||||
// ok.. we need to split the triangle at the plane.
|
// ok.. we need to split the triangle at the plane.
|
||||||
|
|
||||||
// First test ray segment P1 to P2
|
// First test ray segment P1 to P2
|
||||||
if ( r1 == r2 ) // if these are both on the same side...
|
if (r1 == r2) // if these are both on the same side...
|
||||||
{
|
{
|
||||||
if ( r1 == PTR_FRONT )
|
if (r1 == PTR_FRONT)
|
||||||
{
|
{
|
||||||
add( p1, front, tstride, fcount );
|
add(p1, front, tstride, fcount);
|
||||||
add( p2, front, tstride, fcount );
|
add(p2, front, tstride, fcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add( p1, back, tstride, bcount );
|
add(p1, back, tstride, bcount);
|
||||||
add( p2, back, tstride, bcount );
|
add(p2, back, tstride, bcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float split[3]; // split the point
|
float split[3]; // split the point
|
||||||
intersect(p1,p2,split,plane);
|
intersect(p1, p2, split, plane);
|
||||||
|
|
||||||
if ( r1 == PTR_FRONT )
|
if (r1 == PTR_FRONT)
|
||||||
{
|
{
|
||||||
|
add(p1, front, tstride, fcount);
|
||||||
|
add(split, front, tstride, fcount);
|
||||||
|
|
||||||
add(p1, front, tstride, fcount );
|
add(split, back, tstride, bcount);
|
||||||
add(split, front, tstride, fcount );
|
add(p2, back, tstride, bcount);
|
||||||
|
|
||||||
add(split, back, tstride, bcount );
|
|
||||||
add(p2, back, tstride, bcount );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add(p1, back, tstride, bcount );
|
add(p1, back, tstride, bcount);
|
||||||
add(split, back, tstride, bcount );
|
add(split, back, tstride, bcount);
|
||||||
|
|
||||||
add(split, front, tstride, fcount );
|
add(split, front, tstride, fcount);
|
||||||
add(p2, front, tstride, fcount );
|
add(p2, front, tstride, fcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next test ray segment P2 to P3
|
// Next test ray segment P2 to P3
|
||||||
if ( r2 == r3 ) // if these are both on the same side...
|
if (r2 == r3) // if these are both on the same side...
|
||||||
{
|
{
|
||||||
if ( r3 == PTR_FRONT )
|
if (r3 == PTR_FRONT)
|
||||||
{
|
{
|
||||||
add( p3, front, tstride, fcount );
|
add(p3, front, tstride, fcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add( p3, back, tstride, bcount );
|
add(p3, back, tstride, bcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float split[3]; // split the point
|
float split[3]; // split the point
|
||||||
intersect(p2,p3,split,plane);
|
intersect(p2, p3, split, plane);
|
||||||
|
|
||||||
if ( r3 == PTR_FRONT )
|
if (r3 == PTR_FRONT)
|
||||||
{
|
{
|
||||||
add(split, front, tstride, fcount );
|
add(split, front, tstride, fcount);
|
||||||
add(split, back, tstride, bcount );
|
add(split, back, tstride, bcount);
|
||||||
|
|
||||||
add(p3, front, tstride, fcount );
|
add(p3, front, tstride, fcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add(split, front, tstride, fcount );
|
add(split, front, tstride, fcount);
|
||||||
add(split, back, tstride, bcount );
|
add(split, back, tstride, bcount);
|
||||||
|
|
||||||
add(p3, back, tstride, bcount );
|
add(p3, back, tstride, bcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next test ray segment P3 to P1
|
// Next test ray segment P3 to P1
|
||||||
if ( r3 != r1 ) // if these are both on the same side...
|
if (r3 != r1) // if these are both on the same side...
|
||||||
{
|
{
|
||||||
float split[3]; // split the point
|
float split[3]; // split the point
|
||||||
|
|
||||||
intersect(p3,p1,split,plane);
|
intersect(p3, p1, split, plane);
|
||||||
|
|
||||||
if ( r1 == PTR_FRONT )
|
if (r1 == PTR_FRONT)
|
||||||
{
|
{
|
||||||
add(split, front, tstride, fcount );
|
add(split, front, tstride, fcount);
|
||||||
add(split, back, tstride, bcount );
|
add(split, back, tstride, bcount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add(split, front, tstride, fcount );
|
add(split, front, tstride, fcount);
|
||||||
add(split, back, tstride, bcount );
|
add(split, back, tstride, bcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return PTR_SPLIT;
|
return PTR_SPLIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum PlaneTriResult
|
enum PlaneTriResult
|
||||||
{
|
{
|
||||||
PTR_FRONT,
|
PTR_FRONT,
|
||||||
@@ -54,5 +52,4 @@ PlaneTriResult planeTriIntersection(const float *plane, // the plane equation
|
|||||||
float *back, // the triangle in back of the plane
|
float *back, // the triangle in back of the plane
|
||||||
unsigned int &bcount); // the number of vertices in the 'back' triangle.
|
unsigned int &bcount); // the number of vertices in the 'back' triangle.
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -41,62 +41,57 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
/* a = b - c */
|
/* a = b - c */
|
||||||
#define vector(a,b,c) \
|
#define vector(a, b, c) \
|
||||||
(a)[0] = (b)[0] - (c)[0]; \
|
(a)[0] = (b)[0] - (c)[0]; \
|
||||||
(a)[1] = (b)[1] - (c)[1]; \
|
(a)[1] = (b)[1] - (c)[1]; \
|
||||||
(a)[2] = (b)[2] - (c)[2];
|
(a)[2] = (b)[2] - (c)[2];
|
||||||
|
|
||||||
|
#define innerProduct(v, q) \
|
||||||
|
|
||||||
#define innerProduct(v,q) \
|
|
||||||
((v)[0] * (q)[0] + \
|
((v)[0] * (q)[0] + \
|
||||||
(v)[1] * (q)[1] + \
|
(v)[1] * (q)[1] + \
|
||||||
(v)[2] * (q)[2])
|
(v)[2] * (q)[2])
|
||||||
|
|
||||||
#define crossProduct(a,b,c) \
|
#define crossProduct(a, b, c) \
|
||||||
(a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \
|
(a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \
|
||||||
(a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \
|
(a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \
|
||||||
(a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1];
|
(a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1];
|
||||||
|
|
||||||
bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t)
|
bool rayIntersectsTriangle(const float *p, const float *d, const float *v0, const float *v1, const float *v2, float &t)
|
||||||
{
|
{
|
||||||
|
float e1[3], e2[3], h[3], s[3], q[3];
|
||||||
|
float a, f, u, v;
|
||||||
|
|
||||||
float e1[3],e2[3],h[3],s[3],q[3];
|
vector(e1, v1, v0);
|
||||||
float a,f,u,v;
|
vector(e2, v2, v0);
|
||||||
|
crossProduct(h, d, e2);
|
||||||
vector(e1,v1,v0);
|
a = innerProduct(e1, h);
|
||||||
vector(e2,v2,v0);
|
|
||||||
crossProduct(h,d,e2);
|
|
||||||
a = innerProduct(e1,h);
|
|
||||||
|
|
||||||
if (a > -0.00001 && a < 0.00001)
|
if (a > -0.00001 && a < 0.00001)
|
||||||
return(false);
|
return (false);
|
||||||
|
|
||||||
f = 1/a;
|
f = 1 / a;
|
||||||
vector(s,p,v0);
|
vector(s, p, v0);
|
||||||
u = f * (innerProduct(s,h));
|
u = f * (innerProduct(s, h));
|
||||||
|
|
||||||
if (u < 0.0 || u > 1.0)
|
if (u < 0.0 || u > 1.0)
|
||||||
return(false);
|
return (false);
|
||||||
|
|
||||||
crossProduct(q,s,e1);
|
crossProduct(q, s, e1);
|
||||||
v = f * innerProduct(d,q);
|
v = f * innerProduct(d, q);
|
||||||
if (v < 0.0 || u + v > 1.0)
|
if (v < 0.0 || u + v > 1.0)
|
||||||
return(false);
|
return (false);
|
||||||
// at this stage we can compute t to find out where
|
// at this stage we can compute t to find out where
|
||||||
// the intersection point is on the line
|
// the intersection point is on the line
|
||||||
t = f * innerProduct(e2,q);
|
t = f * innerProduct(e2, q);
|
||||||
if (t > 0) // ray intersection
|
if (t > 0) // ray intersection
|
||||||
return(true);
|
return (true);
|
||||||
else // this means that there is a line intersection
|
else // this means that there is a line intersection
|
||||||
// but not a ray intersection
|
// but not a ray intersection
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lineIntersectsTriangle(const float *rayStart, const float *rayEnd, const float *p1, const float *p2, const float *p3, float *sect)
|
||||||
bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect)
|
|
||||||
{
|
{
|
||||||
float dir[3];
|
float dir[3];
|
||||||
|
|
||||||
@@ -104,25 +99,24 @@ bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const floa
|
|||||||
dir[1] = rayEnd[1] - rayStart[1];
|
dir[1] = rayEnd[1] - rayStart[1];
|
||||||
dir[2] = rayEnd[2] - rayStart[2];
|
dir[2] = rayEnd[2] - rayStart[2];
|
||||||
|
|
||||||
float d = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
|
float d = sqrtf(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]);
|
||||||
float r = 1.0f / d;
|
float r = 1.0f / d;
|
||||||
|
|
||||||
dir[0]*=r;
|
dir[0] *= r;
|
||||||
dir[1]*=r;
|
dir[1] *= r;
|
||||||
dir[2]*=r;
|
dir[2] *= r;
|
||||||
|
|
||||||
|
|
||||||
float t;
|
float t;
|
||||||
|
|
||||||
bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t );
|
bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t);
|
||||||
|
|
||||||
if ( ret )
|
if (ret)
|
||||||
{
|
{
|
||||||
if ( t > d )
|
if (t > d)
|
||||||
{
|
{
|
||||||
sect[0] = rayStart[0] + dir[0]*t;
|
sect[0] = rayStart[0] + dir[0] * t;
|
||||||
sect[1] = rayStart[1] + dir[1]*t;
|
sect[1] = rayStart[1] + dir[1] * t;
|
||||||
sect[2] = rayStart[2] + dir[2]*t;
|
sect[2] = rayStart[2] + dir[2] * t;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,10 +36,8 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// returns true if the ray intersects the triangle.
|
// returns true if the ray intersects the triangle.
|
||||||
bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect);
|
bool lineIntersectsTriangle(const float *rayStart, const float *rayEnd, const float *p1, const float *p2, const float *p3, float *sect);
|
||||||
bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t);
|
bool rayIntersectsTriangle(const float *p, const float *d, const float *v0, const float *v1, const float *v2, float &t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -53,10 +52,8 @@
|
|||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
static void computePlane(const float *A, const float *B, const float *C, float *plane)
|
||||||
static void computePlane(const float *A,const float *B,const float *C,float *plane)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
float vx = (B[0] - C[0]);
|
float vx = (B[0] - C[0]);
|
||||||
float vy = (B[1] - C[1]);
|
float vy = (B[1] - C[1]);
|
||||||
float vz = (B[2] - C[2]);
|
float vz = (B[2] - C[2]);
|
||||||
@@ -71,37 +68,34 @@ static void computePlane(const float *A,const float *B,const float *C,float *pla
|
|||||||
|
|
||||||
float mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
|
float mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
|
||||||
|
|
||||||
if ( mag < 0.000001f )
|
if (mag < 0.000001f)
|
||||||
{
|
{
|
||||||
mag = 0;
|
mag = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mag = 1.0f/mag;
|
mag = 1.0f / mag;
|
||||||
}
|
}
|
||||||
|
|
||||||
float x = vw_x * mag;
|
float x = vw_x * mag;
|
||||||
float y = vw_y * mag;
|
float y = vw_y * mag;
|
||||||
float z = vw_z * mag;
|
float z = vw_z * mag;
|
||||||
|
|
||||||
|
float D = 0.0f - ((x * A[0]) + (y * A[1]) + (z * A[2]));
|
||||||
float D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2]));
|
|
||||||
|
|
||||||
plane[0] = x;
|
plane[0] = x;
|
||||||
plane[1] = y;
|
plane[1] = y;
|
||||||
plane[2] = z;
|
plane[2] = z;
|
||||||
plane[3] = D;
|
plane[3] = D;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Rect3d
|
class Rect3d
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Rect3d(void) { };
|
Rect3d(void){};
|
||||||
|
|
||||||
Rect3d(const float *bmin,const float *bmax)
|
Rect3d(const float *bmin, const float *bmax)
|
||||||
{
|
{
|
||||||
|
|
||||||
mMin[0] = bmin[0];
|
mMin[0] = bmin[0];
|
||||||
mMin[1] = bmin[1];
|
mMin[1] = bmin[1];
|
||||||
mMin[2] = bmin[2];
|
mMin[2] = bmin[2];
|
||||||
@@ -109,7 +103,6 @@ public:
|
|||||||
mMax[0] = bmax[0];
|
mMax[0] = bmax[0];
|
||||||
mMax[1] = bmax[1];
|
mMax[1] = bmax[1];
|
||||||
mMax[2] = bmax[2];
|
mMax[2] = bmax[2];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMin(const float *bmin)
|
void SetMin(const float *bmin)
|
||||||
@@ -126,14 +119,14 @@ public:
|
|||||||
mMax[2] = bmax[2];
|
mMax[2] = bmax[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMin(float x,float y,float z)
|
void SetMin(float x, float y, float z)
|
||||||
{
|
{
|
||||||
mMin[0] = x;
|
mMin[0] = x;
|
||||||
mMin[1] = y;
|
mMin[1] = y;
|
||||||
mMin[2] = z;
|
mMin[2] = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMax(float x,float y,float z)
|
void SetMax(float x, float y, float z)
|
||||||
{
|
{
|
||||||
mMax[0] = x;
|
mMax[0] = x;
|
||||||
mMax[1] = y;
|
mMax[1] = y;
|
||||||
@@ -150,29 +143,29 @@ void splitRect(unsigned int axis,
|
|||||||
Rect3d &b2,
|
Rect3d &b2,
|
||||||
const float *midpoint)
|
const float *midpoint)
|
||||||
{
|
{
|
||||||
switch ( axis )
|
switch (axis)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
b1.SetMin(source.mMin);
|
b1.SetMin(source.mMin);
|
||||||
b1.SetMax( midpoint[0], source.mMax[1], source.mMax[2] );
|
b1.SetMax(midpoint[0], source.mMax[1], source.mMax[2]);
|
||||||
|
|
||||||
b2.SetMin( midpoint[0], source.mMin[1], source.mMin[2] );
|
b2.SetMin(midpoint[0], source.mMin[1], source.mMin[2]);
|
||||||
b2.SetMax(source.mMax);
|
b2.SetMax(source.mMax);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
b1.SetMin(source.mMin);
|
b1.SetMin(source.mMin);
|
||||||
b1.SetMax( source.mMax[0], midpoint[1], source.mMax[2] );
|
b1.SetMax(source.mMax[0], midpoint[1], source.mMax[2]);
|
||||||
|
|
||||||
b2.SetMin( source.mMin[0], midpoint[1], source.mMin[2] );
|
b2.SetMin(source.mMin[0], midpoint[1], source.mMin[2]);
|
||||||
b2.SetMax(source.mMax);
|
b2.SetMax(source.mMax);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
b1.SetMin(source.mMin);
|
b1.SetMin(source.mMin);
|
||||||
b1.SetMax( source.mMax[0], source.mMax[1], midpoint[2] );
|
b1.SetMax(source.mMax[0], source.mMax[1], midpoint[2]);
|
||||||
|
|
||||||
b2.SetMin( source.mMin[0], source.mMin[1], midpoint[2] );
|
b2.SetMin(source.mMin[0], source.mMin[1], midpoint[2]);
|
||||||
b2.SetMax(source.mMax);
|
b2.SetMax(source.mMax);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -186,39 +179,37 @@ bool computeSplitPlane(unsigned int vcount,
|
|||||||
ConvexDecompInterface *callback,
|
ConvexDecompInterface *callback,
|
||||||
float *plane)
|
float *plane)
|
||||||
{
|
{
|
||||||
float bmin[3] = { 1e9, 1e9, 1e9 };
|
float bmin[3] = {1e9, 1e9, 1e9};
|
||||||
float bmax[3] = { -1e9, -1e9, -1e9 };
|
float bmax[3] = {-1e9, -1e9, -1e9};
|
||||||
|
|
||||||
for (unsigned int i=0; i<vcount; i++)
|
for (unsigned int i = 0; i < vcount; i++)
|
||||||
{
|
{
|
||||||
const float *p = &vertices[i*3];
|
const float *p = &vertices[i * 3];
|
||||||
|
|
||||||
if ( p[0] < bmin[0] ) bmin[0] = p[0];
|
if (p[0] < bmin[0]) bmin[0] = p[0];
|
||||||
if ( p[1] < bmin[1] ) bmin[1] = p[1];
|
if (p[1] < bmin[1]) bmin[1] = p[1];
|
||||||
if ( p[2] < bmin[2] ) bmin[2] = p[2];
|
if (p[2] < bmin[2]) bmin[2] = p[2];
|
||||||
|
|
||||||
if ( p[0] > bmax[0] ) bmax[0] = p[0];
|
|
||||||
if ( p[1] > bmax[1] ) bmax[1] = p[1];
|
|
||||||
if ( p[2] > bmax[2] ) bmax[2] = p[2];
|
|
||||||
|
|
||||||
|
if (p[0] > bmax[0]) bmax[0] = p[0];
|
||||||
|
if (p[1] > bmax[1]) bmax[1] = p[1];
|
||||||
|
if (p[2] > bmax[2]) bmax[2] = p[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float dx = bmax[0] - bmin[0];
|
float dx = bmax[0] - bmin[0];
|
||||||
float dy = bmax[1] - bmin[1];
|
float dy = bmax[1] - bmin[1];
|
||||||
float dz = bmax[2] - bmin[2];
|
float dz = bmax[2] - bmin[2];
|
||||||
|
|
||||||
|
|
||||||
float laxis = dx;
|
float laxis = dx;
|
||||||
|
|
||||||
unsigned int axis = 0;
|
unsigned int axis = 0;
|
||||||
|
|
||||||
if ( dy > dx )
|
if (dy > dx)
|
||||||
{
|
{
|
||||||
axis = 1;
|
axis = 1;
|
||||||
laxis = dy;
|
laxis = dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dz > dx && dz > dy )
|
if (dz > dx && dz > dy)
|
||||||
{
|
{
|
||||||
axis = 2;
|
axis = 2;
|
||||||
laxis = dz;
|
laxis = dz;
|
||||||
@@ -228,27 +219,26 @@ bool computeSplitPlane(unsigned int vcount,
|
|||||||
float p2[3];
|
float p2[3];
|
||||||
float p3[3];
|
float p3[3];
|
||||||
|
|
||||||
p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f;
|
p3[0] = p2[0] = p1[0] = bmin[0] + dx * 0.5f;
|
||||||
p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f;
|
p3[1] = p2[1] = p1[1] = bmin[1] + dy * 0.5f;
|
||||||
p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f;
|
p3[2] = p2[2] = p1[2] = bmin[2] + dz * 0.5f;
|
||||||
|
|
||||||
Rect3d b(bmin,bmax);
|
Rect3d b(bmin, bmax);
|
||||||
|
|
||||||
Rect3d b1,b2;
|
Rect3d b1, b2;
|
||||||
|
|
||||||
splitRect(axis,b,b1,b2,p1);
|
splitRect(axis, b, b1, b2, p1);
|
||||||
|
|
||||||
|
// callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00);
|
||||||
|
// callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00);
|
||||||
|
|
||||||
// callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00);
|
switch (axis)
|
||||||
// callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00);
|
|
||||||
|
|
||||||
switch ( axis )
|
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
p2[1] = bmin[1];
|
p2[1] = bmin[1];
|
||||||
p2[2] = bmin[2];
|
p2[2] = bmin[2];
|
||||||
|
|
||||||
if ( dz > dy )
|
if (dz > dy)
|
||||||
{
|
{
|
||||||
p3[1] = bmax[1];
|
p3[1] = bmax[1];
|
||||||
p3[2] = bmin[2];
|
p3[2] = bmin[2];
|
||||||
@@ -264,7 +254,7 @@ bool computeSplitPlane(unsigned int vcount,
|
|||||||
p2[0] = bmin[0];
|
p2[0] = bmin[0];
|
||||||
p2[2] = bmin[2];
|
p2[2] = bmin[2];
|
||||||
|
|
||||||
if ( dx > dz )
|
if (dx > dz)
|
||||||
{
|
{
|
||||||
p3[0] = bmax[0];
|
p3[0] = bmax[0];
|
||||||
p3[2] = bmin[2];
|
p3[2] = bmin[2];
|
||||||
@@ -280,7 +270,7 @@ bool computeSplitPlane(unsigned int vcount,
|
|||||||
p2[0] = bmin[0];
|
p2[0] = bmin[0];
|
||||||
p2[1] = bmin[1];
|
p2[1] = bmin[1];
|
||||||
|
|
||||||
if ( dx > dy )
|
if (dx > dy)
|
||||||
{
|
{
|
||||||
p3[0] = bmax[0];
|
p3[0] = bmax[0];
|
||||||
p3[1] = bmin[1];
|
p3[1] = bmin[1];
|
||||||
@@ -294,13 +284,11 @@ bool computeSplitPlane(unsigned int vcount,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback->ConvexDebugTri(p1,p2,p3,0xFF0000);
|
// callback->ConvexDebugTri(p1,p2,p3,0xFF0000);
|
||||||
|
|
||||||
computePlane(p1,p2,p3,plane);
|
computePlane(p1, p2, p3, plane);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace ConvexDecomposition
|
||||||
}
|
|
||||||
|
|||||||
@@ -39,11 +39,8 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ConvexDecomposition
|
namespace ConvexDecomposition
|
||||||
{
|
{
|
||||||
|
|
||||||
class ConvexDecompInterface;
|
class ConvexDecompInterface;
|
||||||
|
|
||||||
bool computeSplitPlane(unsigned int vcount,
|
bool computeSplitPlane(unsigned int vcount,
|
||||||
@@ -53,7 +50,6 @@ bool computeSplitPlane(unsigned int vcount,
|
|||||||
ConvexDecompInterface *callback,
|
ConvexDecompInterface *callback,
|
||||||
float *plane);
|
float *plane);
|
||||||
|
|
||||||
|
} // namespace ConvexDecomposition
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,13 +4,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#pragma warning(disable:4786)
|
#pragma warning(disable : 4786)
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -107,18 +106,14 @@
|
|||||||
// You could easily modify this code to support other vertex
|
// You could easily modify this code to support other vertex
|
||||||
// formats with any number of interpolants.
|
// formats with any number of interpolants.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "vlookup.h"
|
#include "vlookup.h"
|
||||||
|
|
||||||
namespace Vlookup
|
namespace Vlookup
|
||||||
{
|
{
|
||||||
|
|
||||||
class VertexPosition
|
class VertexPosition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexPosition(void) { };
|
VertexPosition(void){};
|
||||||
VertexPosition(const float *p)
|
VertexPosition(const float *p)
|
||||||
{
|
{
|
||||||
mPos[0] = p[0];
|
mPos[0] = p[0];
|
||||||
@@ -126,14 +121,13 @@ public:
|
|||||||
mPos[2] = p[2];
|
mPos[2] = p[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
void Set(int index,const float *pos)
|
void Set(int index, const float *pos)
|
||||||
{
|
{
|
||||||
const float * p = &pos[index*3];
|
const float *p = &pos[index * 3];
|
||||||
|
|
||||||
mPos[0] = p[0];
|
mPos[0] = p[0];
|
||||||
mPos[1] = p[1];
|
mPos[1] = p[1];
|
||||||
mPos[2] = p[2];
|
mPos[2] = p[2];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
float GetX(void) const { return mPos[0]; };
|
float GetX(void) const { return mPos[0]; };
|
||||||
@@ -143,7 +137,7 @@ public:
|
|||||||
float mPos[3];
|
float mPos[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< VertexPosition > VertexVector;
|
typedef std::vector<VertexPosition> VertexVector;
|
||||||
|
|
||||||
struct Tracker
|
struct Tracker
|
||||||
{
|
{
|
||||||
@@ -155,7 +149,7 @@ struct Tracker
|
|||||||
mList = 0;
|
mList = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSearch(const VertexPosition& match,VertexVector *list)
|
void SetSearch(const VertexPosition &match, VertexVector *list)
|
||||||
{
|
{
|
||||||
mFind = match;
|
mFind = match;
|
||||||
mList = list;
|
mList = list;
|
||||||
@@ -165,9 +159,9 @@ struct Tracker
|
|||||||
struct VertexID
|
struct VertexID
|
||||||
{
|
{
|
||||||
int mID;
|
int mID;
|
||||||
Tracker* mTracker;
|
Tracker *mTracker;
|
||||||
|
|
||||||
VertexID(int ID, Tracker* Tracker)
|
VertexID(int ID, Tracker *Tracker)
|
||||||
{
|
{
|
||||||
mID = ID;
|
mID = ID;
|
||||||
mTracker = Tracker;
|
mTracker = Tracker;
|
||||||
@@ -177,46 +171,45 @@ struct VertexID
|
|||||||
class VertexLess
|
class VertexLess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool operator()(VertexID v1, VertexID v2) const;
|
||||||
bool operator()(VertexID v1,VertexID v2) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const VertexPosition& Get(VertexID index) const
|
const VertexPosition &Get(VertexID index) const
|
||||||
{
|
{
|
||||||
if ( index.mID == -1 ) return index.mTracker->mFind;
|
if (index.mID == -1) return index.mTracker->mFind;
|
||||||
VertexVector &vlist = *index.mTracker->mList;
|
VertexVector &vlist = *index.mTracker->mList;
|
||||||
return vlist[index.mID];
|
return vlist[index.mID];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Type> class VertexPool
|
template <class Type>
|
||||||
|
class VertexPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::set<VertexID, VertexLess > VertexSet;
|
typedef std::set<VertexID, VertexLess> VertexSet;
|
||||||
typedef std::vector< Type > VertexVector;
|
typedef std::vector<Type> VertexVector;
|
||||||
|
|
||||||
int getVertex(const Type& vtx)
|
int getVertex(const Type &vtx)
|
||||||
{
|
{
|
||||||
mTracker.SetSearch(vtx,&mVtxs);
|
mTracker.SetSearch(vtx, &mVtxs);
|
||||||
VertexSet::iterator found;
|
VertexSet::iterator found;
|
||||||
found = mVertSet.find( VertexID(-1,&mTracker) );
|
found = mVertSet.find(VertexID(-1, &mTracker));
|
||||||
if ( found != mVertSet.end() )
|
if (found != mVertSet.end())
|
||||||
{
|
{
|
||||||
return found->mID;
|
return found->mID;
|
||||||
}
|
}
|
||||||
int idx = (int)mVtxs.size();
|
int idx = (int)mVtxs.size();
|
||||||
mVtxs.push_back( vtx );
|
mVtxs.push_back(vtx);
|
||||||
mVertSet.insert( VertexID(idx,&mTracker) );
|
mVertSet.insert(VertexID(idx, &mTracker));
|
||||||
return idx;
|
return idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const float *GetPos(int idx) const
|
||||||
const float * GetPos(int idx) const
|
|
||||||
{
|
{
|
||||||
return mVtxs[idx].mPos;
|
return mVtxs[idx].mPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type& Get(int idx) const
|
const Type &Get(int idx) const
|
||||||
{
|
{
|
||||||
return mVtxs[idx];
|
return mVtxs[idx];
|
||||||
};
|
};
|
||||||
@@ -233,9 +226,9 @@ public:
|
|||||||
mVtxs.reserve(reservesize);
|
mVtxs.reserve(reservesize);
|
||||||
};
|
};
|
||||||
|
|
||||||
const VertexVector& GetVertexList(void) const { return mVtxs; };
|
const VertexVector &GetVertexList(void) const { return mVtxs; };
|
||||||
|
|
||||||
void Set(const Type& vtx)
|
void Set(const Type &vtx)
|
||||||
{
|
{
|
||||||
mVtxs.push_back(vtx);
|
mVtxs.push_back(vtx);
|
||||||
}
|
}
|
||||||
@@ -245,8 +238,7 @@ public:
|
|||||||
return mVtxs.size();
|
return mVtxs.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Type *getBuffer(void)
|
||||||
Type * getBuffer(void)
|
|
||||||
{
|
{
|
||||||
return &mVtxs[0];
|
return &mVtxs[0];
|
||||||
};
|
};
|
||||||
@@ -257,70 +249,63 @@ private:
|
|||||||
Tracker mTracker;
|
Tracker mTracker;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool VertexLess::operator()(VertexID v1, VertexID v2) const
|
||||||
bool VertexLess::operator()(VertexID v1,VertexID v2) const
|
|
||||||
{
|
{
|
||||||
|
const VertexPosition &a = Get(v1);
|
||||||
|
const VertexPosition &b = Get(v2);
|
||||||
|
|
||||||
const VertexPosition& a = Get(v1);
|
int ixA = (int)(a.GetX() * 10000.0f);
|
||||||
const VertexPosition& b = Get(v2);
|
int ixB = (int)(b.GetX() * 10000.0f);
|
||||||
|
|
||||||
int ixA = (int) (a.GetX()*10000.0f);
|
if (ixA < ixB) return true;
|
||||||
int ixB = (int) (b.GetX()*10000.0f);
|
if (ixA > ixB) return false;
|
||||||
|
|
||||||
if ( ixA < ixB ) return true;
|
int iyA = (int)(a.GetY() * 10000.0f);
|
||||||
if ( ixA > ixB ) return false;
|
int iyB = (int)(b.GetY() * 10000.0f);
|
||||||
|
|
||||||
int iyA = (int) (a.GetY()*10000.0f);
|
if (iyA < iyB) return true;
|
||||||
int iyB = (int) (b.GetY()*10000.0f);
|
if (iyA > iyB) return false;
|
||||||
|
|
||||||
if ( iyA < iyB ) return true;
|
int izA = (int)(a.GetZ() * 10000.0f);
|
||||||
if ( iyA > iyB ) return false;
|
int izB = (int)(b.GetZ() * 10000.0f);
|
||||||
|
|
||||||
int izA = (int) (a.GetZ()*10000.0f);
|
|
||||||
int izB = (int) (b.GetZ()*10000.0f);
|
|
||||||
|
|
||||||
if ( izA < izB ) return true;
|
|
||||||
if ( izA > izB ) return false;
|
|
||||||
|
|
||||||
|
if (izA < izB) return true;
|
||||||
|
if (izA > izB) return false;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Vlookup
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace Vlookup;
|
using namespace Vlookup;
|
||||||
|
|
||||||
VertexLookup Vl_createVertexLookup(void)
|
VertexLookup Vl_createVertexLookup(void)
|
||||||
{
|
{
|
||||||
VertexLookup ret = new VertexPool< VertexPosition >;
|
VertexLookup ret = new VertexPool<VertexPosition>;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vl_releaseVertexLookup(VertexLookup vlook)
|
void Vl_releaseVertexLookup(VertexLookup vlook)
|
||||||
{
|
{
|
||||||
VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook;
|
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||||
delete vp;
|
delete vp;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Vl_getIndex(VertexLookup vlook,const float *pos) // get index.
|
unsigned int Vl_getIndex(VertexLookup vlook, const float *pos) // get index.
|
||||||
{
|
{
|
||||||
VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook;
|
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||||
VertexPosition p(pos);
|
VertexPosition p(pos);
|
||||||
return vp->getVertex(p);
|
return vp->getVertex(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float * Vl_getVertices(VertexLookup vlook)
|
const float *Vl_getVertices(VertexLookup vlook)
|
||||||
{
|
{
|
||||||
VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook;
|
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||||
return vp->GetPos(0);
|
return vp->GetPos(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int Vl_getVcount(VertexLookup vlook)
|
unsigned int Vl_getVcount(VertexLookup vlook)
|
||||||
{
|
{
|
||||||
VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook;
|
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||||
return vp->GetVertexCount();
|
return vp->GetVertexCount();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#define VLOOKUP_H
|
#define VLOOKUP_H
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Copyright (c) 2004 Open Dynamics Framework Group
|
Copyright (c) 2004 Open Dynamics Framework Group
|
||||||
www.physicstools.org
|
www.physicstools.org
|
||||||
@@ -37,7 +36,6 @@
|
|||||||
// http://www.amillionpixels.us
|
// http://www.amillionpixels.us
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
// CodeSnippet provided by John W. Ratcliff
|
// CodeSnippet provided by John W. Ratcliff
|
||||||
// on March 23, 2006.
|
// on March 23, 2006.
|
||||||
//
|
//
|
||||||
@@ -105,15 +103,13 @@
|
|||||||
// Uses an STL set to create an index table for a bunch of vertex positions
|
// Uses an STL set to create an index table for a bunch of vertex positions
|
||||||
// used typically to re-index a collection of raw triangle data.
|
// used typically to re-index a collection of raw triangle data.
|
||||||
|
|
||||||
|
typedef void *VertexLookup;
|
||||||
typedef void * VertexLookup;
|
|
||||||
|
|
||||||
VertexLookup Vl_createVertexLookup(void);
|
VertexLookup Vl_createVertexLookup(void);
|
||||||
void Vl_releaseVertexLookup(VertexLookup vlook);
|
void Vl_releaseVertexLookup(VertexLookup vlook);
|
||||||
|
|
||||||
unsigned int Vl_getIndex(VertexLookup vlook,const float *pos); // get index.
|
unsigned int Vl_getIndex(VertexLookup vlook, const float *pos); // get index.
|
||||||
const float * Vl_getVertices(VertexLookup vlook);
|
const float *Vl_getVertices(VertexLookup vlook);
|
||||||
unsigned int Vl_getVcount(VertexLookup vlook);
|
unsigned int Vl_getVcount(VertexLookup vlook);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,17 +26,16 @@ subject to the following restrictions:
|
|||||||
class GIM_ConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
|
class GIM_ConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
btGImpactConvexDecompositionShape * m_compoundShape;
|
btGImpactConvexDecompositionShape* m_compoundShape;
|
||||||
|
|
||||||
btAlignedObjectArray<btCollisionShape*> m_convexShapes;
|
btAlignedObjectArray<btCollisionShape*> m_convexShapes;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int mBaseCount;
|
int mBaseCount;
|
||||||
int mHullCount;
|
int mHullCount;
|
||||||
bool m_transformSubShapes;
|
bool m_transformSubShapes;
|
||||||
|
|
||||||
GIM_ConvexDecomposition(btGImpactConvexDecompositionShape * compoundShape,bool transformSubShapes)
|
GIM_ConvexDecomposition(btGImpactConvexDecompositionShape* compoundShape, bool transformSubShapes)
|
||||||
{
|
{
|
||||||
mBaseCount = 0;
|
mBaseCount = 0;
|
||||||
mHullCount = 0;
|
mHullCount = 0;
|
||||||
@@ -47,43 +46,39 @@ public:
|
|||||||
virtual ~GIM_ConvexDecomposition()
|
virtual ~GIM_ConvexDecomposition()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<m_convexShapes.size();i++)
|
for (i = 0; i < m_convexShapes.size(); i++)
|
||||||
{
|
{
|
||||||
btCollisionShape* shape = m_convexShapes[i];
|
btCollisionShape* shape = m_convexShapes[i];
|
||||||
delete shape;
|
delete shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
|
virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult& result)
|
||||||
{
|
{
|
||||||
|
|
||||||
//calc centroid, to shift vertices around center of mass
|
//calc centroid, to shift vertices around center of mass
|
||||||
btVector3 centroid(0,0,0);
|
btVector3 centroid(0, 0, 0);
|
||||||
btAlignedObjectArray<btVector3> vertices;
|
btAlignedObjectArray<btVector3> vertices;
|
||||||
|
|
||||||
if(m_transformSubShapes)
|
if (m_transformSubShapes)
|
||||||
{
|
{
|
||||||
|
|
||||||
//const unsigned int *src = result.mHullIndices;
|
//const unsigned int *src = result.mHullIndices;
|
||||||
for (unsigned int i=0; i<result.mHullVcount; i++)
|
for (unsigned int i = 0; i < result.mHullVcount; i++)
|
||||||
{
|
{
|
||||||
btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
|
btVector3 vertex(result.mHullVertices[i * 3], result.mHullVertices[i * 3 + 1], result.mHullVertices[i * 3 + 2]);
|
||||||
|
|
||||||
centroid += vertex;
|
centroid += vertex;
|
||||||
|
|
||||||
}
|
}
|
||||||
centroid *= 1.f/(float(result.mHullVcount) );
|
centroid *= 1.f / (float(result.mHullVcount));
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect vertices
|
// collect vertices
|
||||||
for (unsigned int i=0; i<result.mHullVcount; i++)
|
for (unsigned int i = 0; i < result.mHullVcount; i++)
|
||||||
{
|
{
|
||||||
btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
|
btVector3 vertex(result.mHullVertices[i * 3], result.mHullVertices[i * 3 + 1], result.mHullVertices[i * 3 + 2]);
|
||||||
|
|
||||||
if(m_transformSubShapes)
|
if (m_transformSubShapes)
|
||||||
{
|
{
|
||||||
vertex -= centroid ;
|
vertex -= centroid;
|
||||||
}
|
}
|
||||||
vertices.push_back(vertex);
|
vertices.push_back(vertex);
|
||||||
}
|
}
|
||||||
@@ -91,12 +86,12 @@ public:
|
|||||||
// build convex shape
|
// build convex shape
|
||||||
|
|
||||||
btCollisionShape* convexShape = new btConvexHullShape(
|
btCollisionShape* convexShape = new btConvexHullShape(
|
||||||
&(vertices[0].getX()),vertices.size(),sizeof(btVector3));
|
&(vertices[0].getX()), vertices.size(), sizeof(btVector3));
|
||||||
m_convexShapes.push_back(convexShape);
|
m_convexShapes.push_back(convexShape);
|
||||||
|
|
||||||
convexShape->setMargin(m_compoundShape->getMargin());
|
convexShape->setMargin(m_compoundShape->getMargin());
|
||||||
|
|
||||||
if(m_transformSubShapes)
|
if (m_transformSubShapes)
|
||||||
{
|
{
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
trans.setIdentity();
|
trans.setIdentity();
|
||||||
@@ -104,7 +99,7 @@ public:
|
|||||||
|
|
||||||
// add convex shape
|
// add convex shape
|
||||||
|
|
||||||
m_compoundShape->addChildShape(trans,convexShape);
|
m_compoundShape->addChildShape(trans, convexShape);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -114,7 +109,7 @@ public:
|
|||||||
|
|
||||||
// add convex shape
|
// add convex shape
|
||||||
|
|
||||||
m_compoundShape->addChildShape(trans,convexShape);
|
m_compoundShape->addChildShape(trans, convexShape);
|
||||||
|
|
||||||
//m_compoundShape->addChildShape(convexShape);
|
//m_compoundShape->addChildShape(convexShape);
|
||||||
}
|
}
|
||||||
@@ -122,35 +117,32 @@ public:
|
|||||||
|
|
||||||
void processDecomposition(int part)
|
void processDecomposition(int part)
|
||||||
{
|
{
|
||||||
btGImpactMeshShapePart::TrimeshPrimitiveManager * trimeshInterface =
|
btGImpactMeshShapePart::TrimeshPrimitiveManager* trimeshInterface =
|
||||||
m_compoundShape->getTrimeshInterface(part);
|
m_compoundShape->getTrimeshInterface(part);
|
||||||
|
|
||||||
|
|
||||||
trimeshInterface->lock();
|
trimeshInterface->lock();
|
||||||
|
|
||||||
//collect vertices
|
//collect vertices
|
||||||
btAlignedObjectArray<float> vertices;
|
btAlignedObjectArray<float> vertices;
|
||||||
vertices.reserve(trimeshInterface->get_vertex_count()*3);
|
vertices.reserve(trimeshInterface->get_vertex_count() * 3);
|
||||||
|
|
||||||
for(int vi = 0;vi<trimeshInterface->get_vertex_count();vi++)
|
for (int vi = 0; vi < trimeshInterface->get_vertex_count(); vi++)
|
||||||
{
|
{
|
||||||
btVector3 vec;
|
btVector3 vec;
|
||||||
trimeshInterface->get_vertex(vi,vec);
|
trimeshInterface->get_vertex(vi, vec);
|
||||||
vertices.push_back(vec[0]);
|
vertices.push_back(vec[0]);
|
||||||
vertices.push_back(vec[1]);
|
vertices.push_back(vec[1]);
|
||||||
vertices.push_back(vec[2]);
|
vertices.push_back(vec[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//collect indices
|
//collect indices
|
||||||
btAlignedObjectArray<unsigned int> indices;
|
btAlignedObjectArray<unsigned int> indices;
|
||||||
indices.reserve(trimeshInterface->get_primitive_count()*3);
|
indices.reserve(trimeshInterface->get_primitive_count() * 3);
|
||||||
|
|
||||||
|
for (int i = 0; i < trimeshInterface->get_primitive_count(); i++)
|
||||||
for(int i = 0;i<trimeshInterface->get_primitive_count();i++)
|
|
||||||
{
|
{
|
||||||
unsigned int i0, i1,i2;
|
unsigned int i0, i1, i2;
|
||||||
trimeshInterface->get_indices(i,i0,i1,i2);
|
trimeshInterface->get_indices(i, i0, i1, i2);
|
||||||
indices.push_back(i0);
|
indices.push_back(i0);
|
||||||
indices.push_back(i1);
|
indices.push_back(i1);
|
||||||
indices.push_back(i2);
|
indices.push_back(i2);
|
||||||
@@ -158,15 +150,12 @@ public:
|
|||||||
|
|
||||||
trimeshInterface->unlock();
|
trimeshInterface->unlock();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int depth = 5;
|
unsigned int depth = 5;
|
||||||
float cpercent = 5;
|
float cpercent = 5;
|
||||||
float ppercent = 15;
|
float ppercent = 15;
|
||||||
unsigned int maxv = 16;
|
unsigned int maxv = 16;
|
||||||
float skinWidth = 0.0f;
|
float skinWidth = 0.0f;
|
||||||
|
|
||||||
|
|
||||||
ConvexDecomposition::DecompDesc desc;
|
ConvexDecomposition::DecompDesc desc;
|
||||||
desc.mVcount = trimeshInterface->get_vertex_count();
|
desc.mVcount = trimeshInterface->get_vertex_count();
|
||||||
desc.mVertices = &vertices[0];
|
desc.mVertices = &vertices[0];
|
||||||
@@ -184,21 +173,14 @@ public:
|
|||||||
ConvexBuilder cb(desc.mCallback);
|
ConvexBuilder cb(desc.mCallback);
|
||||||
cb.process(desc);
|
cb.process(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void btGImpactConvexDecompositionShape::buildConvexDecomposition(bool transformSubShapes)
|
void btGImpactConvexDecompositionShape::buildConvexDecomposition(bool transformSubShapes)
|
||||||
{
|
{
|
||||||
|
m_decomposition = new GIM_ConvexDecomposition(this, transformSubShapes);
|
||||||
m_decomposition = new GIM_ConvexDecomposition(this,transformSubShapes);
|
|
||||||
|
|
||||||
int part_count = m_trimeshInterfaces.size();
|
int part_count = m_trimeshInterfaces.size();
|
||||||
for (int i = 0;i<part_count ;i++ )
|
for (int i = 0; i < part_count; i++)
|
||||||
{
|
{
|
||||||
m_decomposition->processDecomposition(i);
|
m_decomposition->processDecomposition(i);
|
||||||
}
|
}
|
||||||
@@ -210,31 +192,27 @@ btGImpactConvexDecompositionShape::~btGImpactConvexDecompositionShape()
|
|||||||
{
|
{
|
||||||
delete m_decomposition;
|
delete m_decomposition;
|
||||||
}
|
}
|
||||||
void btGImpactConvexDecompositionShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
void btGImpactConvexDecompositionShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
|
||||||
{
|
{
|
||||||
|
|
||||||
int part_count = m_trimeshInterfaces.size();
|
int part_count = m_trimeshInterfaces.size();
|
||||||
for (int part = 0;part<part_count ;part++ )
|
for (int part = 0; part < part_count; part++)
|
||||||
{
|
{
|
||||||
void * ptr = (void * )&m_trimeshInterfaces[part];
|
void* ptr = (void*)&m_trimeshInterfaces[part];
|
||||||
|
|
||||||
btGImpactMeshShapePart::TrimeshPrimitiveManager * trimeshInterface =
|
btGImpactMeshShapePart::TrimeshPrimitiveManager* trimeshInterface =
|
||||||
static_cast<btGImpactMeshShapePart::TrimeshPrimitiveManager *>(ptr);
|
static_cast<btGImpactMeshShapePart::TrimeshPrimitiveManager*>(ptr);
|
||||||
|
|
||||||
trimeshInterface->lock();
|
trimeshInterface->lock();
|
||||||
|
|
||||||
btPrimitiveTriangle triangle;
|
btPrimitiveTriangle triangle;
|
||||||
|
|
||||||
|
|
||||||
int i = trimeshInterface->get_primitive_count();
|
int i = trimeshInterface->get_primitive_count();
|
||||||
while(i--)
|
while (i--)
|
||||||
{
|
{
|
||||||
trimeshInterface->get_primitive_triangle(i,triangle);
|
trimeshInterface->get_primitive_triangle(i, triangle);
|
||||||
callback->processTriangle(triangle.m_vertices,part,i);
|
callback->processTriangle(triangle.m_vertices, part, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
trimeshInterface->unlock();
|
trimeshInterface->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,8 @@ subject to the following restrictions:
|
|||||||
#ifndef GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H
|
#ifndef GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H
|
||||||
#define GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H
|
#define GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H
|
||||||
|
|
||||||
|
|
||||||
#include "BulletCollision/Gimpact/btGImpactShape.h" // box tree class
|
#include "BulletCollision/Gimpact/btGImpactShape.h" // box tree class
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! This class creates a decomposition from a trimesh.
|
//! This class creates a decomposition from a trimesh.
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
@@ -41,15 +38,14 @@ protected:
|
|||||||
class GIM_ConvexDecomposition* m_decomposition;
|
class GIM_ConvexDecomposition* m_decomposition;
|
||||||
|
|
||||||
void buildConvexDecomposition(bool transformSubShapes);
|
void buildConvexDecomposition(bool transformSubShapes);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btGImpactConvexDecompositionShape(
|
btGImpactConvexDecompositionShape(
|
||||||
btStridingMeshInterface * meshInterface,
|
btStridingMeshInterface* meshInterface,
|
||||||
const btVector3 & mesh_scale,
|
const btVector3& mesh_scale,
|
||||||
btScalar margin = btScalar(0.01),bool children_has_transform = true)
|
btScalar margin = btScalar(0.01), bool children_has_transform = true)
|
||||||
:btGImpactCompoundShape(children_has_transform)
|
: btGImpactCompoundShape(children_has_transform)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_collisionMargin = margin;
|
m_collisionMargin = margin;
|
||||||
|
|
||||||
btGImpactMeshShapePart::TrimeshPrimitiveManager triInterface;
|
btGImpactMeshShapePart::TrimeshPrimitiveManager triInterface;
|
||||||
@@ -59,7 +55,7 @@ public:
|
|||||||
|
|
||||||
//add parts
|
//add parts
|
||||||
int part_count = meshInterface->getNumSubParts();
|
int part_count = meshInterface->getNumSubParts();
|
||||||
for (int i=0;i< part_count;i++ )
|
for (int i = 0; i < part_count; i++)
|
||||||
{
|
{
|
||||||
triInterface.m_part = i;
|
triInterface.m_part = i;
|
||||||
m_trimeshInterfaces.push_back(triInterface);
|
m_trimeshInterfaces.push_back(triInterface);
|
||||||
@@ -72,16 +68,12 @@ public:
|
|||||||
|
|
||||||
virtual ~btGImpactConvexDecompositionShape();
|
virtual ~btGImpactConvexDecompositionShape();
|
||||||
|
|
||||||
SIMD_FORCE_INLINE btGImpactMeshShapePart::TrimeshPrimitiveManager * getTrimeshInterface(int part)
|
SIMD_FORCE_INLINE btGImpactMeshShapePart::TrimeshPrimitiveManager* getTrimeshInterface(int part)
|
||||||
{
|
{
|
||||||
return &m_trimeshInterfaces[part];
|
return &m_trimeshInterfaces[part];
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
|
virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //GIMPACT_MESH_SHAPE_H
|
#endif //GIMPACT_MESH_SHAPE_H
|
||||||
|
|||||||
@@ -15,51 +15,57 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef HACD_CIRCULAR_LIST_H
|
#ifndef HACD_CIRCULAR_LIST_H
|
||||||
#define HACD_CIRCULAR_LIST_H
|
#define HACD_CIRCULAR_LIST_H
|
||||||
#include<stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "hacdVersion.h"
|
#include "hacdVersion.h"
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
//! CircularListElement class.
|
//! CircularListElement class.
|
||||||
template < typename T > class CircularListElement
|
template <typename T>
|
||||||
{
|
class CircularListElement
|
||||||
public:
|
{
|
||||||
T & GetData() { return m_data; }
|
public:
|
||||||
const T & GetData() const { return m_data; }
|
T& GetData() { return m_data; }
|
||||||
CircularListElement<T> * & GetNext() { return m_next; }
|
const T& GetData() const { return m_data; }
|
||||||
CircularListElement<T> * & GetPrev() { return m_prev; }
|
CircularListElement<T>*& GetNext() { return m_next; }
|
||||||
const CircularListElement<T> * & GetNext() const { return m_next; }
|
CircularListElement<T>*& GetPrev() { return m_prev; }
|
||||||
const CircularListElement<T> * & GetPrev() const { return m_prev; }
|
const CircularListElement<T>*& GetNext() const { return m_next; }
|
||||||
|
const CircularListElement<T>*& GetPrev() const { return m_prev; }
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CircularListElement(const T & data) {m_data = data;}
|
CircularListElement(const T& data) { m_data = data; }
|
||||||
CircularListElement(void){}
|
CircularListElement(void) {}
|
||||||
//! Destructor
|
//! Destructor
|
||||||
~CircularListElement(void){}
|
~CircularListElement(void) {}
|
||||||
private:
|
|
||||||
|
private:
|
||||||
T m_data;
|
T m_data;
|
||||||
CircularListElement<T> * m_next;
|
CircularListElement<T>* m_next;
|
||||||
CircularListElement<T> * m_prev;
|
CircularListElement<T>* m_prev;
|
||||||
|
|
||||||
CircularListElement(const CircularListElement & rhs);
|
CircularListElement(const CircularListElement& rhs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! CircularList class.
|
||||||
//! CircularList class.
|
template <typename T>
|
||||||
template < typename T > class CircularList
|
class CircularList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CircularListElement<T> * & GetHead() { return m_head;}
|
CircularListElement<T>*& GetHead() { return m_head; }
|
||||||
const CircularListElement<T> * GetHead() const { return m_head;}
|
const CircularListElement<T>* GetHead() const { return m_head; }
|
||||||
bool IsEmpty() const { return (m_size == 0);}
|
bool IsEmpty() const { return (m_size == 0); }
|
||||||
size_t GetSize() const { return m_size; }
|
size_t GetSize() const { return m_size; }
|
||||||
const T & GetData() const { return m_head->GetData(); }
|
const T& GetData() const { return m_head->GetData(); }
|
||||||
T & GetData() { return m_head->GetData();}
|
T& GetData() { return m_head->GetData(); }
|
||||||
bool Delete() ;
|
bool Delete();
|
||||||
bool Delete(CircularListElement<T> * element);
|
bool Delete(CircularListElement<T>* element);
|
||||||
CircularListElement<T> * Add(const T * data = 0);
|
CircularListElement<T>* Add(const T* data = 0);
|
||||||
CircularListElement<T> * Add(const T & data);
|
CircularListElement<T>* Add(const T& data);
|
||||||
bool Next();
|
bool Next();
|
||||||
bool Prev();
|
bool Prev();
|
||||||
void Clear() { while(Delete());};
|
void Clear()
|
||||||
|
{
|
||||||
|
while (Delete())
|
||||||
|
;
|
||||||
|
};
|
||||||
const CircularList& operator=(const CircularList& rhs);
|
const CircularList& operator=(const CircularList& rhs);
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CircularList()
|
CircularList()
|
||||||
@@ -69,12 +75,12 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
CircularList(const CircularList& rhs);
|
CircularList(const CircularList& rhs);
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~CircularList(void) {Clear();};
|
virtual ~CircularList(void) { Clear(); };
|
||||||
private:
|
|
||||||
CircularListElement<T> * m_head; //!< a pointer to the head of the circular list
|
|
||||||
size_t m_size; //!< number of element in the circular list
|
|
||||||
|
|
||||||
};
|
private:
|
||||||
}
|
CircularListElement<T>* m_head; //!< a pointer to the head of the circular list
|
||||||
|
size_t m_size; //!< number of element in the circular list
|
||||||
|
};
|
||||||
|
} // namespace HACD
|
||||||
#include "hacdCircularList.inl"
|
#include "hacdCircularList.inl"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,9 +15,8 @@
|
|||||||
#include "hacdGraph.h"
|
#include "hacdGraph.h"
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
|
GraphEdge::GraphEdge()
|
||||||
GraphEdge::GraphEdge()
|
{
|
||||||
{
|
|
||||||
m_convexHull = 0;
|
m_convexHull = 0;
|
||||||
m_v1 = -1;
|
m_v1 = -1;
|
||||||
m_v2 = -1;
|
m_v2 = -1;
|
||||||
@@ -28,10 +27,10 @@ namespace HACD
|
|||||||
m_concavity = 0;
|
m_concavity = 0;
|
||||||
m_volume = 0;
|
m_volume = 0;
|
||||||
m_deleted = false;
|
m_deleted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphVertex::GraphVertex()
|
GraphVertex::GraphVertex()
|
||||||
{
|
{
|
||||||
m_convexHull = 0;
|
m_convexHull = 0;
|
||||||
m_name = -1;
|
m_name = -1;
|
||||||
m_cc = -1;
|
m_cc = -1;
|
||||||
@@ -41,52 +40,52 @@ namespace HACD
|
|||||||
m_concavity = 0;
|
m_concavity = 0;
|
||||||
m_volume = 0;
|
m_volume = 0;
|
||||||
m_deleted = false;
|
m_deleted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphVertex::DeleteEdge(long name)
|
bool GraphVertex::DeleteEdge(long name)
|
||||||
{
|
{
|
||||||
std::set<long>::iterator it = m_edges.find(name);
|
std::set<long>::iterator it = m_edges.find(name);
|
||||||
if (it != m_edges.end() )
|
if (it != m_edges.end())
|
||||||
{
|
{
|
||||||
m_edges.erase(it);
|
m_edges.erase(it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph::Graph()
|
Graph::Graph()
|
||||||
{
|
{
|
||||||
m_nV = 0;
|
m_nV = 0;
|
||||||
m_nE = 0;
|
m_nE = 0;
|
||||||
m_nCCs = 0;
|
m_nCCs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph::~Graph()
|
Graph::~Graph()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graph::Allocate(size_t nV, size_t nE)
|
void Graph::Allocate(size_t nV, size_t nE)
|
||||||
{
|
{
|
||||||
m_nV = nV;
|
m_nV = nV;
|
||||||
m_edges.reserve(nE);
|
m_edges.reserve(nE);
|
||||||
m_vertices.resize(nV);
|
m_vertices.resize(nV);
|
||||||
for(size_t i = 0; i < nV; i++)
|
for (size_t i = 0; i < nV; i++)
|
||||||
{
|
{
|
||||||
m_vertices[i].m_name = static_cast<long>(i);
|
m_vertices[i].m_name = static_cast<long>(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long Graph::AddVertex()
|
long Graph::AddVertex()
|
||||||
{
|
{
|
||||||
size_t name = m_vertices.size();
|
size_t name = m_vertices.size();
|
||||||
m_vertices.resize(name+1);
|
m_vertices.resize(name + 1);
|
||||||
m_vertices[name].m_name = static_cast<long>(name);
|
m_vertices[name].m_name = static_cast<long>(name);
|
||||||
m_nV++;
|
m_nV++;
|
||||||
return static_cast<long>(name);
|
return static_cast<long>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
long Graph::AddEdge(long v1, long v2)
|
long Graph::AddEdge(long v1, long v2)
|
||||||
{
|
{
|
||||||
size_t name = m_edges.size();
|
size_t name = m_edges.size();
|
||||||
m_edges.push_back(GraphEdge());
|
m_edges.push_back(GraphEdge());
|
||||||
m_edges[name].m_name = static_cast<long>(name);
|
m_edges[name].m_name = static_cast<long>(name);
|
||||||
@@ -96,10 +95,10 @@ namespace HACD
|
|||||||
m_vertices[v2].AddEdge(static_cast<long>(name));
|
m_vertices[v2].AddEdge(static_cast<long>(name));
|
||||||
m_nE++;
|
m_nE++;
|
||||||
return static_cast<long>(name);
|
return static_cast<long>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graph::DeleteEdge(long name)
|
bool Graph::DeleteEdge(long name)
|
||||||
{
|
{
|
||||||
if (name < static_cast<long>(m_edges.size()))
|
if (name < static_cast<long>(m_edges.size()))
|
||||||
{
|
{
|
||||||
long v1 = m_edges[name].m_v1;
|
long v1 = m_edges[name].m_v1;
|
||||||
@@ -115,9 +114,9 @@ namespace HACD
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool Graph::DeleteVertex(long name)
|
bool Graph::DeleteVertex(long name)
|
||||||
{
|
{
|
||||||
if (name < static_cast<long>(m_vertices.size()))
|
if (name < static_cast<long>(m_vertices.size()))
|
||||||
{
|
{
|
||||||
m_vertices[name].m_deleted = true;
|
m_vertices[name].m_deleted = true;
|
||||||
@@ -131,9 +130,9 @@ namespace HACD
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool Graph::EdgeCollapse(long v1, long v2)
|
bool Graph::EdgeCollapse(long v1, long v2)
|
||||||
{
|
{
|
||||||
long edgeToDelete = GetEdgeID(v1, v2);
|
long edgeToDelete = GetEdgeID(v1, v2);
|
||||||
if (edgeToDelete >= 0)
|
if (edgeToDelete >= 0)
|
||||||
{
|
{
|
||||||
@@ -146,11 +145,11 @@ namespace HACD
|
|||||||
m_vertices[v2].m_ancestors.begin(),
|
m_vertices[v2].m_ancestors.begin(),
|
||||||
m_vertices[v2].m_ancestors.end());
|
m_vertices[v2].m_ancestors.end());
|
||||||
// update adjacency information
|
// update adjacency information
|
||||||
std::set<long> & v1Edges = m_vertices[v1].m_edges;
|
std::set<long>& v1Edges = m_vertices[v1].m_edges;
|
||||||
std::set<long>::const_iterator ed(m_vertices[v2].m_edges.begin());
|
std::set<long>::const_iterator ed(m_vertices[v2].m_edges.begin());
|
||||||
std::set<long>::const_iterator itEnd(m_vertices[v2].m_edges.end());
|
std::set<long>::const_iterator itEnd(m_vertices[v2].m_edges.end());
|
||||||
long b = -1;
|
long b = -1;
|
||||||
for(; ed != itEnd; ++ed)
|
for (; ed != itEnd; ++ed)
|
||||||
{
|
{
|
||||||
if (m_edges[*ed].m_v1 == v2)
|
if (m_edges[*ed].m_v1 == v2)
|
||||||
{
|
{
|
||||||
@@ -178,40 +177,39 @@ namespace HACD
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long Graph::GetEdgeID(long v1, long v2) const
|
long Graph::GetEdgeID(long v1, long v2) const
|
||||||
{
|
{
|
||||||
if (v1 < static_cast<long>(m_vertices.size()) && !m_vertices[v1].m_deleted)
|
if (v1 < static_cast<long>(m_vertices.size()) && !m_vertices[v1].m_deleted)
|
||||||
{
|
{
|
||||||
std::set<long>::const_iterator ed(m_vertices[v1].m_edges.begin());
|
std::set<long>::const_iterator ed(m_vertices[v1].m_edges.begin());
|
||||||
std::set<long>::const_iterator itEnd(m_vertices[v1].m_edges.end());
|
std::set<long>::const_iterator itEnd(m_vertices[v1].m_edges.end());
|
||||||
for(; ed != itEnd; ++ed)
|
for (; ed != itEnd; ++ed)
|
||||||
{
|
{
|
||||||
if ( (m_edges[*ed].m_v1 == v2) ||
|
if ((m_edges[*ed].m_v1 == v2) ||
|
||||||
(m_edges[*ed].m_v2 == v2) )
|
(m_edges[*ed].m_v2 == v2))
|
||||||
{
|
{
|
||||||
return m_edges[*ed].m_name;
|
return m_edges[*ed].m_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graph::Print() const
|
void Graph::Print() const
|
||||||
{
|
{
|
||||||
std::cout << "-----------------------------" << std::endl;
|
std::cout << "-----------------------------" << std::endl;
|
||||||
std::cout << "vertices (" << m_nV << ")" << std::endl;
|
std::cout << "vertices (" << m_nV << ")" << std::endl;
|
||||||
for (size_t v = 0; v < m_vertices.size(); ++v)
|
for (size_t v = 0; v < m_vertices.size(); ++v)
|
||||||
{
|
{
|
||||||
const GraphVertex & currentVertex = m_vertices[v];
|
const GraphVertex& currentVertex = m_vertices[v];
|
||||||
if (!m_vertices[v].m_deleted)
|
if (!m_vertices[v].m_deleted)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::cout << currentVertex.m_name << "\t";
|
std::cout << currentVertex.m_name << "\t";
|
||||||
std::set<long>::const_iterator ed(currentVertex.m_edges.begin());
|
std::set<long>::const_iterator ed(currentVertex.m_edges.begin());
|
||||||
std::set<long>::const_iterator itEnd(currentVertex.m_edges.end());
|
std::set<long>::const_iterator itEnd(currentVertex.m_edges.end());
|
||||||
for(; ed != itEnd; ++ed)
|
for (; ed != itEnd; ++ed)
|
||||||
{
|
{
|
||||||
std::cout << "(" << m_edges[*ed].m_v1 << "," << m_edges[*ed].m_v2 << ") ";
|
std::cout << "(" << m_edges[*ed].m_v1 << "," << m_edges[*ed].m_v2 << ") ";
|
||||||
}
|
}
|
||||||
@@ -222,25 +220,25 @@ namespace HACD
|
|||||||
std::cout << "vertices (" << m_nE << ")" << std::endl;
|
std::cout << "vertices (" << m_nE << ")" << std::endl;
|
||||||
for (size_t e = 0; e < m_edges.size(); ++e)
|
for (size_t e = 0; e < m_edges.size(); ++e)
|
||||||
{
|
{
|
||||||
const GraphEdge & currentEdge = m_edges[e];
|
const GraphEdge& currentEdge = m_edges[e];
|
||||||
if (!m_edges[e].m_deleted)
|
if (!m_edges[e].m_deleted)
|
||||||
{
|
{
|
||||||
std::cout << currentEdge.m_name << "\t("
|
std::cout << currentEdge.m_name << "\t("
|
||||||
<< m_edges[e].m_v1 << ","
|
<< m_edges[e].m_v1 << ","
|
||||||
<< m_edges[e].m_v2 << ") "<< std::endl;
|
<< m_edges[e].m_v2 << ") " << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Graph::Clear()
|
void Graph::Clear()
|
||||||
{
|
{
|
||||||
m_vertices.clear();
|
m_vertices.clear();
|
||||||
m_edges.clear();
|
m_edges.clear();
|
||||||
m_nV = 0;
|
m_nV = 0;
|
||||||
m_nE = 0;
|
m_nE = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long Graph::ExtractCCs()
|
long Graph::ExtractCCs()
|
||||||
{
|
{
|
||||||
// all CCs to -1
|
// all CCs to -1
|
||||||
for (size_t v = 0; v < m_vertices.size(); ++v)
|
for (size_t v = 0; v < m_vertices.size(); ++v)
|
||||||
{
|
{
|
||||||
@@ -263,11 +261,11 @@ namespace HACD
|
|||||||
temp.push_back(m_vertices[v].m_name);
|
temp.push_back(m_vertices[v].m_name);
|
||||||
while (temp.size())
|
while (temp.size())
|
||||||
{
|
{
|
||||||
long vertex = temp[temp.size()-1];
|
long vertex = temp[temp.size() - 1];
|
||||||
temp.pop_back();
|
temp.pop_back();
|
||||||
std::set<long>::const_iterator ed(m_vertices[vertex].m_edges.begin());
|
std::set<long>::const_iterator ed(m_vertices[vertex].m_edges.begin());
|
||||||
std::set<long>::const_iterator itEnd(m_vertices[vertex].m_edges.end());
|
std::set<long>::const_iterator itEnd(m_vertices[vertex].m_edges.end());
|
||||||
for(; ed != itEnd; ++ed)
|
for (; ed != itEnd; ++ed)
|
||||||
{
|
{
|
||||||
if (m_edges[*ed].m_v1 == vertex)
|
if (m_edges[*ed].m_v1 == vertex)
|
||||||
{
|
{
|
||||||
@@ -277,7 +275,7 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
v2 = m_edges[*ed].m_v1;
|
v2 = m_edges[*ed].m_v1;
|
||||||
}
|
}
|
||||||
if ( !m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1)
|
if (!m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1)
|
||||||
{
|
{
|
||||||
m_vertices[v2].m_cc = static_cast<long>(m_nCCs);
|
m_vertices[v2].m_cc = static_cast<long>(m_nCCs);
|
||||||
temp.push_back(v2);
|
temp.push_back(v2);
|
||||||
@@ -288,5 +286,5 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return static_cast<long>(m_nCCs);
|
return static_cast<long>(m_nCCs);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace HACD
|
||||||
|
|||||||
@@ -24,14 +24,14 @@
|
|||||||
|
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
class GraphVertex;
|
class GraphVertex;
|
||||||
class GraphEdge;
|
class GraphEdge;
|
||||||
class Graph;
|
class Graph;
|
||||||
class HACD;
|
class HACD;
|
||||||
|
|
||||||
class GraphVertex
|
class GraphVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool AddEdge(long name)
|
bool AddEdge(long name)
|
||||||
{
|
{
|
||||||
m_edges.insert(name);
|
m_edges.insert(name);
|
||||||
@@ -39,8 +39,9 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
bool DeleteEdge(long name);
|
bool DeleteEdge(long name);
|
||||||
GraphVertex();
|
GraphVertex();
|
||||||
~GraphVertex(){ delete m_convexHull;};
|
~GraphVertex() { delete m_convexHull; };
|
||||||
private:
|
|
||||||
|
private:
|
||||||
long m_name;
|
long m_name;
|
||||||
long m_cc;
|
long m_cc;
|
||||||
std::set<long> m_edges;
|
std::set<long> m_edges;
|
||||||
@@ -53,21 +54,21 @@ namespace HACD
|
|||||||
double m_volume;
|
double m_volume;
|
||||||
double m_perimeter;
|
double m_perimeter;
|
||||||
double m_concavity;
|
double m_concavity;
|
||||||
ICHull * m_convexHull;
|
ICHull* m_convexHull;
|
||||||
std::set<unsigned long long> m_boudaryEdges;
|
std::set<unsigned long long> m_boudaryEdges;
|
||||||
|
|
||||||
|
|
||||||
friend class GraphEdge;
|
friend class GraphEdge;
|
||||||
friend class Graph;
|
friend class Graph;
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GraphEdge
|
class GraphEdge
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GraphEdge();
|
GraphEdge();
|
||||||
~GraphEdge(){delete m_convexHull;};
|
~GraphEdge() { delete m_convexHull; };
|
||||||
private:
|
|
||||||
|
private:
|
||||||
long m_name;
|
long m_name;
|
||||||
long m_v1;
|
long m_v1;
|
||||||
long m_v2;
|
long m_v2;
|
||||||
@@ -77,22 +78,20 @@ namespace HACD
|
|||||||
double m_volume;
|
double m_volume;
|
||||||
double m_perimeter;
|
double m_perimeter;
|
||||||
double m_concavity;
|
double m_concavity;
|
||||||
ICHull * m_convexHull;
|
ICHull* m_convexHull;
|
||||||
std::set<unsigned long long> m_boudaryEdges;
|
std::set<unsigned long long> m_boudaryEdges;
|
||||||
bool m_deleted;
|
bool m_deleted;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
friend class GraphVertex;
|
friend class GraphVertex;
|
||||||
friend class Graph;
|
friend class Graph;
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Graph
|
class Graph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
size_t GetNEdges() const { return m_nE;}
|
size_t GetNEdges() const { return m_nE; }
|
||||||
size_t GetNVertices() const { return m_nV;}
|
size_t GetNVertices() const { return m_nV; }
|
||||||
bool EdgeCollapse(long v1, long v2);
|
bool EdgeCollapse(long v1, long v2);
|
||||||
long AddVertex();
|
long AddVertex();
|
||||||
long AddEdge(long v1, long v2);
|
long AddEdge(long v1, long v2);
|
||||||
@@ -107,7 +106,7 @@ namespace HACD
|
|||||||
virtual ~Graph();
|
virtual ~Graph();
|
||||||
void Allocate(size_t nV, size_t nE);
|
void Allocate(size_t nV, size_t nE);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t m_nCCs;
|
size_t m_nCCs;
|
||||||
size_t m_nV;
|
size_t m_nV;
|
||||||
size_t m_nE;
|
size_t m_nE;
|
||||||
@@ -115,6 +114,6 @@ namespace HACD
|
|||||||
std::vector<GraphVertex> m_vertices;
|
std::vector<GraphVertex> m_vertices;
|
||||||
|
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
}
|
} // namespace HACD
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,16 +26,16 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
bool gCancelRequest=false;
|
bool gCancelRequest = false;
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
double HACD::Concavity(ICHull & ch, std::map<long, DPoint> & distPoints)
|
double HACD::Concavity(ICHull& ch, std::map<long, DPoint>& distPoints)
|
||||||
{
|
{
|
||||||
double concavity = 0.0;
|
double concavity = 0.0;
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
std::map<long, DPoint>::iterator itDP(distPoints.begin());
|
std::map<long, DPoint>::iterator itDP(distPoints.begin());
|
||||||
std::map<long, DPoint>::iterator itDPEnd(distPoints.end());
|
std::map<long, DPoint>::iterator itDPEnd(distPoints.end());
|
||||||
for(; itDP != itDPEnd; ++itDP)
|
for (; itDP != itDPEnd; ++itDP)
|
||||||
{
|
{
|
||||||
if (!(itDP->second).m_computed)
|
if (!(itDP->second).m_computed)
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
distance = ch.ComputeDistance(itDP->first, m_facePoints[-itDP->first-1], m_faceNormals[-itDP->first-1], (itDP->second).m_computed, true);
|
distance = ch.ComputeDistance(itDP->first, m_facePoints[-itDP->first - 1], m_faceNormals[-itDP->first - 1], (itDP->second).m_computed, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -58,14 +58,14 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return concavity;
|
return concavity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HACD::CreateGraph()
|
void HACD::CreateGraph()
|
||||||
{
|
{
|
||||||
// vertex to triangle adjacency information
|
// vertex to triangle adjacency information
|
||||||
std::vector< std::set<long> > vertexToTriangles;
|
std::vector<std::set<long> > vertexToTriangles;
|
||||||
vertexToTriangles.resize(m_nPoints);
|
vertexToTriangles.resize(m_nPoints);
|
||||||
for(size_t t = 0; t < m_nTriangles; ++t)
|
for (size_t t = 0; t < m_nTriangles; ++t)
|
||||||
{
|
{
|
||||||
vertexToTriangles[m_triangles[t].X()].insert(static_cast<long>(t));
|
vertexToTriangles[m_triangles[t].X()].insert(static_cast<long>(t));
|
||||||
vertexToTriangles[m_triangles[t].Y()].insert(static_cast<long>(t));
|
vertexToTriangles[m_triangles[t].Y()].insert(static_cast<long>(t));
|
||||||
@@ -81,7 +81,7 @@ namespace HACD
|
|||||||
for (size_t v = 0; v < m_nPoints; v++)
|
for (size_t v = 0; v < m_nPoints; v++)
|
||||||
{
|
{
|
||||||
std::set<long>::const_iterator it1(vertexToTriangles[v].begin()), itEnd(vertexToTriangles[v].end());
|
std::set<long>::const_iterator it1(vertexToTriangles[v].begin()), itEnd(vertexToTriangles[v].end());
|
||||||
for(; it1 != itEnd; ++it1)
|
for (; it1 != itEnd; ++it1)
|
||||||
{
|
{
|
||||||
t1 = *it1;
|
t1 = *it1;
|
||||||
i1 = m_triangles[t1].X();
|
i1 = m_triangles[t1].X();
|
||||||
@@ -91,7 +91,7 @@ namespace HACD
|
|||||||
tr1[1] = GetEdgeIndex(j1, k1);
|
tr1[1] = GetEdgeIndex(j1, k1);
|
||||||
tr1[2] = GetEdgeIndex(k1, i1);
|
tr1[2] = GetEdgeIndex(k1, i1);
|
||||||
std::set<long>::const_iterator it2(it1);
|
std::set<long>::const_iterator it2(it1);
|
||||||
for(++it2; it2 != itEnd; ++it2)
|
for (++it2; it2 != itEnd; ++it2)
|
||||||
{
|
{
|
||||||
t2 = *it2;
|
t2 = *it2;
|
||||||
i2 = m_triangles[t2].X();
|
i2 = m_triangles[t2].X();
|
||||||
@@ -101,9 +101,9 @@ namespace HACD
|
|||||||
tr2[1] = GetEdgeIndex(j2, k2);
|
tr2[1] = GetEdgeIndex(j2, k2);
|
||||||
tr2[2] = GetEdgeIndex(k2, i2);
|
tr2[2] = GetEdgeIndex(k2, i2);
|
||||||
int shared = 0;
|
int shared = 0;
|
||||||
for(int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
for(int j = 0; j < 3; ++j)
|
for (int j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
if (tr1[i] == tr2[j])
|
if (tr1[i] == tr2[j])
|
||||||
{
|
{
|
||||||
@@ -123,10 +123,10 @@ namespace HACD
|
|||||||
m_graph.ExtractCCs();
|
m_graph.ExtractCCs();
|
||||||
if (m_graph.m_nCCs > 1)
|
if (m_graph.m_nCCs > 1)
|
||||||
{
|
{
|
||||||
std::vector< std::set<long> > cc2V;
|
std::vector<std::set<long> > cc2V;
|
||||||
cc2V.resize(m_graph.m_nCCs);
|
cc2V.resize(m_graph.m_nCCs);
|
||||||
long cc;
|
long cc;
|
||||||
for(size_t t = 0; t < m_nTriangles; ++t)
|
for (size_t t = 0; t < m_nTriangles; ++t)
|
||||||
{
|
{
|
||||||
cc = m_graph.m_vertices[t].m_cc;
|
cc = m_graph.m_vertices[t].m_cc;
|
||||||
cc2V[cc].insert(m_triangles[t].X());
|
cc2V[cc].insert(m_triangles[t].X());
|
||||||
@@ -134,19 +134,19 @@ namespace HACD
|
|||||||
cc2V[cc].insert(m_triangles[t].Z());
|
cc2V[cc].insert(m_triangles[t].Z());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1)
|
for (size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1)
|
||||||
{
|
{
|
||||||
for(size_t cc2 = cc1+1; cc2 < m_graph.m_nCCs; ++cc2)
|
for (size_t cc2 = cc1 + 1; cc2 < m_graph.m_nCCs; ++cc2)
|
||||||
{
|
{
|
||||||
std::set<long>::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end());
|
std::set<long>::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end());
|
||||||
for(; itV1 != itVEnd1; ++itV1)
|
for (; itV1 != itVEnd1; ++itV1)
|
||||||
{
|
{
|
||||||
double distC1C2 = std::numeric_limits<double>::max();
|
double distC1C2 = std::numeric_limits<double>::max();
|
||||||
double dist;
|
double dist;
|
||||||
t1 = -1;
|
t1 = -1;
|
||||||
t2 = -1;
|
t2 = -1;
|
||||||
std::set<long>::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end());
|
std::set<long>::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end());
|
||||||
for(; itV2 != itVEnd2; ++itV2)
|
for (; itV2 != itVEnd2; ++itV2)
|
||||||
{
|
{
|
||||||
dist = (m_points[*itV1] - m_points[*itV2]).GetNorm();
|
dist = (m_points[*itV1] - m_points[*itV2]).GetNorm();
|
||||||
if (dist < distC1C2)
|
if (dist < distC1C2)
|
||||||
@@ -157,7 +157,7 @@ namespace HACD
|
|||||||
std::set<long>::const_iterator it2(vertexToTriangles[*itV2].begin()),
|
std::set<long>::const_iterator it2(vertexToTriangles[*itV2].begin()),
|
||||||
it2End(vertexToTriangles[*itV2].end());
|
it2End(vertexToTriangles[*itV2].end());
|
||||||
t2 = -1;
|
t2 = -1;
|
||||||
for(; it2 != it2End; ++it2)
|
for (; it2 != it2End; ++it2)
|
||||||
{
|
{
|
||||||
if (*it2 != t1)
|
if (*it2 != t1)
|
||||||
{
|
{
|
||||||
@@ -169,7 +169,6 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
if (distC1C2 <= m_ccConnectDist && t1 > 0 && t2 > 0)
|
if (distC1C2 <= m_ccConnectDist && t1 > 0 && t2 > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_graph.AddEdge(t1, t2);
|
m_graph.AddEdge(t1, t2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,22 +176,22 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void HACD::InitializeDualGraph()
|
void HACD::InitializeDualGraph()
|
||||||
{
|
{
|
||||||
long i, j, k;
|
long i, j, k;
|
||||||
Vec3<Real> u, v, w, normal;
|
Vec3<Real> u, v, w, normal;
|
||||||
delete [] m_normals;
|
delete[] m_normals;
|
||||||
m_normals = new Vec3<Real>[m_nPoints];
|
m_normals = new Vec3<Real>[m_nPoints];
|
||||||
if (m_addFacesPoints)
|
if (m_addFacesPoints)
|
||||||
{
|
{
|
||||||
delete [] m_facePoints;
|
delete[] m_facePoints;
|
||||||
delete [] m_faceNormals;
|
delete[] m_faceNormals;
|
||||||
m_facePoints = new Vec3<Real>[m_nTriangles];
|
m_facePoints = new Vec3<Real>[m_nTriangles];
|
||||||
m_faceNormals = new Vec3<Real>[m_nTriangles];
|
m_faceNormals = new Vec3<Real>[m_nTriangles];
|
||||||
}
|
}
|
||||||
memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);
|
memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);
|
||||||
for(unsigned long f = 0; f < m_nTriangles; f++)
|
for (unsigned long f = 0; f < m_nTriangles; f++)
|
||||||
{
|
{
|
||||||
if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0);
|
if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0);
|
||||||
|
|
||||||
@@ -207,7 +206,7 @@ namespace HACD
|
|||||||
m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false;
|
m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false;
|
||||||
m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false;
|
m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false;
|
||||||
|
|
||||||
ICHull * ch = new ICHull;
|
ICHull* ch = new ICHull;
|
||||||
m_graph.m_vertices[f].m_convexHull = ch;
|
m_graph.m_vertices[f].m_convexHull = ch;
|
||||||
ch->AddPoint(m_points[i], i);
|
ch->AddPoint(m_points[i], i);
|
||||||
ch->AddPoint(m_points[j], j);
|
ch->AddPoint(m_points[j], j);
|
||||||
@@ -228,17 +227,17 @@ namespace HACD
|
|||||||
|
|
||||||
normal.Normalize();
|
normal.Normalize();
|
||||||
|
|
||||||
m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i,j));
|
m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i, j));
|
||||||
m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j,k));
|
m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j, k));
|
||||||
m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k,i));
|
m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k, i));
|
||||||
if(m_addFacesPoints)
|
if (m_addFacesPoints)
|
||||||
{
|
{
|
||||||
m_faceNormals[f] = normal;
|
m_faceNormals[f] = normal;
|
||||||
m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
|
m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
|
||||||
m_graph.m_vertices[f].m_distPoints[-static_cast<long>(f)-1].m_distOnly = true;
|
m_graph.m_vertices[f].m_distPoints[-static_cast<long>(f) - 1].m_distOnly = true;
|
||||||
}
|
}
|
||||||
if (m_addExtraDistPoints)
|
if (m_addExtraDistPoints)
|
||||||
{// we need a kd-tree structure to accelerate this part!
|
{ // we need a kd-tree structure to accelerate this part!
|
||||||
long i1, j1, k1;
|
long i1, j1, k1;
|
||||||
Vec3<Real> u1, v1, normal1;
|
Vec3<Real> u1, v1, normal1;
|
||||||
normal = -normal;
|
normal = -normal;
|
||||||
@@ -247,7 +246,7 @@ namespace HACD
|
|||||||
size_t faceIndex = m_nTriangles;
|
size_t faceIndex = m_nTriangles;
|
||||||
Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
|
Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
|
||||||
long nhit = 0;
|
long nhit = 0;
|
||||||
for(size_t f1 = 0; f1 < m_nTriangles; f1++)
|
for (size_t f1 = 0; f1 < m_nTriangles; f1++)
|
||||||
{
|
{
|
||||||
i1 = m_triangles[f1].X();
|
i1 = m_triangles[f1].X();
|
||||||
j1 = m_triangles[f1].Y();
|
j1 = m_triangles[f1].Y();
|
||||||
@@ -263,15 +262,14 @@ namespace HACD
|
|||||||
Vec3<double>(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()),
|
Vec3<double>(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()),
|
||||||
Vec3<double>(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()),
|
Vec3<double>(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()),
|
||||||
distance);
|
distance);
|
||||||
if ((nhit==1) && ((distMin > distance) || (faceIndex == m_nTriangles)))
|
if ((nhit == 1) && ((distMin > distance) || (faceIndex == m_nTriangles)))
|
||||||
{
|
{
|
||||||
distMin = distance;
|
distMin = distance;
|
||||||
faceIndex = f1;
|
faceIndex = f1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (faceIndex < m_nTriangles )
|
if (faceIndex < m_nTriangles)
|
||||||
{
|
{
|
||||||
i1 = m_triangles[faceIndex].X();
|
i1 = m_triangles[faceIndex].X();
|
||||||
j1 = m_triangles[faceIndex].Y();
|
j1 = m_triangles[faceIndex].Y();
|
||||||
@@ -281,7 +279,7 @@ namespace HACD
|
|||||||
m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true;
|
m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true;
|
||||||
if (m_addFacesPoints)
|
if (m_addFacesPoints)
|
||||||
{
|
{
|
||||||
m_graph.m_vertices[f].m_distPoints[-static_cast<long>(faceIndex)-1].m_distOnly = true;
|
m_graph.m_vertices[f].m_distPoints[-static_cast<long>(faceIndex) - 1].m_distOnly = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,10 +288,10 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
m_normals[v].Normalize();
|
m_normals[v].Normalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HACD::NormalizeData()
|
void HACD::NormalizeData()
|
||||||
{
|
{
|
||||||
if (m_nPoints == 0)
|
if (m_nPoints == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -302,32 +300,38 @@ namespace HACD
|
|||||||
Vec3<Real> min = m_points[0];
|
Vec3<Real> min = m_points[0];
|
||||||
Vec3<Real> max = m_points[0];
|
Vec3<Real> max = m_points[0];
|
||||||
Real x, y, z;
|
Real x, y, z;
|
||||||
for (size_t v = 1; v < m_nPoints ; v++)
|
for (size_t v = 1; v < m_nPoints; v++)
|
||||||
{
|
{
|
||||||
m_barycenter += m_points[v];
|
m_barycenter += m_points[v];
|
||||||
x = m_points[v].X();
|
x = m_points[v].X();
|
||||||
y = m_points[v].Y();
|
y = m_points[v].Y();
|
||||||
z = m_points[v].Z();
|
z = m_points[v].Z();
|
||||||
if ( x < min.X()) min.X() = x;
|
if (x < min.X())
|
||||||
else if ( x > max.X()) max.X() = x;
|
min.X() = x;
|
||||||
if ( y < min.Y()) min.Y() = y;
|
else if (x > max.X())
|
||||||
else if ( y > max.Y()) max.Y() = y;
|
max.X() = x;
|
||||||
if ( z < min.Z()) min.Z() = z;
|
if (y < min.Y())
|
||||||
else if ( z > max.Z()) max.Z() = z;
|
min.Y() = y;
|
||||||
|
else if (y > max.Y())
|
||||||
|
max.Y() = y;
|
||||||
|
if (z < min.Z())
|
||||||
|
min.Z() = z;
|
||||||
|
else if (z > max.Z())
|
||||||
|
max.Z() = z;
|
||||||
}
|
}
|
||||||
m_barycenter /= static_cast<Real>(m_nPoints);
|
m_barycenter /= static_cast<Real>(m_nPoints);
|
||||||
m_diag = (max-min).GetNorm();
|
m_diag = (max - min).GetNorm();
|
||||||
const Real invDiag = static_cast<Real>(2.0 * m_scale / m_diag);
|
const Real invDiag = static_cast<Real>(2.0 * m_scale / m_diag);
|
||||||
if (m_diag != 0.0)
|
if (m_diag != 0.0)
|
||||||
{
|
{
|
||||||
for (size_t v = 0; v < m_nPoints ; v++)
|
for (size_t v = 0; v < m_nPoints; v++)
|
||||||
{
|
{
|
||||||
m_points[v] = (m_points[v] - m_barycenter) * invDiag;
|
m_points[v] = (m_points[v] - m_barycenter) * invDiag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void HACD::DenormalizeData()
|
void HACD::DenormalizeData()
|
||||||
{
|
{
|
||||||
if (m_nPoints == 0)
|
if (m_nPoints == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -335,14 +339,14 @@ namespace HACD
|
|||||||
if (m_diag != 0.0)
|
if (m_diag != 0.0)
|
||||||
{
|
{
|
||||||
const Real diag = static_cast<Real>(m_diag / (2.0 * m_scale));
|
const Real diag = static_cast<Real>(m_diag / (2.0 * m_scale));
|
||||||
for (size_t v = 0; v < m_nPoints ; v++)
|
for (size_t v = 0; v < m_nPoints; v++)
|
||||||
{
|
{
|
||||||
m_points[v] = m_points[v] * diag + m_barycenter;
|
m_points[v] = m_points[v] * diag + m_barycenter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HACD::HACD(void)
|
HACD::HACD(void)
|
||||||
{
|
{
|
||||||
m_convexHulls = 0;
|
m_convexHulls = 0;
|
||||||
m_triangles = 0;
|
m_triangles = 0;
|
||||||
m_points = 0;
|
m_points = 0;
|
||||||
@@ -352,7 +356,7 @@ namespace HACD
|
|||||||
m_nClusters = 0;
|
m_nClusters = 0;
|
||||||
m_concavity = 0.0;
|
m_concavity = 0.0;
|
||||||
m_diag = 1.0;
|
m_diag = 1.0;
|
||||||
m_barycenter = Vec3<Real>(0.0, 0.0,0.0);
|
m_barycenter = Vec3<Real>(0.0, 0.0, 0.0);
|
||||||
m_alpha = 0.1;
|
m_alpha = 0.1;
|
||||||
m_beta = 0.1;
|
m_beta = 0.1;
|
||||||
m_nVerticesPerCH = 30;
|
m_nVerticesPerCH = 30;
|
||||||
@@ -365,36 +369,36 @@ namespace HACD
|
|||||||
m_facePoints = 0;
|
m_facePoints = 0;
|
||||||
m_faceNormals = 0;
|
m_faceNormals = 0;
|
||||||
m_ccConnectDist = 30;
|
m_ccConnectDist = 30;
|
||||||
}
|
}
|
||||||
HACD::~HACD(void)
|
HACD::~HACD(void)
|
||||||
{
|
{
|
||||||
delete [] m_normals;
|
delete[] m_normals;
|
||||||
delete [] m_convexHulls;
|
delete[] m_convexHulls;
|
||||||
delete [] m_partition;
|
delete[] m_partition;
|
||||||
delete [] m_facePoints;
|
delete[] m_facePoints;
|
||||||
delete [] m_faceNormals;
|
delete[] m_faceNormals;
|
||||||
}
|
}
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
void HACD::ComputeEdgeCost(size_t e)
|
void HACD::ComputeEdgeCost(size_t e)
|
||||||
{
|
{
|
||||||
GraphEdge & gE = m_graph.m_edges[e];
|
GraphEdge& gE = m_graph.m_edges[e];
|
||||||
long v1 = gE.m_v1;
|
long v1 = gE.m_v1;
|
||||||
long v2 = gE.m_v2;
|
long v2 = gE.m_v2;
|
||||||
|
|
||||||
if (m_graph.m_vertices[v2].m_distPoints.size()>m_graph.m_vertices[v1].m_distPoints.size())
|
if (m_graph.m_vertices[v2].m_distPoints.size() > m_graph.m_vertices[v1].m_distPoints.size())
|
||||||
{
|
{
|
||||||
gE.m_v1 = v2;
|
gE.m_v1 = v2;
|
||||||
gE.m_v2 = v1;
|
gE.m_v2 = v1;
|
||||||
//std::swap<long>(v1, v2);
|
//std::swap<long>(v1, v2);
|
||||||
std::swap(v1, v2);
|
std::swap(v1, v2);
|
||||||
}
|
}
|
||||||
GraphVertex & gV1 = m_graph.m_vertices[v1];
|
GraphVertex& gV1 = m_graph.m_vertices[v1];
|
||||||
GraphVertex & gV2 = m_graph.m_vertices[v2];
|
GraphVertex& gV2 = m_graph.m_vertices[v2];
|
||||||
|
|
||||||
// delete old convex-hull
|
// delete old convex-hull
|
||||||
delete gE.m_convexHull;
|
delete gE.m_convexHull;
|
||||||
// create the edge's convex-hull
|
// create the edge's convex-hull
|
||||||
ICHull * ch = new ICHull;
|
ICHull* ch = new ICHull;
|
||||||
gE.m_convexHull = ch;
|
gE.m_convexHull = ch;
|
||||||
(*ch) = (*gV1.m_convexHull);
|
(*ch) = (*gV1.m_convexHull);
|
||||||
|
|
||||||
@@ -404,20 +408,20 @@ namespace HACD
|
|||||||
std::map<long, DPoint>::iterator itDPEnd(gV2.m_distPoints.end());
|
std::map<long, DPoint>::iterator itDPEnd(gV2.m_distPoints.end());
|
||||||
std::map<long, DPoint>::iterator itDP1;
|
std::map<long, DPoint>::iterator itDP1;
|
||||||
|
|
||||||
for(; itDP != itDPEnd; ++itDP)
|
for (; itDP != itDPEnd; ++itDP)
|
||||||
{
|
{
|
||||||
itDP1 = gE.m_distPoints.find(itDP->first);
|
itDP1 = gE.m_distPoints.find(itDP->first);
|
||||||
if (itDP1 == gE.m_distPoints.end())
|
if (itDP1 == gE.m_distPoints.end())
|
||||||
{
|
{
|
||||||
gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly;
|
gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly;
|
||||||
if ( !(itDP->second).m_distOnly )
|
if (!(itDP->second).m_distOnly)
|
||||||
{
|
{
|
||||||
ch->AddPoint(m_points[itDP->first], itDP->first);
|
ch->AddPoint(m_points[itDP->first], itDP->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( (itDP1->second).m_distOnly && !(itDP->second).m_distOnly)
|
if ((itDP1->second).m_distOnly && !(itDP->second).m_distOnly)
|
||||||
{
|
{
|
||||||
gE.m_distPoints[itDP->first].m_distOnly = false;
|
gE.m_distPoints[itDP->first].m_distOnly = false;
|
||||||
ch->AddPoint(m_points[itDP->first], itDP->first);
|
ch->AddPoint(m_points[itDP->first], itDP->first);
|
||||||
@@ -429,16 +433,16 @@ namespace HACD
|
|||||||
// create the convex-hull
|
// create the convex-hull
|
||||||
while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!!
|
while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!!
|
||||||
{
|
{
|
||||||
// if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0);
|
// if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0);
|
||||||
ch = new ICHull;
|
ch = new ICHull;
|
||||||
CircularList<TMMVertex> & verticesCH = (gE.m_convexHull)->GetMesh().m_vertices;
|
CircularList<TMMVertex>& verticesCH = (gE.m_convexHull)->GetMesh().m_vertices;
|
||||||
size_t nV = verticesCH.GetSize();
|
size_t nV = verticesCH.GetSize();
|
||||||
long ptIndex = 0;
|
long ptIndex = 0;
|
||||||
verticesCH.Next();
|
verticesCH.Next();
|
||||||
for(size_t v = 1; v < nV; ++v)
|
for (size_t v = 1; v < nV; ++v)
|
||||||
{
|
{
|
||||||
ptIndex = verticesCH.GetHead()->GetData().m_name;
|
ptIndex = verticesCH.GetHead()->GetData().m_name;
|
||||||
if (ptIndex != ICHull::sc_dummyIndex/* && ptIndex < m_nPoints*/)
|
if (ptIndex != ICHull::sc_dummyIndex /* && ptIndex < m_nPoints*/)
|
||||||
ch->AddPoint(m_points[ptIndex], ptIndex);
|
ch->AddPoint(m_points[ptIndex], ptIndex);
|
||||||
verticesCH.Next();
|
verticesCH.Next();
|
||||||
}
|
}
|
||||||
@@ -452,7 +456,7 @@ namespace HACD
|
|||||||
bool insideHull;
|
bool insideHull;
|
||||||
std::map<long, DPoint>::iterator itDP(gE.m_distPoints.begin());
|
std::map<long, DPoint>::iterator itDP(gE.m_distPoints.begin());
|
||||||
std::map<long, DPoint>::iterator itDPEnd(gE.m_distPoints.end());
|
std::map<long, DPoint>::iterator itDPEnd(gE.m_distPoints.end());
|
||||||
for(; itDP != itDPEnd; ++itDP)
|
for (; itDP != itDPEnd; ++itDP)
|
||||||
{
|
{
|
||||||
if (itDP->first >= 0)
|
if (itDP->first >= 0)
|
||||||
{
|
{
|
||||||
@@ -469,20 +473,20 @@ namespace HACD
|
|||||||
gV1.m_edges.end(),
|
gV1.m_edges.end(),
|
||||||
gV2.m_edges.begin(),
|
gV2.m_edges.begin(),
|
||||||
gV2.m_edges.end(),
|
gV2.m_edges.end(),
|
||||||
std::inserter( eEdges, eEdges.begin() ) );
|
std::inserter(eEdges, eEdges.begin()));
|
||||||
|
|
||||||
std::set<long>::const_iterator ed(eEdges.begin());
|
std::set<long>::const_iterator ed(eEdges.begin());
|
||||||
std::set<long>::const_iterator itEnd(eEdges.end());
|
std::set<long>::const_iterator itEnd(eEdges.end());
|
||||||
long a, b, c;
|
long a, b, c;
|
||||||
for(; ed != itEnd; ++ed)
|
for (; ed != itEnd; ++ed)
|
||||||
{
|
{
|
||||||
a = m_graph.m_edges[*ed].m_v1;
|
a = m_graph.m_edges[*ed].m_v1;
|
||||||
b = m_graph.m_edges[*ed].m_v2;
|
b = m_graph.m_edges[*ed].m_v2;
|
||||||
if ( a != v2 && a != v1)
|
if (a != v2 && a != v1)
|
||||||
{
|
{
|
||||||
c = a;
|
c = a;
|
||||||
}
|
}
|
||||||
else if ( b != v2 && b != v1)
|
else if (b != v2 && b != v1)
|
||||||
{
|
{
|
||||||
c = b;
|
c = b;
|
||||||
}
|
}
|
||||||
@@ -490,13 +494,13 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
c = -1;
|
c = -1;
|
||||||
}
|
}
|
||||||
if ( c > 0)
|
if (c > 0)
|
||||||
{
|
{
|
||||||
GraphVertex & gVC = m_graph.m_vertices[c];
|
GraphVertex& gVC = m_graph.m_vertices[c];
|
||||||
std::map<long, DPoint>::iterator itDP(gVC.m_distPoints.begin());
|
std::map<long, DPoint>::iterator itDP(gVC.m_distPoints.begin());
|
||||||
std::map<long, DPoint>::iterator itDPEnd(gVC.m_distPoints.end());
|
std::map<long, DPoint>::iterator itDPEnd(gVC.m_distPoints.end());
|
||||||
std::map<long, DPoint>::iterator itDP1;
|
std::map<long, DPoint>::iterator itDP1;
|
||||||
for(; itDP != itDPEnd; ++itDP)
|
for (; itDP != itDPEnd; ++itDP)
|
||||||
{
|
{
|
||||||
itDP1 = gE.m_distPoints.find(itDP->first);
|
itDP1 = gE.m_distPoints.find(itDP->first);
|
||||||
if (itDP1 == gE.m_distPoints.end())
|
if (itDP1 == gE.m_distPoints.end())
|
||||||
@@ -505,7 +509,7 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
gE.m_distPoints[itDP->first].m_distOnly = true;
|
gE.m_distPoints[itDP->first].m_distOnly = true;
|
||||||
}
|
}
|
||||||
else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first-1]))
|
else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first - 1]))
|
||||||
{
|
{
|
||||||
gE.m_distPoints[itDP->first].m_distOnly = true;
|
gE.m_distPoints[itDP->first].m_distOnly = true;
|
||||||
}
|
}
|
||||||
@@ -523,41 +527,42 @@ namespace HACD
|
|||||||
if (m_alpha > 0.0)
|
if (m_alpha > 0.0)
|
||||||
{
|
{
|
||||||
gE.m_boudaryEdges.clear();
|
gE.m_boudaryEdges.clear();
|
||||||
std::set_symmetric_difference (gV1.m_boudaryEdges.begin(),
|
std::set_symmetric_difference(gV1.m_boudaryEdges.begin(),
|
||||||
gV1.m_boudaryEdges.end(),
|
gV1.m_boudaryEdges.end(),
|
||||||
gV2.m_boudaryEdges.begin(),
|
gV2.m_boudaryEdges.begin(),
|
||||||
gV2.m_boudaryEdges.end(),
|
gV2.m_boudaryEdges.end(),
|
||||||
std::inserter( gE.m_boudaryEdges,
|
std::inserter(gE.m_boudaryEdges,
|
||||||
gE.m_boudaryEdges.begin() ) );
|
gE.m_boudaryEdges.begin()));
|
||||||
|
|
||||||
std::set<unsigned long long>::const_iterator itBE(gE.m_boudaryEdges.begin());
|
std::set<unsigned long long>::const_iterator itBE(gE.m_boudaryEdges.begin());
|
||||||
std::set<unsigned long long>::const_iterator itBEEnd(gE.m_boudaryEdges.end());
|
std::set<unsigned long long>::const_iterator itBEEnd(gE.m_boudaryEdges.end());
|
||||||
for(; itBE != itBEEnd; ++itBE)
|
for (; itBE != itBEEnd; ++itBE)
|
||||||
{
|
{
|
||||||
perimeter += (m_points[static_cast<long>((*itBE) >> 32)] -
|
perimeter += (m_points[static_cast<long>((*itBE) >> 32)] -
|
||||||
m_points[static_cast<long>((*itBE) & 0xFFFFFFFFULL)]).GetNorm();
|
m_points[static_cast<long>((*itBE) & 0xFFFFFFFFULL)])
|
||||||
|
.GetNorm();
|
||||||
}
|
}
|
||||||
surf = gV1.m_surf + gV2.m_surf;
|
surf = gV1.m_surf + gV2.m_surf;
|
||||||
}
|
}
|
||||||
double ratio = perimeter * perimeter / (4.0 * sc_pi * surf);
|
double ratio = perimeter * perimeter / (4.0 * sc_pi * surf);
|
||||||
gE.m_volume = (m_beta == 0.0)?0.0:ch->ComputeVolume()/pow(m_scale, 3.0); // cluster's volume
|
gE.m_volume = (m_beta == 0.0) ? 0.0 : ch->ComputeVolume() / pow(m_scale, 3.0); // cluster's volume
|
||||||
gE.m_surf = surf; // cluster's area
|
gE.m_surf = surf; // cluster's area
|
||||||
gE.m_perimeter = perimeter; // cluster's perimeter
|
gE.m_perimeter = perimeter; // cluster's perimeter
|
||||||
gE.m_concavity = concavity; // cluster's concavity
|
gE.m_concavity = concavity; // cluster's concavity
|
||||||
gE.m_error = static_cast<Real>(concavity + m_alpha * ratio + m_beta * volume); // cluster's priority
|
gE.m_error = static_cast<Real>(concavity + m_alpha * ratio + m_beta * volume); // cluster's priority
|
||||||
}
|
}
|
||||||
bool HACD::InitializePriorityQueue()
|
bool HACD::InitializePriorityQueue()
|
||||||
{
|
{
|
||||||
m_pqueue.reserve(m_graph.m_nE + 100);
|
m_pqueue.reserve(m_graph.m_nE + 100);
|
||||||
for (size_t e=0; e < m_graph.m_nE; ++e)
|
for (size_t e = 0; e < m_graph.m_nE; ++e)
|
||||||
{
|
{
|
||||||
ComputeEdgeCost(static_cast<long>(e));
|
ComputeEdgeCost(static_cast<long>(e));
|
||||||
m_pqueue.push(GraphEdgePriorityQueue(static_cast<long>(e), m_graph.m_edges[e].m_error));
|
m_pqueue.push(GraphEdgePriorityQueue(static_cast<long>(e), m_graph.m_edges[e].m_error));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void HACD::Simplify()
|
void HACD::Simplify()
|
||||||
{
|
{
|
||||||
long v1 = -1;
|
long v1 = -1;
|
||||||
long v2 = -1;
|
long v2 = -1;
|
||||||
double progressOld = -1.0;
|
double progressOld = -1.0;
|
||||||
@@ -565,12 +570,12 @@ namespace HACD
|
|||||||
double globalConcavity = 0.0;
|
double globalConcavity = 0.0;
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
double ptgStep = 1.0;
|
double ptgStep = 1.0;
|
||||||
while ( (globalConcavity < m_concavity) &&
|
while ((globalConcavity < m_concavity) &&
|
||||||
(m_graph.GetNVertices() > m_nMinClusters) &&
|
(m_graph.GetNVertices() > m_nMinClusters) &&
|
||||||
(m_graph.GetNEdges() > 0))
|
(m_graph.GetNEdges() > 0))
|
||||||
{
|
{
|
||||||
progress = 100.0-m_graph.GetNVertices() * 100.0 / m_nTriangles;
|
progress = 100.0 - m_graph.GetNVertices() * 100.0 / m_nTriangles;
|
||||||
if (fabs(progress-progressOld) > ptgStep && m_callBack)
|
if (fabs(progress - progressOld) > ptgStep && m_callBack)
|
||||||
{
|
{
|
||||||
sprintf(msg, "%3.2f %% V = %lu \t C = %f \t \t \r", progress, static_cast<unsigned long>(m_graph.GetNVertices()), globalConcavity);
|
sprintf(msg, "%3.2f %% V = %lu \t C = %f \t \t \r", progress, static_cast<unsigned long>(m_graph.GetNVertices()), globalConcavity);
|
||||||
(*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices());
|
(*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices());
|
||||||
@@ -585,7 +590,7 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphEdgePriorityQueue currentEdge(0,0.0);
|
GraphEdgePriorityQueue currentEdge(0, 0.0);
|
||||||
bool done = false;
|
bool done = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -597,14 +602,12 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
currentEdge = m_pqueue.top();
|
currentEdge = m_pqueue.top();
|
||||||
m_pqueue.pop();
|
m_pqueue.pop();
|
||||||
}
|
} while (m_graph.m_edges[currentEdge.m_name].m_deleted ||
|
||||||
while ( m_graph.m_edges[currentEdge.m_name].m_deleted ||
|
|
||||||
m_graph.m_edges[currentEdge.m_name].m_error != currentEdge.m_priority);
|
m_graph.m_edges[currentEdge.m_name].m_error != currentEdge.m_priority);
|
||||||
|
|
||||||
|
|
||||||
if (m_graph.m_edges[currentEdge.m_name].m_concavity < m_concavity && !done)
|
if (m_graph.m_edges[currentEdge.m_name].m_concavity < m_concavity && !done)
|
||||||
{
|
{
|
||||||
globalConcavity = std::max<double>(globalConcavity ,m_graph.m_edges[currentEdge.m_name].m_concavity);
|
globalConcavity = std::max<double>(globalConcavity, m_graph.m_edges[currentEdge.m_name].m_concavity);
|
||||||
v1 = m_graph.m_edges[currentEdge.m_name].m_v1;
|
v1 = m_graph.m_edges[currentEdge.m_name].m_v1;
|
||||||
v2 = m_graph.m_edges[currentEdge.m_name].m_v2;
|
v2 = m_graph.m_edges[currentEdge.m_name].m_v2;
|
||||||
// update vertex info
|
// update vertex info
|
||||||
@@ -619,12 +622,12 @@ namespace HACD
|
|||||||
m_graph.m_vertices[v1].m_boudaryEdges = m_graph.m_edges[currentEdge.m_name].m_boudaryEdges;
|
m_graph.m_vertices[v1].m_boudaryEdges = m_graph.m_edges[currentEdge.m_name].m_boudaryEdges;
|
||||||
|
|
||||||
// We apply the optimal ecol
|
// We apply the optimal ecol
|
||||||
// std::cout << "v1 " << v1 << " v2 " << v2 << std::endl;
|
// std::cout << "v1 " << v1 << " v2 " << v2 << std::endl;
|
||||||
m_graph.EdgeCollapse(v1, v2);
|
m_graph.EdgeCollapse(v1, v2);
|
||||||
// recompute the adjacent edges costs
|
// recompute the adjacent edges costs
|
||||||
std::set<long>::const_iterator itE(m_graph.m_vertices[v1].m_edges.begin()),
|
std::set<long>::const_iterator itE(m_graph.m_vertices[v1].m_edges.begin()),
|
||||||
itEEnd(m_graph.m_vertices[v1].m_edges.end());
|
itEEnd(m_graph.m_vertices[v1].m_edges.end());
|
||||||
for(; itE != itEEnd; ++itE)
|
for (; itE != itEEnd; ++itE)
|
||||||
{
|
{
|
||||||
size_t e = *itE;
|
size_t e = *itE;
|
||||||
ComputeEdgeCost(static_cast<long>(e));
|
ComputeEdgeCost(static_cast<long>(e));
|
||||||
@@ -644,7 +647,7 @@ namespace HACD
|
|||||||
m_cVertices.clear();
|
m_cVertices.clear();
|
||||||
m_nClusters = m_graph.GetNVertices();
|
m_nClusters = m_graph.GetNVertices();
|
||||||
m_cVertices.reserve(m_nClusters);
|
m_cVertices.reserve(m_nClusters);
|
||||||
for (size_t p=0, v = 0; v != m_graph.m_vertices.size(); ++v)
|
for (size_t p = 0, v = 0; v != m_graph.m_vertices.size(); ++v)
|
||||||
{
|
{
|
||||||
if (!m_graph.m_vertices[v].m_deleted)
|
if (!m_graph.m_vertices[v].m_deleted)
|
||||||
{
|
{
|
||||||
@@ -663,14 +666,13 @@ namespace HACD
|
|||||||
sprintf(msg, "# clusters = %lu \t C = %f\n", static_cast<unsigned long>(m_nClusters), globalConcavity);
|
sprintf(msg, "# clusters = %lu \t C = %f\n", static_cast<unsigned long>(m_nClusters), globalConcavity);
|
||||||
(*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices());
|
(*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
bool HACD::Compute(bool fullCH, bool exportDistPoints)
|
||||||
|
{
|
||||||
bool HACD::Compute(bool fullCH, bool exportDistPoints)
|
|
||||||
{
|
|
||||||
gCancelRequest = false;
|
gCancelRequest = false;
|
||||||
|
|
||||||
if ( !m_points || !m_triangles || !m_nPoints || !m_nTriangles)
|
if (!m_points || !m_triangles || !m_nPoints || !m_nTriangles)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -716,23 +718,23 @@ namespace HACD
|
|||||||
if (m_callBack) (*m_callBack)("+ Denormalizing Data\n", 0.0, 0.0, m_nClusters);
|
if (m_callBack) (*m_callBack)("+ Denormalizing Data\n", 0.0, 0.0, m_nClusters);
|
||||||
DenormalizeData();
|
DenormalizeData();
|
||||||
if (m_callBack) (*m_callBack)("+ Computing final convex-hulls\n", 0.0, 0.0, m_nClusters);
|
if (m_callBack) (*m_callBack)("+ Computing final convex-hulls\n", 0.0, 0.0, m_nClusters);
|
||||||
delete [] m_convexHulls;
|
delete[] m_convexHulls;
|
||||||
m_convexHulls = new ICHull[m_nClusters];
|
m_convexHulls = new ICHull[m_nClusters];
|
||||||
delete [] m_partition;
|
delete[] m_partition;
|
||||||
m_partition = new long [m_nTriangles];
|
m_partition = new long[m_nTriangles];
|
||||||
for (size_t p = 0; p != m_cVertices.size(); ++p)
|
for (size_t p = 0; p != m_cVertices.size(); ++p)
|
||||||
{
|
{
|
||||||
size_t v = m_cVertices[p];
|
size_t v = m_cVertices[p];
|
||||||
m_partition[v] = static_cast<long>(p);
|
m_partition[v] = static_cast<long>(p);
|
||||||
for(size_t a = 0; a < m_graph.m_vertices[v].m_ancestors.size(); a++)
|
for (size_t a = 0; a < m_graph.m_vertices[v].m_ancestors.size(); a++)
|
||||||
{
|
{
|
||||||
m_partition[m_graph.m_vertices[v].m_ancestors[a]] = static_cast<long>(p);
|
m_partition[m_graph.m_vertices[v].m_ancestors[a]] = static_cast<long>(p);
|
||||||
}
|
}
|
||||||
// compute the convex-hull
|
// compute the convex-hull
|
||||||
const std::map<long, DPoint> & pointsCH = m_graph.m_vertices[v].m_distPoints;
|
const std::map<long, DPoint>& pointsCH = m_graph.m_vertices[v].m_distPoints;
|
||||||
std::map<long, DPoint>::const_iterator itCH(pointsCH.begin());
|
std::map<long, DPoint>::const_iterator itCH(pointsCH.begin());
|
||||||
std::map<long, DPoint>::const_iterator itCHEnd(pointsCH.end());
|
std::map<long, DPoint>::const_iterator itCHEnd(pointsCH.end());
|
||||||
for(; itCH != itCHEnd; ++itCH)
|
for (; itCH != itCHEnd; ++itCH)
|
||||||
{
|
{
|
||||||
if (!(itCH->second).m_distOnly)
|
if (!(itCH->second).m_distOnly)
|
||||||
{
|
{
|
||||||
@@ -751,7 +753,7 @@ namespace HACD
|
|||||||
if (exportDistPoints)
|
if (exportDistPoints)
|
||||||
{
|
{
|
||||||
itCH = pointsCH.begin();
|
itCH = pointsCH.begin();
|
||||||
for(; itCH != itCHEnd; ++itCH)
|
for (; itCH != itCHEnd; ++itCH)
|
||||||
{
|
{
|
||||||
if ((itCH->second).m_distOnly)
|
if ((itCH->second).m_distOnly)
|
||||||
{
|
{
|
||||||
@@ -761,44 +763,44 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_convexHulls[p].AddPoint(m_facePoints[-itCH->first-1], itCH->first);
|
m_convexHulls[p].AddPoint(m_facePoints[-itCH->first - 1], itCH->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HACD::GetNTrianglesCH(size_t numCH) const
|
size_t HACD::GetNTrianglesCH(size_t numCH) const
|
||||||
{
|
{
|
||||||
if (numCH >= m_nClusters)
|
if (numCH >= m_nClusters)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return m_convexHulls[numCH].GetMesh().GetNTriangles();
|
return m_convexHulls[numCH].GetMesh().GetNTriangles();
|
||||||
}
|
}
|
||||||
size_t HACD::GetNPointsCH(size_t numCH) const
|
size_t HACD::GetNPointsCH(size_t numCH) const
|
||||||
{
|
{
|
||||||
if (numCH >= m_nClusters)
|
if (numCH >= m_nClusters)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return m_convexHulls[numCH].GetMesh().GetNVertices();
|
return m_convexHulls[numCH].GetMesh().GetNVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HACD::GetCH(size_t numCH, Vec3<Real> * const points, Vec3<long> * const triangles)
|
bool HACD::GetCH(size_t numCH, Vec3<Real>* const points, Vec3<long>* const triangles)
|
||||||
{
|
{
|
||||||
if (numCH >= m_nClusters)
|
if (numCH >= m_nClusters)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_convexHulls[numCH].GetMesh().GetIFS(points, triangles);
|
m_convexHulls[numCH].GetMesh().GetIFS(points, triangles);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HACD::Save(const char * fileName, bool uniColor, long numCluster) const
|
bool HACD::Save(const char* fileName, bool uniColor, long numCluster) const
|
||||||
{
|
{
|
||||||
std::ofstream fout(fileName);
|
std::ofstream fout(fileName);
|
||||||
if (fout.is_open())
|
if (fout.is_open())
|
||||||
{
|
{
|
||||||
@@ -818,11 +820,11 @@ namespace HACD
|
|||||||
mat.m_diffuseColor.X() = mat.m_diffuseColor.Y() = mat.m_diffuseColor.Z() = 0.0;
|
mat.m_diffuseColor.X() = mat.m_diffuseColor.Y() = mat.m_diffuseColor.Z() = 0.0;
|
||||||
while (mat.m_diffuseColor.X() == mat.m_diffuseColor.Y() ||
|
while (mat.m_diffuseColor.X() == mat.m_diffuseColor.Y() ||
|
||||||
mat.m_diffuseColor.Z() == mat.m_diffuseColor.Y() ||
|
mat.m_diffuseColor.Z() == mat.m_diffuseColor.Y() ||
|
||||||
mat.m_diffuseColor.Z() == mat.m_diffuseColor.X() )
|
mat.m_diffuseColor.Z() == mat.m_diffuseColor.X())
|
||||||
{
|
{
|
||||||
mat.m_diffuseColor.X() = (rand()%100) / 100.0;
|
mat.m_diffuseColor.X() = (rand() % 100) / 100.0;
|
||||||
mat.m_diffuseColor.Y() = (rand()%100) / 100.0;
|
mat.m_diffuseColor.Y() = (rand() % 100) / 100.0;
|
||||||
mat.m_diffuseColor.Z() = (rand()%100) / 100.0;
|
mat.m_diffuseColor.Z() = (rand() % 100) / 100.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_convexHulls[p].GetMesh().SaveVRML2(fout, mat);
|
m_convexHulls[p].GetMesh().SaveVRML2(fout, mat);
|
||||||
@@ -845,7 +847,5 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace HACD
|
||||||
|
|
||||||
|
|||||||
@@ -26,25 +26,26 @@
|
|||||||
|
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
const double sc_pi = 3.14159265;
|
const double sc_pi = 3.14159265;
|
||||||
class HACD;
|
class HACD;
|
||||||
|
|
||||||
// just to be able to set the capcity of the container
|
// just to be able to set the capcity of the container
|
||||||
|
|
||||||
template<class _Ty, class _Container = std::vector<_Ty>, class _Pr = std::less<typename _Container::value_type> >
|
template <class _Ty, class _Container = std::vector<_Ty>, class _Pr = std::less<typename _Container::value_type> >
|
||||||
class reservable_priority_queue: public std::priority_queue<_Ty, _Container, _Pr>
|
class reservable_priority_queue : public std::priority_queue<_Ty, _Container, _Pr>
|
||||||
{
|
{
|
||||||
typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type;
|
typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
reservable_priority_queue(size_type capacity = 0) { reserve(capacity); };
|
reservable_priority_queue(size_type capacity = 0) { reserve(capacity); };
|
||||||
void reserve(size_type capacity) { this->c.reserve(capacity); }
|
void reserve(size_type capacity) { this->c.reserve(capacity); }
|
||||||
size_type capacity() const { return this->c.capacity(); }
|
size_type capacity() const { return this->c.capacity(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//! priority queque element
|
//! priority queque element
|
||||||
class GraphEdgePriorityQueue
|
class GraphEdgePriorityQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
//! @param name edge's id
|
//! @param name edge's id
|
||||||
//! @param priority edge's priority
|
//! @param priority edge's priority
|
||||||
@@ -54,125 +55,125 @@ namespace HACD
|
|||||||
m_priority = priority;
|
m_priority = priority;
|
||||||
}
|
}
|
||||||
//! Destructor
|
//! Destructor
|
||||||
~GraphEdgePriorityQueue(void){}
|
~GraphEdgePriorityQueue(void) {}
|
||||||
private:
|
|
||||||
|
private:
|
||||||
long m_name; //!< edge name
|
long m_name; //!< edge name
|
||||||
Real m_priority; //!< priority
|
Real m_priority; //!< priority
|
||||||
//! Operator < for GraphEdgePQ
|
//! Operator < for GraphEdgePQ
|
||||||
friend bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs);
|
friend bool operator<(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs);
|
||||||
//! Operator > for GraphEdgePQ
|
//! Operator > for GraphEdgePQ
|
||||||
friend bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs);
|
friend bool operator>(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs);
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
inline bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs)
|
inline bool operator<(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs)
|
||||||
{
|
{
|
||||||
return lhs.m_priority<rhs.m_priority;
|
return lhs.m_priority < rhs.m_priority;
|
||||||
}
|
}
|
||||||
inline bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs)
|
inline bool operator>(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs)
|
||||||
{
|
{
|
||||||
return lhs.m_priority>rhs.m_priority;
|
return lhs.m_priority > rhs.m_priority;
|
||||||
}
|
}
|
||||||
typedef bool (*CallBackFunction)(const char *, double, double, size_t);
|
typedef bool (*CallBackFunction)(const char *, double, double, size_t);
|
||||||
|
|
||||||
//! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf
|
|
||||||
class HACD
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
//! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf
|
||||||
|
class HACD
|
||||||
|
{
|
||||||
|
public:
|
||||||
//! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
|
//! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
|
||||||
//! @return triangles partition
|
//! @return triangles partition
|
||||||
const long * GetPartition() const { return m_partition;}
|
const long *GetPartition() const { return m_partition; }
|
||||||
//! Sets the scale factor
|
//! Sets the scale factor
|
||||||
//! @param scale scale factor
|
//! @param scale scale factor
|
||||||
void SetScaleFactor(double scale) { m_scale = scale;}
|
void SetScaleFactor(double scale) { m_scale = scale; }
|
||||||
//! Gives the scale factor
|
//! Gives the scale factor
|
||||||
//! @return scale factor
|
//! @return scale factor
|
||||||
double GetScaleFactor() const { return m_scale;}
|
double GetScaleFactor() const { return m_scale; }
|
||||||
//! Sets the call-back function
|
//! Sets the call-back function
|
||||||
//! @param callBack pointer to the call-back function
|
//! @param callBack pointer to the call-back function
|
||||||
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;}
|
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack; }
|
||||||
//! Gives the call-back function
|
//! Gives the call-back function
|
||||||
//! @return pointer to the call-back function
|
//! @return pointer to the call-back function
|
||||||
CallBackFunction GetCallBack() const { return m_callBack;}
|
CallBackFunction GetCallBack() const { return m_callBack; }
|
||||||
|
|
||||||
//! Specifies whether faces points should be added when computing the concavity
|
//! Specifies whether faces points should be added when computing the concavity
|
||||||
//! @param addFacesPoints true = faces points should be added
|
//! @param addFacesPoints true = faces points should be added
|
||||||
void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints;}
|
void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints; }
|
||||||
//! Specifies wheter faces points should be added when computing the concavity
|
//! Specifies wheter faces points should be added when computing the concavity
|
||||||
//! @return true = faces points should be added
|
//! @return true = faces points should be added
|
||||||
bool GetAddFacesPoints() const { return m_addFacesPoints;}
|
bool GetAddFacesPoints() const { return m_addFacesPoints; }
|
||||||
//! Specifies whether extra points should be added when computing the concavity
|
//! Specifies whether extra points should be added when computing the concavity
|
||||||
//! @param addExteraDistPoints true = extra points should be added
|
//! @param addExteraDistPoints true = extra points should be added
|
||||||
void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints;}
|
void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints; }
|
||||||
//! Specifies wheter extra points should be added when computing the concavity
|
//! Specifies wheter extra points should be added when computing the concavity
|
||||||
//! @return true = extra points should be added
|
//! @return true = extra points should be added
|
||||||
bool GetAddExtraDistPoints() const { return m_addExtraDistPoints;}
|
bool GetAddExtraDistPoints() const { return m_addExtraDistPoints; }
|
||||||
//! Specifies whether extra points should be added when computing the concavity
|
//! Specifies whether extra points should be added when computing the concavity
|
||||||
//! @param addExteraDistPoints true = extra points should be added
|
//! @param addExteraDistPoints true = extra points should be added
|
||||||
void SetAddNeighboursDistPoints(bool addNeighboursDistPoints) { m_addNeighboursDistPoints = addNeighboursDistPoints;}
|
void SetAddNeighboursDistPoints(bool addNeighboursDistPoints) { m_addNeighboursDistPoints = addNeighboursDistPoints; }
|
||||||
//! Specifies wheter extra points should be added when computing the concavity
|
//! Specifies wheter extra points should be added when computing the concavity
|
||||||
//! @return true = extra points should be added
|
//! @return true = extra points should be added
|
||||||
bool GetAddNeighboursDistPoints() const { return m_addNeighboursDistPoints;}
|
bool GetAddNeighboursDistPoints() const { return m_addNeighboursDistPoints; }
|
||||||
//! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
|
//! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
|
||||||
//! @param points pointer to the input points
|
//! @param points pointer to the input points
|
||||||
void SetPoints(Vec3<Real> * points) { m_points = points;}
|
void SetPoints(Vec3<Real> *points) { m_points = points; }
|
||||||
//! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
|
//! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
|
||||||
//! @return pointer to the input points
|
//! @return pointer to the input points
|
||||||
const Vec3<Real> * GetPoints() const { return m_points;}
|
const Vec3<Real> *GetPoints() const { return m_points; }
|
||||||
//! Sets the triangles of the input mesh.
|
//! Sets the triangles of the input mesh.
|
||||||
//! @param triangles points pointer to the input points
|
//! @param triangles points pointer to the input points
|
||||||
void SetTriangles(Vec3<long> * triangles) { m_triangles = triangles;}
|
void SetTriangles(Vec3<long> *triangles) { m_triangles = triangles; }
|
||||||
//! Gives the triangles in the input mesh
|
//! Gives the triangles in the input mesh
|
||||||
//! @return pointer to the input triangles
|
//! @return pointer to the input triangles
|
||||||
const Vec3<long> * GetTriangles() const { return m_triangles;}
|
const Vec3<long> *GetTriangles() const { return m_triangles; }
|
||||||
//! Sets the number of points in the input mesh.
|
//! Sets the number of points in the input mesh.
|
||||||
//! @param nPoints number of points the input mesh
|
//! @param nPoints number of points the input mesh
|
||||||
void SetNPoints(size_t nPoints) { m_nPoints = nPoints;}
|
void SetNPoints(size_t nPoints) { m_nPoints = nPoints; }
|
||||||
//! Gives the number of points in the input mesh.
|
//! Gives the number of points in the input mesh.
|
||||||
//! @return number of points the input mesh
|
//! @return number of points the input mesh
|
||||||
size_t GetNPoints() const { return m_nPoints;}
|
size_t GetNPoints() const { return m_nPoints; }
|
||||||
//! Sets the number of triangles in the input mesh.
|
//! Sets the number of triangles in the input mesh.
|
||||||
//! @param nTriangles number of triangles in the input mesh
|
//! @param nTriangles number of triangles in the input mesh
|
||||||
void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles;}
|
void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles; }
|
||||||
//! Gives the number of triangles in the input mesh.
|
//! Gives the number of triangles in the input mesh.
|
||||||
//! @return number of triangles the input mesh
|
//! @return number of triangles the input mesh
|
||||||
size_t GetNTriangles() const { return m_nTriangles;}
|
size_t GetNTriangles() const { return m_nTriangles; }
|
||||||
//! Sets the minimum number of clusters to be generated.
|
//! Sets the minimum number of clusters to be generated.
|
||||||
//! @param nClusters minimum number of clusters
|
//! @param nClusters minimum number of clusters
|
||||||
void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters;}
|
void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters; }
|
||||||
//! Gives the number of generated clusters.
|
//! Gives the number of generated clusters.
|
||||||
//! @return number of generated clusters
|
//! @return number of generated clusters
|
||||||
size_t GetNClusters() const { return m_nClusters;}
|
size_t GetNClusters() const { return m_nClusters; }
|
||||||
//! Sets the maximum allowed concavity.
|
//! Sets the maximum allowed concavity.
|
||||||
//! @param concavity maximum concavity
|
//! @param concavity maximum concavity
|
||||||
void SetConcavity(double concavity) { m_concavity = concavity;}
|
void SetConcavity(double concavity) { m_concavity = concavity; }
|
||||||
//! Gives the maximum allowed concavity.
|
//! Gives the maximum allowed concavity.
|
||||||
//! @return maximum concavity
|
//! @return maximum concavity
|
||||||
double GetConcavity() const { return m_concavity;}
|
double GetConcavity() const { return m_concavity; }
|
||||||
//! Sets the maximum allowed distance to get CCs connected.
|
//! Sets the maximum allowed distance to get CCs connected.
|
||||||
//! @param concavity maximum distance to get CCs connected
|
//! @param concavity maximum distance to get CCs connected
|
||||||
void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist;}
|
void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist; }
|
||||||
//! Gives the maximum allowed distance to get CCs connected.
|
//! Gives the maximum allowed distance to get CCs connected.
|
||||||
//! @return maximum distance to get CCs connected
|
//! @return maximum distance to get CCs connected
|
||||||
double GetConnectDist() const { return m_ccConnectDist;}
|
double GetConnectDist() const { return m_ccConnectDist; }
|
||||||
//! Sets the volume weight.
|
//! Sets the volume weight.
|
||||||
//! @param beta volume weight
|
//! @param beta volume weight
|
||||||
void SetVolumeWeight(double beta) { m_beta = beta;}
|
void SetVolumeWeight(double beta) { m_beta = beta; }
|
||||||
//! Gives the volume weight.
|
//! Gives the volume weight.
|
||||||
//! @return volume weight
|
//! @return volume weight
|
||||||
double GetVolumeWeight() const { return m_beta;}
|
double GetVolumeWeight() const { return m_beta; }
|
||||||
//! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
|
//! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
|
||||||
//! @param alpha compacity weight
|
//! @param alpha compacity weight
|
||||||
void SetCompacityWeight(double alpha) { m_alpha = alpha;}
|
void SetCompacityWeight(double alpha) { m_alpha = alpha; }
|
||||||
//! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
|
//! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
|
||||||
//! @return compacity weight
|
//! @return compacity weight
|
||||||
double GetCompacityWeight() const { return m_alpha;}
|
double GetCompacityWeight() const { return m_alpha; }
|
||||||
//! Sets the maximum number of vertices for each generated convex-hull.
|
//! Sets the maximum number of vertices for each generated convex-hull.
|
||||||
//! @param nVerticesPerCH maximum # vertices per CH
|
//! @param nVerticesPerCH maximum # vertices per CH
|
||||||
void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH;}
|
void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH; }
|
||||||
//! Gives the maximum number of vertices for each generated convex-hull.
|
//! Gives the maximum number of vertices for each generated convex-hull.
|
||||||
//! @return maximum # vertices per CH
|
//! @return maximum # vertices per CH
|
||||||
size_t GetNVerticesPerCH() const { return m_nVerticesPerCH;}
|
size_t GetNVerticesPerCH() const { return m_nVerticesPerCH; }
|
||||||
//! Gives the number of vertices for the cluster number numCH.
|
//! Gives the number of vertices for the cluster number numCH.
|
||||||
//! @return number of vertices
|
//! @return number of vertices
|
||||||
size_t GetNPointsCH(size_t numCH) const;
|
size_t GetNPointsCH(size_t numCH) const;
|
||||||
@@ -185,18 +186,18 @@ namespace HACD
|
|||||||
//! @param points pointer to the vector of points to be filled
|
//! @param points pointer to the vector of points to be filled
|
||||||
//! @param triangles pointer to the vector of triangles to be filled
|
//! @param triangles pointer to the vector of triangles to be filled
|
||||||
//! @return true if sucess
|
//! @return true if sucess
|
||||||
bool GetCH(size_t numCH, Vec3<Real> * const points, Vec3<long> * const triangles);
|
bool GetCH(size_t numCH, Vec3<Real> *const points, Vec3<long> *const triangles);
|
||||||
//! Computes the HACD decomposition.
|
//! Computes the HACD decomposition.
|
||||||
//! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices
|
//! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices
|
||||||
//! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging).
|
//! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging).
|
||||||
//! @return true if sucess
|
//! @return true if sucess
|
||||||
bool Compute(bool fullCH=false, bool exportDistPoints=false);
|
bool Compute(bool fullCH = false, bool exportDistPoints = false);
|
||||||
//! Saves the generated convex-hulls in a VRML 2.0 file.
|
//! Saves the generated convex-hulls in a VRML 2.0 file.
|
||||||
//! @param fileName the output file name
|
//! @param fileName the output file name
|
||||||
//! @param uniColor specifies whether the different convex-hulls should have the same color or not
|
//! @param uniColor specifies whether the different convex-hulls should have the same color or not
|
||||||
//! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters
|
//! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters
|
||||||
//! @return true if sucess
|
//! @return true if sucess
|
||||||
bool Save(const char * fileName, bool uniColor, long numCluster=-1) const;
|
bool Save(const char *fileName, bool uniColor, long numCluster = -1) const;
|
||||||
//! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0.
|
//! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0.
|
||||||
void NormalizeData();
|
void NormalizeData();
|
||||||
//! Inverse the operations applied by NormalizeData().
|
//! Inverse the operations applied by NormalizeData().
|
||||||
@@ -206,26 +207,28 @@ namespace HACD
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
~HACD(void);
|
~HACD(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Gives the edge index.
|
//! Gives the edge index.
|
||||||
//! @param a first vertex id
|
//! @param a first vertex id
|
||||||
//! @param b second vertex id
|
//! @param b second vertex id
|
||||||
//! @return edge's index
|
//! @return edge's index
|
||||||
static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b)
|
static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b)
|
||||||
{
|
{
|
||||||
if (a > b) return (a << 32) + b;
|
if (a > b)
|
||||||
else return (b << 32) + a;
|
return (a << 32) + b;
|
||||||
|
else
|
||||||
|
return (b << 32) + a;
|
||||||
}
|
}
|
||||||
//! Computes the concavity of a cluster.
|
//! Computes the concavity of a cluster.
|
||||||
//! @param ch the cluster's convex-hull
|
//! @param ch the cluster's convex-hull
|
||||||
//! @param distPoints the cluster's points
|
//! @param distPoints the cluster's points
|
||||||
//! @return cluster's concavity
|
//! @return cluster's concavity
|
||||||
double Concavity(ICHull & ch, std::map<long, DPoint> & distPoints);
|
double Concavity(ICHull &ch, std::map<long, DPoint> &distPoints);
|
||||||
//! Computes the perimeter of a cluster.
|
//! Computes the perimeter of a cluster.
|
||||||
//! @param triIndices the cluster's triangles
|
//! @param triIndices the cluster's triangles
|
||||||
//! @param distPoints the cluster's points
|
//! @param distPoints the cluster's points
|
||||||
//! @return cluster's perimeter
|
//! @return cluster's perimeter
|
||||||
double ComputePerimeter(const std::vector<long> & triIndices) const;
|
double ComputePerimeter(const std::vector<long> &triIndices) const;
|
||||||
//! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph.
|
//! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph.
|
||||||
void CreateGraph();
|
void CreateGraph();
|
||||||
//! Initializes the graph costs and computes the vertices normals
|
//! Initializes the graph costs and computes the vertices normals
|
||||||
@@ -246,13 +249,13 @@ namespace HACD
|
|||||||
//! @param fast specifies whether fast mode is used
|
//! @param fast specifies whether fast mode is used
|
||||||
void Simplify();
|
void Simplify();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData()
|
double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData()
|
||||||
Vec3<long> * m_triangles; //>! pointer the triangles array
|
Vec3<long> *m_triangles; //>! pointer the triangles array
|
||||||
Vec3<Real> * m_points; //>! pointer the points array
|
Vec3<Real> *m_points; //>! pointer the points array
|
||||||
Vec3<Real> * m_facePoints; //>! pointer to the faces points array
|
Vec3<Real> *m_facePoints; //>! pointer to the faces points array
|
||||||
Vec3<Real> * m_faceNormals; //>! pointer to the faces normals array
|
Vec3<Real> *m_faceNormals; //>! pointer to the faces normals array
|
||||||
Vec3<Real> * m_normals; //>! pointer the normals array
|
Vec3<Real> *m_normals; //>! pointer the normals array
|
||||||
size_t m_nTriangles; //>! number of triangles in the original mesh
|
size_t m_nTriangles; //>! number of triangles in the original mesh
|
||||||
size_t m_nPoints; //>! number of vertices in the original mesh
|
size_t m_nPoints; //>! number of vertices in the original mesh
|
||||||
size_t m_nClusters; //>! number of clusters
|
size_t m_nClusters; //>! number of clusters
|
||||||
@@ -263,20 +266,20 @@ namespace HACD
|
|||||||
double m_beta; //>! volume weigth
|
double m_beta; //>! volume weigth
|
||||||
double m_diag; //>! length of the BB diagonal
|
double m_diag; //>! length of the BB diagonal
|
||||||
Vec3<Real> m_barycenter; //>! barycenter of the mesh
|
Vec3<Real> m_barycenter; //>! barycenter of the mesh
|
||||||
std::vector< long > m_cVertices; //>! array of vertices each belonging to a different cluster
|
std::vector<long> m_cVertices; //>! array of vertices each belonging to a different cluster
|
||||||
ICHull * m_convexHulls; //>! convex-hulls associated with the final HACD clusters
|
ICHull *m_convexHulls; //>! convex-hulls associated with the final HACD clusters
|
||||||
Graph m_graph; //>! simplification graph
|
Graph m_graph; //>! simplification graph
|
||||||
size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull
|
size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull
|
||||||
reservable_priority_queue<GraphEdgePriorityQueue,
|
reservable_priority_queue<GraphEdgePriorityQueue,
|
||||||
std::vector<GraphEdgePriorityQueue>,
|
std::vector<GraphEdgePriorityQueue>,
|
||||||
std::greater<std::vector<GraphEdgePriorityQueue>::value_type> > m_pqueue; //!> priority queue
|
std::greater<std::vector<GraphEdgePriorityQueue>::value_type> >
|
||||||
HACD(const HACD & rhs);
|
m_pqueue; //!> priority queue
|
||||||
|
HACD(const HACD &rhs);
|
||||||
CallBackFunction m_callBack; //>! call-back function
|
CallBackFunction m_callBack; //>! call-back function
|
||||||
long * m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
|
long *m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
|
||||||
bool m_addFacesPoints; //>! specifies whether to add faces points or not
|
bool m_addFacesPoints; //>! specifies whether to add faces points or not
|
||||||
bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not
|
bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not
|
||||||
bool m_addNeighboursDistPoints; //>! specifies whether to add extra points from adjacent clusters or not
|
bool m_addNeighboursDistPoints; //>! specifies whether to add extra points from adjacent clusters or not
|
||||||
|
};
|
||||||
};
|
} // namespace HACD
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,20 +18,20 @@
|
|||||||
|
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
const long ICHull::sc_dummyIndex = std::numeric_limits<long>::max();
|
const long ICHull::sc_dummyIndex = std::numeric_limits<long>::max();
|
||||||
ICHull::ICHull(void)
|
ICHull::ICHull(void)
|
||||||
{
|
{
|
||||||
m_distPoints = 0;
|
m_distPoints = 0;
|
||||||
m_isFlat = false;
|
m_isFlat = false;
|
||||||
m_dummyVertex = 0;
|
m_dummyVertex = 0;
|
||||||
}
|
}
|
||||||
bool ICHull::AddPoints(const Vec3<Real> * points, size_t nPoints)
|
bool ICHull::AddPoints(const Vec3<Real> *points, size_t nPoints)
|
||||||
{
|
{
|
||||||
if (!points)
|
if (!points)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CircularListElement<TMMVertex> * vertex = NULL;
|
CircularListElement<TMMVertex> *vertex = NULL;
|
||||||
for (size_t i = 0; i < nPoints; i++)
|
for (size_t i = 0; i < nPoints; i++)
|
||||||
{
|
{
|
||||||
vertex = m_mesh.AddVertex();
|
vertex = m_mesh.AddVertex();
|
||||||
@@ -41,10 +41,10 @@ namespace HACD
|
|||||||
vertex->GetData().m_name = static_cast<long>(i);
|
vertex->GetData().m_name = static_cast<long>(i);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ICHull::AddPoints(std::vector< Vec3<Real> > points)
|
bool ICHull::AddPoints(std::vector<Vec3<Real> > points)
|
||||||
{
|
{
|
||||||
CircularListElement<TMMVertex> * vertex = NULL;
|
CircularListElement<TMMVertex> *vertex = NULL;
|
||||||
for (size_t i = 0; i < points.size(); i++)
|
for (size_t i = 0; i < points.size(); i++)
|
||||||
{
|
{
|
||||||
vertex = m_mesh.AddVertex();
|
vertex = m_mesh.AddVertex();
|
||||||
@@ -53,20 +53,20 @@ namespace HACD
|
|||||||
vertex->GetData().m_pos.Z() = points[i].Z();
|
vertex->GetData().m_pos.Z() = points[i].Z();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ICHull::AddPoint(const Vec3<Real> & point, long id)
|
bool ICHull::AddPoint(const Vec3<Real> &point, long id)
|
||||||
{
|
{
|
||||||
if (AddPoints(&point, 1))
|
if (AddPoints(&point, 1))
|
||||||
{
|
{
|
||||||
m_mesh.m_vertices.GetData().m_name = id;
|
m_mesh.m_vertices.GetData().m_name = id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ICHullError ICHull::Process()
|
ICHullError ICHull::Process()
|
||||||
{
|
{
|
||||||
unsigned long addedPoints = 0;
|
unsigned long addedPoints = 0;
|
||||||
if (m_mesh.GetNVertices() < 3)
|
if (m_mesh.GetNVertices() < 3)
|
||||||
{
|
{
|
||||||
@@ -75,16 +75,16 @@ namespace HACD
|
|||||||
if (m_mesh.GetNVertices() == 3)
|
if (m_mesh.GetNVertices() == 3)
|
||||||
{
|
{
|
||||||
m_isFlat = true;
|
m_isFlat = true;
|
||||||
CircularListElement<TMMTriangle> * t1 = m_mesh.AddTriangle();
|
CircularListElement<TMMTriangle> *t1 = m_mesh.AddTriangle();
|
||||||
CircularListElement<TMMTriangle> * t2 = m_mesh.AddTriangle();
|
CircularListElement<TMMTriangle> *t2 = m_mesh.AddTriangle();
|
||||||
CircularListElement<TMMVertex> * v0 = m_mesh.m_vertices.GetHead();
|
CircularListElement<TMMVertex> *v0 = m_mesh.m_vertices.GetHead();
|
||||||
CircularListElement<TMMVertex> * v1 = v0->GetNext();
|
CircularListElement<TMMVertex> *v1 = v0->GetNext();
|
||||||
CircularListElement<TMMVertex> * v2 = v1->GetNext();
|
CircularListElement<TMMVertex> *v2 = v1->GetNext();
|
||||||
// Compute the normal to the plane
|
// Compute the normal to the plane
|
||||||
Vec3<Real> p0 = v0->GetData().m_pos;
|
Vec3<Real> p0 = v0->GetData().m_pos;
|
||||||
Vec3<Real> p1 = v1->GetData().m_pos;
|
Vec3<Real> p1 = v1->GetData().m_pos;
|
||||||
Vec3<Real> p2 = v2->GetData().m_pos;
|
Vec3<Real> p2 = v2->GetData().m_pos;
|
||||||
m_normal = (p1-p0) ^ (p2-p0);
|
m_normal = (p1 - p0) ^ (p2 - p0);
|
||||||
m_normal.Normalize();
|
m_normal.Normalize();
|
||||||
t1->GetData().m_vertices[0] = v0;
|
t1->GetData().m_vertices[0] = v0;
|
||||||
t1->GetData().m_vertices[1] = v1;
|
t1->GetData().m_vertices[1] = v1;
|
||||||
@@ -112,7 +112,7 @@ namespace HACD
|
|||||||
addedPoints += 3;
|
addedPoints += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
// go to the first added and not processed vertex
|
// go to the first added and not processed vertex
|
||||||
while (!(vertices.GetHead()->GetPrev()->GetData().m_tag))
|
while (!(vertices.GetHead()->GetPrev()->GetData().m_tag))
|
||||||
{
|
{
|
||||||
@@ -134,19 +134,19 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
if (m_isFlat)
|
if (m_isFlat)
|
||||||
{
|
{
|
||||||
std::vector< CircularListElement<TMMTriangle> * > trianglesToDuplicate;
|
std::vector<CircularListElement<TMMTriangle> *> trianglesToDuplicate;
|
||||||
size_t nT = m_mesh.GetNTriangles();
|
size_t nT = m_mesh.GetNTriangles();
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData();
|
TMMTriangle ¤tTriangle = m_mesh.m_triangles.GetHead()->GetData();
|
||||||
if( currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex ||
|
if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex ||
|
||||||
currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex ||
|
currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex ||
|
||||||
currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex )
|
currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex)
|
||||||
{
|
{
|
||||||
m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead());
|
m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead());
|
||||||
for(int k = 0; k < 3; k++)
|
for (int k = 0; k < 3; k++)
|
||||||
{
|
{
|
||||||
for(int h = 0; h < 2; h++)
|
for (int h = 0; h < 2; h++)
|
||||||
{
|
{
|
||||||
if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead())
|
if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead())
|
||||||
{
|
{
|
||||||
@@ -163,10 +163,10 @@ namespace HACD
|
|||||||
m_mesh.m_triangles.Next();
|
m_mesh.m_triangles.Next();
|
||||||
}
|
}
|
||||||
size_t nE = m_mesh.GetNEdges();
|
size_t nE = m_mesh.GetNEdges();
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData();
|
TMMEdge ¤tEdge = m_mesh.m_edges.GetHead()->GetData();
|
||||||
if( currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0)
|
if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0)
|
||||||
{
|
{
|
||||||
m_edgesToDelete.push_back(m_mesh.m_edges.GetHead());
|
m_edgesToDelete.push_back(m_mesh.m_edges.GetHead());
|
||||||
}
|
}
|
||||||
@@ -175,16 +175,16 @@ namespace HACD
|
|||||||
m_mesh.m_vertices.Delete(m_dummyVertex);
|
m_mesh.m_vertices.Delete(m_dummyVertex);
|
||||||
m_dummyVertex = 0;
|
m_dummyVertex = 0;
|
||||||
size_t nV = m_mesh.GetNVertices();
|
size_t nV = m_mesh.GetNVertices();
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
for(size_t v = 0; v < nV; ++v)
|
for (size_t v = 0; v < nV; ++v)
|
||||||
{
|
{
|
||||||
vertices.GetData().m_tag = false;
|
vertices.GetData().m_tag = false;
|
||||||
vertices.Next();
|
vertices.Next();
|
||||||
}
|
}
|
||||||
CleanEdges();
|
CleanEdges();
|
||||||
CleanTriangles();
|
CleanTriangles();
|
||||||
CircularListElement<TMMTriangle> * newTriangle;
|
CircularListElement<TMMTriangle> *newTriangle;
|
||||||
for(size_t t = 0; t < trianglesToDuplicate.size(); t++)
|
for (size_t t = 0; t < trianglesToDuplicate.size(); t++)
|
||||||
{
|
{
|
||||||
newTriangle = m_mesh.AddTriangle();
|
newTriangle = m_mesh.AddTriangle();
|
||||||
newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1];
|
newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1];
|
||||||
@@ -193,9 +193,9 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ICHullErrorOK;
|
return ICHullErrorOK;
|
||||||
}
|
}
|
||||||
ICHullError ICHull::Process(unsigned long nPointsCH)
|
ICHullError ICHull::Process(unsigned long nPointsCH)
|
||||||
{
|
{
|
||||||
unsigned long addedPoints = 0;
|
unsigned long addedPoints = 0;
|
||||||
if (nPointsCH < 3 || m_mesh.GetNVertices() < 3)
|
if (nPointsCH < 3 || m_mesh.GetNVertices() < 3)
|
||||||
{
|
{
|
||||||
@@ -204,16 +204,16 @@ namespace HACD
|
|||||||
if (m_mesh.GetNVertices() == 3)
|
if (m_mesh.GetNVertices() == 3)
|
||||||
{
|
{
|
||||||
m_isFlat = true;
|
m_isFlat = true;
|
||||||
CircularListElement<TMMTriangle> * t1 = m_mesh.AddTriangle();
|
CircularListElement<TMMTriangle> *t1 = m_mesh.AddTriangle();
|
||||||
CircularListElement<TMMTriangle> * t2 = m_mesh.AddTriangle();
|
CircularListElement<TMMTriangle> *t2 = m_mesh.AddTriangle();
|
||||||
CircularListElement<TMMVertex> * v0 = m_mesh.m_vertices.GetHead();
|
CircularListElement<TMMVertex> *v0 = m_mesh.m_vertices.GetHead();
|
||||||
CircularListElement<TMMVertex> * v1 = v0->GetNext();
|
CircularListElement<TMMVertex> *v1 = v0->GetNext();
|
||||||
CircularListElement<TMMVertex> * v2 = v1->GetNext();
|
CircularListElement<TMMVertex> *v2 = v1->GetNext();
|
||||||
// Compute the normal to the plane
|
// Compute the normal to the plane
|
||||||
Vec3<Real> p0 = v0->GetData().m_pos;
|
Vec3<Real> p0 = v0->GetData().m_pos;
|
||||||
Vec3<Real> p1 = v1->GetData().m_pos;
|
Vec3<Real> p1 = v1->GetData().m_pos;
|
||||||
Vec3<Real> p2 = v2->GetData().m_pos;
|
Vec3<Real> p2 = v2->GetData().m_pos;
|
||||||
m_normal = (p1-p0) ^ (p2-p0);
|
m_normal = (p1 - p0) ^ (p2 - p0);
|
||||||
m_normal.Normalize();
|
m_normal.Normalize();
|
||||||
t1->GetData().m_vertices[0] = v0;
|
t1->GetData().m_vertices[0] = v0;
|
||||||
t1->GetData().m_vertices[1] = v1;
|
t1->GetData().m_vertices[1] = v1;
|
||||||
@@ -243,7 +243,7 @@ namespace HACD
|
|||||||
addedPoints += 3;
|
addedPoints += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed
|
while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed
|
||||||
{
|
{
|
||||||
if (!FindMaxVolumePoint())
|
if (!FindMaxVolumePoint())
|
||||||
@@ -271,19 +271,19 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
if (m_isFlat)
|
if (m_isFlat)
|
||||||
{
|
{
|
||||||
std::vector< CircularListElement<TMMTriangle> * > trianglesToDuplicate;
|
std::vector<CircularListElement<TMMTriangle> *> trianglesToDuplicate;
|
||||||
size_t nT = m_mesh.GetNTriangles();
|
size_t nT = m_mesh.GetNTriangles();
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData();
|
TMMTriangle ¤tTriangle = m_mesh.m_triangles.GetHead()->GetData();
|
||||||
if( currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex ||
|
if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex ||
|
||||||
currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex ||
|
currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex ||
|
||||||
currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex )
|
currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex)
|
||||||
{
|
{
|
||||||
m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead());
|
m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead());
|
||||||
for(int k = 0; k < 3; k++)
|
for (int k = 0; k < 3; k++)
|
||||||
{
|
{
|
||||||
for(int h = 0; h < 2; h++)
|
for (int h = 0; h < 2; h++)
|
||||||
{
|
{
|
||||||
if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead())
|
if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead())
|
||||||
{
|
{
|
||||||
@@ -300,10 +300,10 @@ namespace HACD
|
|||||||
m_mesh.m_triangles.Next();
|
m_mesh.m_triangles.Next();
|
||||||
}
|
}
|
||||||
size_t nE = m_mesh.GetNEdges();
|
size_t nE = m_mesh.GetNEdges();
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData();
|
TMMEdge ¤tEdge = m_mesh.m_edges.GetHead()->GetData();
|
||||||
if( currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0)
|
if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0)
|
||||||
{
|
{
|
||||||
m_edgesToDelete.push_back(m_mesh.m_edges.GetHead());
|
m_edgesToDelete.push_back(m_mesh.m_edges.GetHead());
|
||||||
}
|
}
|
||||||
@@ -312,16 +312,16 @@ namespace HACD
|
|||||||
m_mesh.m_vertices.Delete(m_dummyVertex);
|
m_mesh.m_vertices.Delete(m_dummyVertex);
|
||||||
m_dummyVertex = 0;
|
m_dummyVertex = 0;
|
||||||
size_t nV = m_mesh.GetNVertices();
|
size_t nV = m_mesh.GetNVertices();
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
for(size_t v = 0; v < nV; ++v)
|
for (size_t v = 0; v < nV; ++v)
|
||||||
{
|
{
|
||||||
vertices.GetData().m_tag = false;
|
vertices.GetData().m_tag = false;
|
||||||
vertices.Next();
|
vertices.Next();
|
||||||
}
|
}
|
||||||
CleanEdges();
|
CleanEdges();
|
||||||
CleanTriangles();
|
CleanTriangles();
|
||||||
CircularListElement<TMMTriangle> * newTriangle;
|
CircularListElement<TMMTriangle> *newTriangle;
|
||||||
for(size_t t = 0; t < trianglesToDuplicate.size(); t++)
|
for (size_t t = 0; t < trianglesToDuplicate.size(); t++)
|
||||||
{
|
{
|
||||||
newTriangle = m_mesh.AddTriangle();
|
newTriangle = m_mesh.AddTriangle();
|
||||||
newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1];
|
newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1];
|
||||||
@@ -330,12 +330,12 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ICHullErrorOK;
|
return ICHullErrorOK;
|
||||||
}
|
}
|
||||||
bool ICHull::FindMaxVolumePoint()
|
bool ICHull::FindMaxVolumePoint()
|
||||||
{
|
{
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
CircularListElement<TMMVertex> * vMaxVolume = 0;
|
CircularListElement<TMMVertex> *vMaxVolume = 0;
|
||||||
CircularListElement<TMMVertex> * vHeadPrev = vertices.GetHead()->GetPrev();
|
CircularListElement<TMMVertex> *vHeadPrev = vertices.GetHead()->GetPrev();
|
||||||
|
|
||||||
double maxVolume = 0.0;
|
double maxVolume = 0.0;
|
||||||
double volume = 0.0;
|
double volume = 0.0;
|
||||||
@@ -344,7 +344,7 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
if (ComputePointVolume(volume, false))
|
if (ComputePointVolume(volume, false))
|
||||||
{
|
{
|
||||||
if ( maxVolume < volume)
|
if (maxVolume < volume)
|
||||||
{
|
{
|
||||||
maxVolume = volume;
|
maxVolume = volume;
|
||||||
vMaxVolume = vertices.GetHead();
|
vMaxVolume = vertices.GetHead();
|
||||||
@@ -352,7 +352,7 @@ namespace HACD
|
|||||||
vertices.Next();
|
vertices.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CircularListElement<TMMVertex> * vHead = vHeadPrev->GetNext();
|
CircularListElement<TMMVertex> *vHead = vHeadPrev->GetNext();
|
||||||
vertices.GetHead() = vHead;
|
vertices.GetHead() = vHead;
|
||||||
|
|
||||||
if (!vMaxVolume)
|
if (!vMaxVolume)
|
||||||
@@ -370,35 +370,34 @@ namespace HACD
|
|||||||
vHead->GetData().m_name = id;
|
vHead->GetData().m_name = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ICHullError ICHull::DoubleTriangle()
|
ICHullError ICHull::DoubleTriangle()
|
||||||
{
|
{
|
||||||
// find three non colinear points
|
// find three non colinear points
|
||||||
m_isFlat = false;
|
m_isFlat = false;
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
CircularListElement<TMMVertex> * v0 = vertices.GetHead();
|
CircularListElement<TMMVertex> *v0 = vertices.GetHead();
|
||||||
while( Colinear(v0->GetData().m_pos,
|
while (Colinear(v0->GetData().m_pos,
|
||||||
v0->GetNext()->GetData().m_pos,
|
v0->GetNext()->GetData().m_pos,
|
||||||
v0->GetNext()->GetNext()->GetData().m_pos))
|
v0->GetNext()->GetNext()->GetData().m_pos))
|
||||||
{
|
{
|
||||||
if ( (v0 = v0->GetNext()) == vertices.GetHead())
|
if ((v0 = v0->GetNext()) == vertices.GetHead())
|
||||||
{
|
{
|
||||||
return ICHullErrorCoplanarPoints;
|
return ICHullErrorCoplanarPoints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CircularListElement<TMMVertex> * v1 = v0->GetNext();
|
CircularListElement<TMMVertex> *v1 = v0->GetNext();
|
||||||
CircularListElement<TMMVertex> * v2 = v1->GetNext();
|
CircularListElement<TMMVertex> *v2 = v1->GetNext();
|
||||||
// mark points as processed
|
// mark points as processed
|
||||||
v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true;
|
v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true;
|
||||||
|
|
||||||
// create two triangles
|
// create two triangles
|
||||||
CircularListElement<TMMTriangle> * f0 = MakeFace(v0, v1, v2, 0);
|
CircularListElement<TMMTriangle> *f0 = MakeFace(v0, v1, v2, 0);
|
||||||
MakeFace(v2, v1, v0, f0);
|
MakeFace(v2, v1, v0, f0);
|
||||||
|
|
||||||
// find a fourth non-coplanar point to form tetrahedron
|
// find a fourth non-coplanar point to form tetrahedron
|
||||||
CircularListElement<TMMVertex> * v3 = v2->GetNext();
|
CircularListElement<TMMVertex> *v3 = v2->GetNext();
|
||||||
vertices.GetHead() = v3;
|
vertices.GetHead() = v3;
|
||||||
|
|
||||||
double vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos);
|
double vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos);
|
||||||
@@ -410,20 +409,19 @@ namespace HACD
|
|||||||
if (vol == 0.0)
|
if (vol == 0.0)
|
||||||
{
|
{
|
||||||
// compute the barycenter
|
// compute the barycenter
|
||||||
Vec3<Real> bary(0.0,0.0,0.0);
|
Vec3<Real> bary(0.0, 0.0, 0.0);
|
||||||
CircularListElement<TMMVertex> * vBary = v0;
|
CircularListElement<TMMVertex> *vBary = v0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
bary += vBary->GetData().m_pos;
|
bary += vBary->GetData().m_pos;
|
||||||
}
|
} while ((vBary = vBary->GetNext()) != v0);
|
||||||
while ( (vBary = vBary->GetNext()) != v0);
|
|
||||||
bary /= static_cast<Real>(vertices.GetSize());
|
bary /= static_cast<Real>(vertices.GetSize());
|
||||||
|
|
||||||
// Compute the normal to the plane
|
// Compute the normal to the plane
|
||||||
Vec3<Real> p0 = v0->GetData().m_pos;
|
Vec3<Real> p0 = v0->GetData().m_pos;
|
||||||
Vec3<Real> p1 = v1->GetData().m_pos;
|
Vec3<Real> p1 = v1->GetData().m_pos;
|
||||||
Vec3<Real> p2 = v2->GetData().m_pos;
|
Vec3<Real> p2 = v2->GetData().m_pos;
|
||||||
m_normal = (p1-p0) ^ (p2-p0);
|
m_normal = (p1 - p0) ^ (p2 - p0);
|
||||||
m_normal.Normalize();
|
m_normal.Normalize();
|
||||||
// add dummy vertex placed at (bary + normal)
|
// add dummy vertex placed at (bary + normal)
|
||||||
vertices.GetHead() = v2;
|
vertices.GetHead() = v2;
|
||||||
@@ -446,15 +444,15 @@ namespace HACD
|
|||||||
vertices.GetHead()->GetData().m_pos = temp.m_pos;
|
vertices.GetHead()->GetData().m_pos = temp.m_pos;
|
||||||
}
|
}
|
||||||
return ICHullErrorOK;
|
return ICHullErrorOK;
|
||||||
}
|
}
|
||||||
CircularListElement<TMMTriangle> * ICHull::MakeFace(CircularListElement<TMMVertex> * v0,
|
CircularListElement<TMMTriangle> *ICHull::MakeFace(CircularListElement<TMMVertex> *v0,
|
||||||
CircularListElement<TMMVertex> * v1,
|
CircularListElement<TMMVertex> *v1,
|
||||||
CircularListElement<TMMVertex> * v2,
|
CircularListElement<TMMVertex> *v2,
|
||||||
CircularListElement<TMMTriangle> * fold)
|
CircularListElement<TMMTriangle> *fold)
|
||||||
{
|
{
|
||||||
CircularListElement<TMMEdge> * e0;
|
CircularListElement<TMMEdge> *e0;
|
||||||
CircularListElement<TMMEdge> * e1;
|
CircularListElement<TMMEdge> *e1;
|
||||||
CircularListElement<TMMEdge> * e2;
|
CircularListElement<TMMEdge> *e2;
|
||||||
long index = 0;
|
long index = 0;
|
||||||
if (!fold) // if first face to be created
|
if (!fold) // if first face to be created
|
||||||
{
|
{
|
||||||
@@ -469,24 +467,31 @@ namespace HACD
|
|||||||
e2 = fold->GetData().m_edges[0];
|
e2 = fold->GetData().m_edges[0];
|
||||||
index = 1;
|
index = 1;
|
||||||
}
|
}
|
||||||
e0->GetData().m_vertices[0] = v0; e0->GetData().m_vertices[1] = v1;
|
e0->GetData().m_vertices[0] = v0;
|
||||||
e1->GetData().m_vertices[0] = v1; e1->GetData().m_vertices[1] = v2;
|
e0->GetData().m_vertices[1] = v1;
|
||||||
e2->GetData().m_vertices[0] = v2; e2->GetData().m_vertices[1] = v0;
|
e1->GetData().m_vertices[0] = v1;
|
||||||
|
e1->GetData().m_vertices[1] = v2;
|
||||||
|
e2->GetData().m_vertices[0] = v2;
|
||||||
|
e2->GetData().m_vertices[1] = v0;
|
||||||
// create the new face
|
// create the new face
|
||||||
CircularListElement<TMMTriangle> * f = m_mesh.AddTriangle();
|
CircularListElement<TMMTriangle> *f = m_mesh.AddTriangle();
|
||||||
f->GetData().m_edges[0] = e0; f->GetData().m_edges[1] = e1; f->GetData().m_edges[2] = e2;
|
f->GetData().m_edges[0] = e0;
|
||||||
f->GetData().m_vertices[0] = v0; f->GetData().m_vertices[1] = v1; f->GetData().m_vertices[2] = v2;
|
f->GetData().m_edges[1] = e1;
|
||||||
|
f->GetData().m_edges[2] = e2;
|
||||||
|
f->GetData().m_vertices[0] = v0;
|
||||||
|
f->GetData().m_vertices[1] = v1;
|
||||||
|
f->GetData().m_vertices[2] = v2;
|
||||||
// link edges to face f
|
// link edges to face f
|
||||||
e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f;
|
e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
CircularListElement<TMMTriangle> * ICHull::MakeConeFace(CircularListElement<TMMEdge> * e, CircularListElement<TMMVertex> * p)
|
CircularListElement<TMMTriangle> *ICHull::MakeConeFace(CircularListElement<TMMEdge> *e, CircularListElement<TMMVertex> *p)
|
||||||
{
|
{
|
||||||
// create two new edges if they don't already exist
|
// create two new edges if they don't already exist
|
||||||
CircularListElement<TMMEdge> * newEdges[2];
|
CircularListElement<TMMEdge> *newEdges[2];
|
||||||
for(int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
if ( !( newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate ) )
|
if (!(newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate))
|
||||||
{ // if the edge doesn't exits add it and mark the vertex as duplicated
|
{ // if the edge doesn't exits add it and mark the vertex as duplicated
|
||||||
newEdges[i] = m_mesh.AddEdge();
|
newEdges[i] = m_mesh.AddEdge();
|
||||||
newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i];
|
newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i];
|
||||||
@@ -495,16 +500,16 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// make the new face
|
// make the new face
|
||||||
CircularListElement<TMMTriangle> * newFace = m_mesh.AddTriangle();
|
CircularListElement<TMMTriangle> *newFace = m_mesh.AddTriangle();
|
||||||
newFace->GetData().m_edges[0] = e;
|
newFace->GetData().m_edges[0] = e;
|
||||||
newFace->GetData().m_edges[1] = newEdges[0];
|
newFace->GetData().m_edges[1] = newEdges[0];
|
||||||
newFace->GetData().m_edges[2] = newEdges[1];
|
newFace->GetData().m_edges[2] = newEdges[1];
|
||||||
MakeCCW(newFace, e, p);
|
MakeCCW(newFace, e, p);
|
||||||
for(int i=0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
for(int j=0; j < 2; ++j)
|
for (int j = 0; j < 2; ++j)
|
||||||
{
|
{
|
||||||
if ( ! newEdges[i]->GetData().m_triangles[j] )
|
if (!newEdges[i]->GetData().m_triangles[j])
|
||||||
{
|
{
|
||||||
newEdges[i]->GetData().m_triangles[j] = newFace;
|
newEdges[i]->GetData().m_triangles[j] = newFace;
|
||||||
break;
|
break;
|
||||||
@@ -512,14 +517,14 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newFace;
|
return newFace;
|
||||||
}
|
}
|
||||||
bool ICHull::ComputePointVolume(double &totalVolume, bool markVisibleFaces)
|
bool ICHull::ComputePointVolume(double &totalVolume, bool markVisibleFaces)
|
||||||
{
|
{
|
||||||
// mark visible faces
|
// mark visible faces
|
||||||
CircularListElement<TMMTriangle> * fHead = m_mesh.GetTriangles().GetHead();
|
CircularListElement<TMMTriangle> *fHead = m_mesh.GetTriangles().GetHead();
|
||||||
CircularListElement<TMMTriangle> * f = fHead;
|
CircularListElement<TMMTriangle> *f = fHead;
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
CircularListElement<TMMVertex> * vertex0 = vertices.GetHead();
|
CircularListElement<TMMVertex> *vertex0 = vertices.GetHead();
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
Vec3<double> pos0 = Vec3<double>(vertex0->GetData().m_pos.X(),
|
Vec3<double> pos0 = Vec3<double>(vertex0->GetData().m_pos.X(),
|
||||||
vertex0->GetData().m_pos.Y(),
|
vertex0->GetData().m_pos.Y(),
|
||||||
@@ -539,7 +544,7 @@ namespace HACD
|
|||||||
ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y();
|
ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y();
|
||||||
ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z();
|
ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z();
|
||||||
vol = Volume(ver0, ver1, ver2, pos0);
|
vol = Volume(ver0, ver1, ver2, pos0);
|
||||||
if ( vol < 0.0 )
|
if (vol < 0.0)
|
||||||
{
|
{
|
||||||
vol = fabs(vol);
|
vol = fabs(vol);
|
||||||
totalVolume += vol;
|
totalVolume += vol;
|
||||||
@@ -551,12 +556,11 @@ namespace HACD
|
|||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
f = f->GetNext();
|
f = f->GetNext();
|
||||||
}
|
} while (f != fHead);
|
||||||
while (f != fHead);
|
|
||||||
|
|
||||||
if (m_trianglesToDelete.size() == m_mesh.m_triangles.GetSize())
|
if (m_trianglesToDelete.size() == m_mesh.m_triangles.GetSize())
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < m_trianglesToDelete.size(); i++)
|
for (size_t i = 0; i < m_trianglesToDelete.size(); i++)
|
||||||
{
|
{
|
||||||
m_trianglesToDelete[i]->GetData().m_visible = false;
|
m_trianglesToDelete[i]->GetData().m_visible = false;
|
||||||
}
|
}
|
||||||
@@ -572,9 +576,9 @@ namespace HACD
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ICHull::ProcessPoint()
|
bool ICHull::ProcessPoint()
|
||||||
{
|
{
|
||||||
double totalVolume = 0.0;
|
double totalVolume = 0.0;
|
||||||
if (!ComputePointVolume(totalVolume, true))
|
if (!ComputePointVolume(totalVolume, true))
|
||||||
{
|
{
|
||||||
@@ -582,10 +586,10 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
// Mark edges in interior of visible region for deletion.
|
// Mark edges in interior of visible region for deletion.
|
||||||
// Create a new face based on each border edge
|
// Create a new face based on each border edge
|
||||||
CircularListElement<TMMVertex> * v0 = m_mesh.GetVertices().GetHead();
|
CircularListElement<TMMVertex> *v0 = m_mesh.GetVertices().GetHead();
|
||||||
CircularListElement<TMMEdge> * eHead = m_mesh.GetEdges().GetHead();
|
CircularListElement<TMMEdge> *eHead = m_mesh.GetEdges().GetHead();
|
||||||
CircularListElement<TMMEdge> * e = eHead;
|
CircularListElement<TMMEdge> *e = eHead;
|
||||||
CircularListElement<TMMEdge> * tmp = 0;
|
CircularListElement<TMMEdge> *tmp = 0;
|
||||||
long nvisible = 0;
|
long nvisible = 0;
|
||||||
m_edgesToDelete.clear();
|
m_edgesToDelete.clear();
|
||||||
m_edgesToUpdate.clear();
|
m_edgesToUpdate.clear();
|
||||||
@@ -593,33 +597,32 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
tmp = e->GetNext();
|
tmp = e->GetNext();
|
||||||
nvisible = 0;
|
nvisible = 0;
|
||||||
for(int k = 0; k < 2; k++)
|
for (int k = 0; k < 2; k++)
|
||||||
{
|
{
|
||||||
if ( e->GetData().m_triangles[k]->GetData().m_visible )
|
if (e->GetData().m_triangles[k]->GetData().m_visible)
|
||||||
{
|
{
|
||||||
nvisible++;
|
nvisible++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( nvisible == 2)
|
if (nvisible == 2)
|
||||||
{
|
{
|
||||||
m_edgesToDelete.push_back(e);
|
m_edgesToDelete.push_back(e);
|
||||||
}
|
}
|
||||||
else if ( nvisible == 1)
|
else if (nvisible == 1)
|
||||||
{
|
{
|
||||||
e->GetData().m_newFace = MakeConeFace(e, v0);
|
e->GetData().m_newFace = MakeConeFace(e, v0);
|
||||||
m_edgesToUpdate.push_back(e);
|
m_edgesToUpdate.push_back(e);
|
||||||
}
|
}
|
||||||
e = tmp;
|
e = tmp;
|
||||||
}
|
} while (e != eHead);
|
||||||
while (e != eHead);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ICHull::MakeCCW(CircularListElement<TMMTriangle> * f,
|
bool ICHull::MakeCCW(CircularListElement<TMMTriangle> *f,
|
||||||
CircularListElement<TMMEdge> * e,
|
CircularListElement<TMMEdge> *e,
|
||||||
CircularListElement<TMMVertex> * v)
|
CircularListElement<TMMVertex> *v)
|
||||||
{
|
{
|
||||||
// the visible face adjacent to e
|
// the visible face adjacent to e
|
||||||
CircularListElement<TMMTriangle> * fv;
|
CircularListElement<TMMTriangle> *fv;
|
||||||
if (e->GetData().m_triangles[0]->GetData().m_visible)
|
if (e->GetData().m_triangles[0]->GetData().m_visible)
|
||||||
{
|
{
|
||||||
fv = e->GetData().m_triangles[0];
|
fv = e->GetData().m_triangles[0];
|
||||||
@@ -631,11 +634,12 @@ namespace HACD
|
|||||||
|
|
||||||
// set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv.
|
// set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv.
|
||||||
long i; // index of e->m_vertices[0] in fv
|
long i; // index of e->m_vertices[0] in fv
|
||||||
CircularListElement<TMMVertex> * v0 = e->GetData().m_vertices[0];
|
CircularListElement<TMMVertex> *v0 = e->GetData().m_vertices[0];
|
||||||
CircularListElement<TMMVertex> * v1 = e->GetData().m_vertices[1];
|
CircularListElement<TMMVertex> *v1 = e->GetData().m_vertices[1];
|
||||||
for(i = 0; fv->GetData().m_vertices[i] != v0; i++);
|
for (i = 0; fv->GetData().m_vertices[i] != v0; i++)
|
||||||
|
;
|
||||||
|
|
||||||
if ( fv->GetData().m_vertices[(i+1) % 3] != e->GetData().m_vertices[1] )
|
if (fv->GetData().m_vertices[(i + 1) % 3] != e->GetData().m_vertices[1])
|
||||||
{
|
{
|
||||||
f->GetData().m_vertices[0] = v1;
|
f->GetData().m_vertices[0] = v1;
|
||||||
f->GetData().m_vertices[1] = v0;
|
f->GetData().m_vertices[1] = v0;
|
||||||
@@ -645,31 +649,31 @@ namespace HACD
|
|||||||
f->GetData().m_vertices[0] = v0;
|
f->GetData().m_vertices[0] = v0;
|
||||||
f->GetData().m_vertices[1] = v1;
|
f->GetData().m_vertices[1] = v1;
|
||||||
// swap edges
|
// swap edges
|
||||||
CircularListElement<TMMEdge> * tmp = f->GetData().m_edges[0];
|
CircularListElement<TMMEdge> *tmp = f->GetData().m_edges[0];
|
||||||
f->GetData().m_edges[0] = f->GetData().m_edges[1];
|
f->GetData().m_edges[0] = f->GetData().m_edges[1];
|
||||||
f->GetData().m_edges[1] = tmp;
|
f->GetData().m_edges[1] = tmp;
|
||||||
}
|
}
|
||||||
f->GetData().m_vertices[2] = v;
|
f->GetData().m_vertices[2] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ICHull::CleanUp(unsigned long & addedPoints)
|
bool ICHull::CleanUp(unsigned long &addedPoints)
|
||||||
{
|
{
|
||||||
bool r0 = CleanEdges();
|
bool r0 = CleanEdges();
|
||||||
bool r1 = CleanTriangles();
|
bool r1 = CleanTriangles();
|
||||||
bool r2 = CleanVertices(addedPoints);
|
bool r2 = CleanVertices(addedPoints);
|
||||||
return r0 && r1 && r2;
|
return r0 && r1 && r2;
|
||||||
}
|
}
|
||||||
bool ICHull::CleanEdges()
|
bool ICHull::CleanEdges()
|
||||||
{
|
{
|
||||||
// integrate the new faces into the data structure
|
// integrate the new faces into the data structure
|
||||||
CircularListElement<TMMEdge> * e;
|
CircularListElement<TMMEdge> *e;
|
||||||
const std::vector<CircularListElement<TMMEdge> *>::iterator itEndUpdate = m_edgesToUpdate.end();
|
const std::vector<CircularListElement<TMMEdge> *>::iterator itEndUpdate = m_edgesToUpdate.end();
|
||||||
for(std::vector<CircularListElement<TMMEdge> *>::iterator it = m_edgesToUpdate.begin(); it != itEndUpdate; ++it)
|
for (std::vector<CircularListElement<TMMEdge> *>::iterator it = m_edgesToUpdate.begin(); it != itEndUpdate; ++it)
|
||||||
{
|
{
|
||||||
e = *it;
|
e = *it;
|
||||||
if ( e->GetData().m_newFace )
|
if (e->GetData().m_newFace)
|
||||||
{
|
{
|
||||||
if ( e->GetData().m_triangles[0]->GetData().m_visible)
|
if (e->GetData().m_triangles[0]->GetData().m_visible)
|
||||||
{
|
{
|
||||||
e->GetData().m_triangles[0] = e->GetData().m_newFace;
|
e->GetData().m_triangles[0] = e->GetData().m_newFace;
|
||||||
}
|
}
|
||||||
@@ -681,21 +685,21 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// delete edges maked for deletion
|
// delete edges maked for deletion
|
||||||
CircularList<TMMEdge> & edges = m_mesh.GetEdges();
|
CircularList<TMMEdge> &edges = m_mesh.GetEdges();
|
||||||
const std::vector<CircularListElement<TMMEdge> *>::iterator itEndDelete = m_edgesToDelete.end();
|
const std::vector<CircularListElement<TMMEdge> *>::iterator itEndDelete = m_edgesToDelete.end();
|
||||||
for(std::vector<CircularListElement<TMMEdge> *>::iterator it = m_edgesToDelete.begin(); it != itEndDelete; ++it)
|
for (std::vector<CircularListElement<TMMEdge> *>::iterator it = m_edgesToDelete.begin(); it != itEndDelete; ++it)
|
||||||
{
|
{
|
||||||
edges.Delete(*it);
|
edges.Delete(*it);
|
||||||
}
|
}
|
||||||
m_edgesToDelete.clear();
|
m_edgesToDelete.clear();
|
||||||
m_edgesToUpdate.clear();
|
m_edgesToUpdate.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ICHull::CleanTriangles()
|
bool ICHull::CleanTriangles()
|
||||||
{
|
{
|
||||||
CircularList<TMMTriangle> & triangles = m_mesh.GetTriangles();
|
CircularList<TMMTriangle> &triangles = m_mesh.GetTriangles();
|
||||||
const std::vector<CircularListElement<TMMTriangle> *>::iterator itEndDelete = m_trianglesToDelete.end();
|
const std::vector<CircularListElement<TMMTriangle> *>::iterator itEndDelete = m_trianglesToDelete.end();
|
||||||
for(std::vector<CircularListElement<TMMTriangle> *>::iterator it = m_trianglesToDelete.begin(); it != itEndDelete; ++it)
|
for (std::vector<CircularListElement<TMMTriangle> *>::iterator it = m_trianglesToDelete.begin(); it != itEndDelete; ++it)
|
||||||
{
|
{
|
||||||
if (m_distPoints)
|
if (m_distPoints)
|
||||||
{
|
{
|
||||||
@@ -708,7 +712,7 @@ namespace HACD
|
|||||||
std::set<long>::const_iterator itPEnd((*it)->GetData().m_incidentPoints.end());
|
std::set<long>::const_iterator itPEnd((*it)->GetData().m_incidentPoints.end());
|
||||||
std::set<long>::const_iterator itP((*it)->GetData().m_incidentPoints.begin());
|
std::set<long>::const_iterator itP((*it)->GetData().m_incidentPoints.begin());
|
||||||
std::map<long, DPoint>::iterator itPoint;
|
std::map<long, DPoint>::iterator itPoint;
|
||||||
for(; itP != itPEnd; ++itP)
|
for (; itP != itPEnd; ++itP)
|
||||||
{
|
{
|
||||||
itPoint = m_distPoints->find(*itP);
|
itPoint = m_distPoints->find(*itP);
|
||||||
if (itPoint != m_distPoints->end())
|
if (itPoint != m_distPoints->end())
|
||||||
@@ -722,29 +726,29 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
m_trianglesToDelete.clear();
|
m_trianglesToDelete.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ICHull::CleanVertices(unsigned long & addedPoints)
|
bool ICHull::CleanVertices(unsigned long &addedPoints)
|
||||||
{
|
{
|
||||||
// mark all vertices incident to some undeleted edge as on the hull
|
// mark all vertices incident to some undeleted edge as on the hull
|
||||||
CircularList<TMMEdge> & edges = m_mesh.GetEdges();
|
CircularList<TMMEdge> &edges = m_mesh.GetEdges();
|
||||||
CircularListElement<TMMEdge> * e = edges.GetHead();
|
CircularListElement<TMMEdge> *e = edges.GetHead();
|
||||||
size_t nE = edges.GetSize();
|
size_t nE = edges.GetSize();
|
||||||
for(size_t i = 0; i < nE; i++)
|
for (size_t i = 0; i < nE; i++)
|
||||||
{
|
{
|
||||||
e->GetData().m_vertices[0]->GetData().m_onHull = true;
|
e->GetData().m_vertices[0]->GetData().m_onHull = true;
|
||||||
e->GetData().m_vertices[1]->GetData().m_onHull = true;
|
e->GetData().m_vertices[1]->GetData().m_onHull = true;
|
||||||
e = e->GetNext();
|
e = e->GetNext();
|
||||||
}
|
}
|
||||||
// delete all the vertices that have been processed but are not on the hull
|
// delete all the vertices that have been processed but are not on the hull
|
||||||
CircularList<TMMVertex> & vertices = m_mesh.GetVertices();
|
CircularList<TMMVertex> &vertices = m_mesh.GetVertices();
|
||||||
CircularListElement<TMMVertex> * vHead = vertices.GetHead();
|
CircularListElement<TMMVertex> *vHead = vertices.GetHead();
|
||||||
CircularListElement<TMMVertex> * v = vHead;
|
CircularListElement<TMMVertex> *v = vHead;
|
||||||
v = v->GetPrev();
|
v = v->GetPrev();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (v->GetData().m_tag && !v->GetData().m_onHull)
|
if (v->GetData().m_tag && !v->GetData().m_onHull)
|
||||||
{
|
{
|
||||||
CircularListElement<TMMVertex> * tmp = v->GetPrev();
|
CircularListElement<TMMVertex> *tmp = v->GetPrev();
|
||||||
if (tmp == m_dummyVertex)
|
if (tmp == m_dummyVertex)
|
||||||
m_dummyVertex = 0;
|
m_dummyVertex = 0;
|
||||||
vertices.Delete(v);
|
vertices.Delete(v);
|
||||||
@@ -757,20 +761,19 @@ namespace HACD
|
|||||||
v->GetData().m_onHull = false;
|
v->GetData().m_onHull = false;
|
||||||
v = v->GetPrev();
|
v = v->GetPrev();
|
||||||
}
|
}
|
||||||
}
|
} while (v->GetData().m_tag && v != vHead);
|
||||||
while (v->GetData().m_tag && v != vHead);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void ICHull::Clear()
|
void ICHull::Clear()
|
||||||
{
|
{
|
||||||
m_mesh.Clear();
|
m_mesh.Clear();
|
||||||
m_edgesToDelete = std::vector<CircularListElement<TMMEdge> *>();
|
m_edgesToDelete = std::vector<CircularListElement<TMMEdge> *>();
|
||||||
m_edgesToUpdate = std::vector<CircularListElement<TMMEdge> *>();
|
m_edgesToUpdate = std::vector<CircularListElement<TMMEdge> *>();
|
||||||
m_trianglesToDelete= std::vector<CircularListElement<TMMTriangle> *>();
|
m_trianglesToDelete = std::vector<CircularListElement<TMMTriangle> *>();
|
||||||
m_isFlat = false;
|
m_isFlat = false;
|
||||||
}
|
}
|
||||||
const ICHull & ICHull::operator=(ICHull & rhs)
|
const ICHull &ICHull::operator=(ICHull &rhs)
|
||||||
{
|
{
|
||||||
if (&rhs != this)
|
if (&rhs != this)
|
||||||
{
|
{
|
||||||
m_mesh.Copy(rhs.m_mesh);
|
m_mesh.Copy(rhs.m_mesh);
|
||||||
@@ -780,16 +783,16 @@ namespace HACD
|
|||||||
m_isFlat = rhs.m_isFlat;
|
m_isFlat = rhs.m_isFlat;
|
||||||
}
|
}
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
double ICHull::ComputeVolume()
|
double ICHull::ComputeVolume()
|
||||||
{
|
{
|
||||||
size_t nV = m_mesh.m_vertices.GetSize();
|
size_t nV = m_mesh.m_vertices.GetSize();
|
||||||
if (nV == 0 || m_isFlat)
|
if (nV == 0 || m_isFlat)
|
||||||
{
|
{
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
Vec3<double> bary(0.0, 0.0, 0.0);
|
Vec3<double> bary(0.0, 0.0, 0.0);
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
bary.X() += m_mesh.m_vertices.GetHead()->GetData().m_pos.X();
|
bary.X() += m_mesh.m_vertices.GetHead()->GetData().m_pos.X();
|
||||||
bary.Y() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Y();
|
bary.Y() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Y();
|
||||||
@@ -801,7 +804,7 @@ namespace HACD
|
|||||||
size_t nT = m_mesh.m_triangles.GetSize();
|
size_t nT = m_mesh.m_triangles.GetSize();
|
||||||
Vec3<double> ver0, ver1, ver2;
|
Vec3<double> ver0, ver1, ver2;
|
||||||
double totalVolume = 0.0;
|
double totalVolume = 0.0;
|
||||||
for(size_t t = 0; t < nT; t++)
|
for (size_t t = 0; t < nT; t++)
|
||||||
{
|
{
|
||||||
ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
|
ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
|
||||||
ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
|
ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
|
||||||
@@ -816,16 +819,16 @@ namespace HACD
|
|||||||
m_mesh.m_triangles.Next();
|
m_mesh.m_triangles.Next();
|
||||||
}
|
}
|
||||||
return totalVolume;
|
return totalVolume;
|
||||||
}
|
}
|
||||||
bool ICHull::IsInside(const Vec3<Real> & pt0)
|
bool ICHull::IsInside(const Vec3<Real> &pt0)
|
||||||
{
|
{
|
||||||
const Vec3<double> pt(pt0.X(), pt0.Y(), pt0.Z());
|
const Vec3<double> pt(pt0.X(), pt0.Y(), pt0.Z());
|
||||||
if (m_isFlat)
|
if (m_isFlat)
|
||||||
{
|
{
|
||||||
size_t nT = m_mesh.m_triangles.GetSize();
|
size_t nT = m_mesh.m_triangles.GetSize();
|
||||||
Vec3<double> ver0, ver1, ver2, a, b, c;
|
Vec3<double> ver0, ver1, ver2, a, b, c;
|
||||||
double u,v;
|
double u, v;
|
||||||
for(size_t t = 0; t < nT; t++)
|
for (size_t t = 0; t < nT; t++)
|
||||||
{
|
{
|
||||||
ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
|
ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
|
||||||
ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
|
ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
|
||||||
@@ -841,7 +844,7 @@ namespace HACD
|
|||||||
c = pt - ver0;
|
c = pt - ver0;
|
||||||
u = c * a;
|
u = c * a;
|
||||||
v = c * b;
|
v = c * b;
|
||||||
if ( u >= 0.0 && u <= 1.0 && v >= 0.0 && u+v <= 1.0)
|
if (u >= 0.0 && u <= 1.0 && v >= 0.0 && u + v <= 1.0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -853,7 +856,7 @@ namespace HACD
|
|||||||
{
|
{
|
||||||
size_t nT = m_mesh.m_triangles.GetSize();
|
size_t nT = m_mesh.m_triangles.GetSize();
|
||||||
Vec3<double> ver0, ver1, ver2;
|
Vec3<double> ver0, ver1, ver2;
|
||||||
for(size_t t = 0; t < nT; t++)
|
for (size_t t = 0; t < nT; t++)
|
||||||
{
|
{
|
||||||
ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
|
ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
|
||||||
ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
|
ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
|
||||||
@@ -872,13 +875,13 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double ICHull::ComputeDistance(long name, const Vec3<Real> & pt, const Vec3<Real> & normal, bool & insideHull, bool updateIncidentPoints)
|
double ICHull::ComputeDistance(long name, const Vec3<Real> &pt, const Vec3<Real> &normal, bool &insideHull, bool updateIncidentPoints)
|
||||||
{
|
{
|
||||||
Vec3<double> ptNormal(static_cast<double>(normal.X()),
|
Vec3<double> ptNormal(static_cast<double>(normal.X()),
|
||||||
static_cast<double>(normal.Y()),
|
static_cast<double>(normal.Y()),
|
||||||
static_cast<double>(normal.Z()));
|
static_cast<double>(normal.Z()));
|
||||||
Vec3<double> p0( static_cast<double>(pt.X()),
|
Vec3<double> p0(static_cast<double>(pt.X()),
|
||||||
static_cast<double>(pt.Y()),
|
static_cast<double>(pt.Y()),
|
||||||
static_cast<double>(pt.Z()));
|
static_cast<double>(pt.Z()));
|
||||||
|
|
||||||
@@ -900,14 +903,14 @@ namespace HACD
|
|||||||
double mua, mub, s;
|
double mua, mub, s;
|
||||||
const double EPS = 0.00000000001;
|
const double EPS = 0.00000000001;
|
||||||
size_t nE = m_mesh.GetNEdges();
|
size_t nE = m_mesh.GetNEdges();
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData();
|
TMMEdge ¤tEdge = m_mesh.m_edges.GetHead()->GetData();
|
||||||
nameVE1 = currentEdge.m_vertices[0]->GetData().m_name;
|
nameVE1 = currentEdge.m_vertices[0]->GetData().m_name;
|
||||||
nameVE2 = currentEdge.m_vertices[1]->GetData().m_name;
|
nameVE2 = currentEdge.m_vertices[1]->GetData().m_name;
|
||||||
if (currentEdge.m_triangles[0] == 0 || currentEdge.m_triangles[1] == 0)
|
if (currentEdge.m_triangles[0] == 0 || currentEdge.m_triangles[1] == 0)
|
||||||
{
|
{
|
||||||
if ( nameVE1==name || nameVE2==name )
|
if (nameVE1 == name || nameVE2 == name)
|
||||||
{
|
{
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
@@ -930,10 +933,10 @@ namespace HACD
|
|||||||
d1 = pa - p2;
|
d1 = pa - p2;
|
||||||
d2 = pa - pb;
|
d2 = pa - pb;
|
||||||
d3 = pa - p0;
|
d3 = pa - p0;
|
||||||
mua = d1.GetNorm()/d0.GetNorm();
|
mua = d1.GetNorm() / d0.GetNorm();
|
||||||
mub = d1*d0;
|
mub = d1 * d0;
|
||||||
s = d3*ptNormal;
|
s = d3 * ptNormal;
|
||||||
if (d2.GetNorm() < EPS && mua <= 1.0 && mub>=0.0 && s>0.0)
|
if (d2.GetNorm() < EPS && mua <= 1.0 && mub >= 0.0 && s > 0.0)
|
||||||
{
|
{
|
||||||
distance = std::max<double>(distance, d3.GetNorm());
|
distance = std::max<double>(distance, d3.GetNorm());
|
||||||
}
|
}
|
||||||
@@ -957,11 +960,11 @@ namespace HACD
|
|||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
size_t nT = m_mesh.GetNTriangles();
|
size_t nT = m_mesh.GetNTriangles();
|
||||||
insideHull = false;
|
insideHull = false;
|
||||||
CircularListElement<TMMTriangle> * face = 0;
|
CircularListElement<TMMTriangle> *face = 0;
|
||||||
Vec3<double> ver0, ver1, ver2;
|
Vec3<double> ver0, ver1, ver2;
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData();
|
TMMTriangle ¤tTriangle = m_mesh.m_triangles.GetHead()->GetData();
|
||||||
/*
|
/*
|
||||||
if (debug) std::cout << "T " << currentTriangle.m_vertices[0]->GetData().m_name << " "
|
if (debug) std::cout << "T " << currentTriangle.m_vertices[0]->GetData().m_name << " "
|
||||||
<< currentTriangle.m_vertices[1]->GetData().m_name << " "
|
<< currentTriangle.m_vertices[1]->GetData().m_name << " "
|
||||||
@@ -993,7 +996,7 @@ namespace HACD
|
|||||||
distance = dist;
|
distance = dist;
|
||||||
insideHull = true;
|
insideHull = true;
|
||||||
face = m_mesh.m_triangles.GetHead();
|
face = m_mesh.m_triangles.GetHead();
|
||||||
/*
|
/*
|
||||||
std::cout << name << " -> T " << currentTriangle.m_vertices[0]->GetData().m_name << " "
|
std::cout << name << " -> T " << currentTriangle.m_vertices[0]->GetData().m_name << " "
|
||||||
<< currentTriangle.m_vertices[1]->GetData().m_name << " "
|
<< currentTriangle.m_vertices[1]->GetData().m_name << " "
|
||||||
<< currentTriangle.m_vertices[2]->GetData().m_name << " Dist "
|
<< currentTriangle.m_vertices[2]->GetData().m_name << " Dist "
|
||||||
@@ -1013,7 +1016,5 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace HACD
|
||||||
|
|
||||||
|
|||||||
@@ -22,35 +22,35 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
class DPoint;
|
class DPoint;
|
||||||
class HACD;
|
class HACD;
|
||||||
//! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ).
|
//! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ).
|
||||||
enum ICHullError
|
enum ICHullError
|
||||||
{
|
{
|
||||||
ICHullErrorOK = 0,
|
ICHullErrorOK = 0,
|
||||||
ICHullErrorCoplanarPoints,
|
ICHullErrorCoplanarPoints,
|
||||||
ICHullErrorNoVolume,
|
ICHullErrorNoVolume,
|
||||||
ICHullErrorInconsistent,
|
ICHullErrorInconsistent,
|
||||||
ICHullErrorNotEnoughPoints
|
ICHullErrorNotEnoughPoints
|
||||||
};
|
};
|
||||||
class ICHull
|
class ICHull
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//!
|
//!
|
||||||
bool IsFlat() { return m_isFlat;}
|
bool IsFlat() { return m_isFlat; }
|
||||||
//!
|
//!
|
||||||
std::map<long, DPoint> * GetDistPoints() const { return m_distPoints;}
|
std::map<long, DPoint> *GetDistPoints() const { return m_distPoints; }
|
||||||
//!
|
//!
|
||||||
void SetDistPoints(std::map<long, DPoint> * distPoints) { m_distPoints = distPoints;}
|
void SetDistPoints(std::map<long, DPoint> *distPoints) { m_distPoints = distPoints; }
|
||||||
//! Returns the computed mesh
|
//! Returns the computed mesh
|
||||||
TMMesh & GetMesh() { return m_mesh;}
|
TMMesh &GetMesh() { return m_mesh; }
|
||||||
//! Add one point to the convex-hull
|
//! Add one point to the convex-hull
|
||||||
bool AddPoint(const Vec3<Real> & point) {return AddPoints(&point, 1);}
|
bool AddPoint(const Vec3<Real> &point) { return AddPoints(&point, 1); }
|
||||||
//! Add one point to the convex-hull
|
//! Add one point to the convex-hull
|
||||||
bool AddPoint(const Vec3<Real> & point, long id);
|
bool AddPoint(const Vec3<Real> &point, long id);
|
||||||
//! Add points to the convex-hull
|
//! Add points to the convex-hull
|
||||||
bool AddPoints(const Vec3<Real> * points, size_t nPoints);
|
bool AddPoints(const Vec3<Real> *points, size_t nPoints);
|
||||||
bool AddPoints(std::vector< Vec3<Real> > points);
|
bool AddPoints(std::vector<Vec3<Real> > points);
|
||||||
//!
|
//!
|
||||||
ICHullError Process();
|
ICHullError Process();
|
||||||
//!
|
//!
|
||||||
@@ -58,27 +58,27 @@ namespace HACD
|
|||||||
//!
|
//!
|
||||||
double ComputeVolume();
|
double ComputeVolume();
|
||||||
//!
|
//!
|
||||||
bool IsInside(const Vec3<Real> & pt0);
|
bool IsInside(const Vec3<Real> &pt0);
|
||||||
//!
|
//!
|
||||||
double ComputeDistance(long name, const Vec3<Real> & pt, const Vec3<Real> & normal, bool & insideHull, bool updateIncidentPoints);
|
double ComputeDistance(long name, const Vec3<Real> &pt, const Vec3<Real> &normal, bool &insideHull, bool updateIncidentPoints);
|
||||||
//!
|
//!
|
||||||
const ICHull & operator=(ICHull & rhs);
|
const ICHull &operator=(ICHull &rhs);
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
ICHull(void);
|
ICHull(void);
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~ICHull(void) {};
|
virtual ~ICHull(void){};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up.
|
//! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up.
|
||||||
ICHullError DoubleTriangle();
|
ICHullError DoubleTriangle();
|
||||||
//! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face.
|
//! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face.
|
||||||
CircularListElement<TMMTriangle> * MakeFace(CircularListElement<TMMVertex> * v0,
|
CircularListElement<TMMTriangle> *MakeFace(CircularListElement<TMMVertex> *v0,
|
||||||
CircularListElement<TMMVertex> * v1,
|
CircularListElement<TMMVertex> *v1,
|
||||||
CircularListElement<TMMVertex> * v2,
|
CircularListElement<TMMVertex> *v2,
|
||||||
CircularListElement<TMMTriangle> * fold);
|
CircularListElement<TMMTriangle> *fold);
|
||||||
//!
|
//!
|
||||||
CircularListElement<TMMTriangle> * MakeConeFace(CircularListElement<TMMEdge> * e, CircularListElement<TMMVertex> * v);
|
CircularListElement<TMMTriangle> *MakeConeFace(CircularListElement<TMMEdge> *e, CircularListElement<TMMVertex> *v);
|
||||||
//!
|
//!
|
||||||
bool ProcessPoint();
|
bool ProcessPoint();
|
||||||
//!
|
//!
|
||||||
@@ -88,33 +88,33 @@ namespace HACD
|
|||||||
//!
|
//!
|
||||||
bool CleanEdges();
|
bool CleanEdges();
|
||||||
//!
|
//!
|
||||||
bool CleanVertices(unsigned long & addedPoints);
|
bool CleanVertices(unsigned long &addedPoints);
|
||||||
//!
|
//!
|
||||||
bool CleanTriangles();
|
bool CleanTriangles();
|
||||||
//!
|
//!
|
||||||
bool CleanUp(unsigned long & addedPoints);
|
bool CleanUp(unsigned long &addedPoints);
|
||||||
//!
|
//!
|
||||||
bool MakeCCW(CircularListElement<TMMTriangle> * f,
|
bool MakeCCW(CircularListElement<TMMTriangle> *f,
|
||||||
CircularListElement<TMMEdge> * e,
|
CircularListElement<TMMEdge> *e,
|
||||||
CircularListElement<TMMVertex> * v);
|
CircularListElement<TMMVertex> *v);
|
||||||
void Clear();
|
void Clear();
|
||||||
private:
|
|
||||||
|
private:
|
||||||
static const long sc_dummyIndex;
|
static const long sc_dummyIndex;
|
||||||
static const double sc_distMin;
|
static const double sc_distMin;
|
||||||
TMMesh m_mesh;
|
TMMesh m_mesh;
|
||||||
std::vector<CircularListElement<TMMEdge> *> m_edgesToDelete;
|
std::vector<CircularListElement<TMMEdge> *> m_edgesToDelete;
|
||||||
std::vector<CircularListElement<TMMEdge> *> m_edgesToUpdate;
|
std::vector<CircularListElement<TMMEdge> *> m_edgesToUpdate;
|
||||||
std::vector<CircularListElement<TMMTriangle> *> m_trianglesToDelete;
|
std::vector<CircularListElement<TMMTriangle> *> m_trianglesToDelete;
|
||||||
std::map<long, DPoint> * m_distPoints;
|
std::map<long, DPoint> *m_distPoints;
|
||||||
CircularListElement<TMMVertex> * m_dummyVertex;
|
CircularListElement<TMMVertex> *m_dummyVertex;
|
||||||
Vec3<Real> m_normal;
|
Vec3<Real> m_normal;
|
||||||
bool m_isFlat;
|
bool m_isFlat;
|
||||||
|
|
||||||
|
ICHull(const ICHull &rhs);
|
||||||
ICHull(const ICHull & rhs);
|
|
||||||
|
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace HACD
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,11 +15,10 @@
|
|||||||
#include "hacdManifoldMesh.h"
|
#include "hacdManifoldMesh.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
Material::Material(void)
|
Material::Material(void)
|
||||||
{
|
{
|
||||||
m_diffuseColor.X() = 0.5;
|
m_diffuseColor.X() = 0.5;
|
||||||
m_diffuseColor.Y() = 0.5;
|
m_diffuseColor.Y() = 0.5;
|
||||||
m_diffuseColor.Z() = 0.5;
|
m_diffuseColor.Z() = 0.5;
|
||||||
@@ -32,58 +31,58 @@ namespace HACD
|
|||||||
m_emissiveColor.Z() = 0.0;
|
m_emissiveColor.Z() = 0.0;
|
||||||
m_shininess = 0.4;
|
m_shininess = 0.4;
|
||||||
m_transparency = 0.0;
|
m_transparency = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TMMVertex::TMMVertex(void)
|
TMMVertex::TMMVertex(void)
|
||||||
{
|
{
|
||||||
m_name = 0;
|
m_name = 0;
|
||||||
m_id = 0;
|
m_id = 0;
|
||||||
m_duplicate = 0;
|
m_duplicate = 0;
|
||||||
m_onHull = false;
|
m_onHull = false;
|
||||||
m_tag = false;
|
m_tag = false;
|
||||||
}
|
}
|
||||||
TMMVertex::~TMMVertex(void)
|
TMMVertex::~TMMVertex(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
TMMEdge::TMMEdge(void)
|
TMMEdge::TMMEdge(void)
|
||||||
{
|
{
|
||||||
m_id = 0;
|
m_id = 0;
|
||||||
m_triangles[0] = m_triangles[1] = m_newFace = 0;
|
m_triangles[0] = m_triangles[1] = m_newFace = 0;
|
||||||
m_vertices[0] = m_vertices[1] = 0;
|
m_vertices[0] = m_vertices[1] = 0;
|
||||||
}
|
}
|
||||||
TMMEdge::~TMMEdge(void)
|
TMMEdge::~TMMEdge(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
TMMTriangle::TMMTriangle(void)
|
TMMTriangle::TMMTriangle(void)
|
||||||
{
|
{
|
||||||
m_id = 0;
|
m_id = 0;
|
||||||
for(int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
m_edges[i] = 0;
|
m_edges[i] = 0;
|
||||||
m_vertices[0] = 0;
|
m_vertices[0] = 0;
|
||||||
}
|
}
|
||||||
m_visible = false;
|
m_visible = false;
|
||||||
}
|
}
|
||||||
TMMTriangle::~TMMTriangle(void)
|
TMMTriangle::~TMMTriangle(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
TMMesh::TMMesh(void)
|
TMMesh::TMMesh(void)
|
||||||
{
|
{
|
||||||
m_barycenter = Vec3<Real>(0,0,0);
|
m_barycenter = Vec3<Real>(0, 0, 0);
|
||||||
m_diag = 1;
|
m_diag = 1;
|
||||||
}
|
}
|
||||||
TMMesh::~TMMesh(void)
|
TMMesh::~TMMesh(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMMesh::Print()
|
void TMMesh::Print()
|
||||||
{
|
{
|
||||||
size_t nV = m_vertices.GetSize();
|
size_t nV = m_vertices.GetSize();
|
||||||
std::cout << "-----------------------------" << std::endl;
|
std::cout << "-----------------------------" << std::endl;
|
||||||
std::cout << "vertices (" << nV << ")" << std::endl;
|
std::cout << "vertices (" << nV << ")" << std::endl;
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
const TMMVertex & currentVertex = m_vertices.GetData();
|
const TMMVertex ¤tVertex = m_vertices.GetData();
|
||||||
std::cout << currentVertex.m_id << ", "
|
std::cout << currentVertex.m_id << ", "
|
||||||
<< currentVertex.m_pos.X() << ", "
|
<< currentVertex.m_pos.X() << ", "
|
||||||
<< currentVertex.m_pos.Y() << ", "
|
<< currentVertex.m_pos.Y() << ", "
|
||||||
@@ -91,21 +90,20 @@ namespace HACD
|
|||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t nE = m_edges.GetSize();
|
size_t nE = m_edges.GetSize();
|
||||||
std::cout << "edges (" << nE << ")" << std::endl;
|
std::cout << "edges (" << nE << ")" << std::endl;
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
const TMMEdge & currentEdge = m_edges.GetData();
|
const TMMEdge ¤tEdge = m_edges.GetData();
|
||||||
const CircularListElement<TMMVertex> * v0 = currentEdge.m_vertices[0];
|
const CircularListElement<TMMVertex> *v0 = currentEdge.m_vertices[0];
|
||||||
const CircularListElement<TMMVertex> * v1 = currentEdge.m_vertices[1];
|
const CircularListElement<TMMVertex> *v1 = currentEdge.m_vertices[1];
|
||||||
const CircularListElement<TMMTriangle> * f0 = currentEdge.m_triangles[0];
|
const CircularListElement<TMMTriangle> *f0 = currentEdge.m_triangles[0];
|
||||||
const CircularListElement<TMMTriangle> * f1 = currentEdge.m_triangles[1];
|
const CircularListElement<TMMTriangle> *f1 = currentEdge.m_triangles[1];
|
||||||
|
|
||||||
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl;
|
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl;
|
||||||
std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", "
|
std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
<< f0->GetData().m_vertices[1]->GetData().m_name << ", "
|
<< f0->GetData().m_vertices[1]->GetData().m_name << ", "
|
||||||
<< f0->GetData().m_vertices[2]->GetData().m_name <<")" << std::endl;
|
<< f0->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl;
|
||||||
std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", "
|
std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
<< f1->GetData().m_vertices[1]->GetData().m_name << ", "
|
<< f1->GetData().m_vertices[1]->GetData().m_name << ", "
|
||||||
<< f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl;
|
<< f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl;
|
||||||
@@ -113,17 +111,17 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
size_t nT = m_triangles.GetSize();
|
size_t nT = m_triangles.GetSize();
|
||||||
std::cout << "triangles (" << nT << ")" << std::endl;
|
std::cout << "triangles (" << nT << ")" << std::endl;
|
||||||
for(size_t t = 0; t < nT; t++)
|
for (size_t t = 0; t < nT; t++)
|
||||||
{
|
{
|
||||||
const TMMTriangle & currentTriangle = m_triangles.GetData();
|
const TMMTriangle ¤tTriangle = m_triangles.GetData();
|
||||||
const CircularListElement<TMMVertex> * v0 = currentTriangle.m_vertices[0];
|
const CircularListElement<TMMVertex> *v0 = currentTriangle.m_vertices[0];
|
||||||
const CircularListElement<TMMVertex> * v1 = currentTriangle.m_vertices[1];
|
const CircularListElement<TMMVertex> *v1 = currentTriangle.m_vertices[1];
|
||||||
const CircularListElement<TMMVertex> * v2 = currentTriangle.m_vertices[2];
|
const CircularListElement<TMMVertex> *v2 = currentTriangle.m_vertices[2];
|
||||||
const CircularListElement<TMMEdge> * e0 = currentTriangle.m_edges[0];
|
const CircularListElement<TMMEdge> *e0 = currentTriangle.m_edges[0];
|
||||||
const CircularListElement<TMMEdge> * e1 = currentTriangle.m_edges[1];
|
const CircularListElement<TMMEdge> *e1 = currentTriangle.m_edges[1];
|
||||||
const CircularListElement<TMMEdge> * e2 = currentTriangle.m_edges[2];
|
const CircularListElement<TMMEdge> *e2 = currentTriangle.m_edges[2];
|
||||||
|
|
||||||
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", "<< v2->GetData().m_name << ")" << std::endl;
|
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", " << v2->GetData().m_name << ")" << std::endl;
|
||||||
|
|
||||||
std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", "
|
std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
<< e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
<< e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
||||||
@@ -133,9 +131,9 @@ namespace HACD
|
|||||||
<< e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
<< e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
||||||
m_triangles.Next();
|
m_triangles.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool TMMesh::Save(const char *fileName)
|
bool TMMesh::Save(const char *fileName)
|
||||||
{
|
{
|
||||||
std::ofstream fout(fileName);
|
std::ofstream fout(fileName);
|
||||||
std::cout << "Saving " << fileName << std::endl;
|
std::cout << "Saving " << fileName << std::endl;
|
||||||
if (SaveVRML2(fout))
|
if (SaveVRML2(fout))
|
||||||
@@ -144,124 +142,125 @@ namespace HACD
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool TMMesh::SaveVRML2(std::ofstream &fout)
|
bool TMMesh::SaveVRML2(std::ofstream &fout)
|
||||||
{
|
{
|
||||||
return SaveVRML2(fout, Material());
|
return SaveVRML2(fout, Material());
|
||||||
}
|
}
|
||||||
bool TMMesh::SaveVRML2(std::ofstream &fout, const Material & material)
|
bool TMMesh::SaveVRML2(std::ofstream &fout, const Material &material)
|
||||||
{
|
{
|
||||||
if (fout.is_open())
|
if (fout.is_open())
|
||||||
{
|
{
|
||||||
size_t nV = m_vertices.GetSize();
|
size_t nV = m_vertices.GetSize();
|
||||||
size_t nT = m_triangles.GetSize();
|
size_t nT = m_triangles.GetSize();
|
||||||
fout <<"#VRML V2.0 utf8" << std::endl;
|
fout << "#VRML V2.0 utf8" << std::endl;
|
||||||
fout <<"" << std::endl;
|
fout << "" << std::endl;
|
||||||
fout <<"# Vertices: " << nV << std::endl;
|
fout << "# Vertices: " << nV << std::endl;
|
||||||
fout <<"# Triangles: " << nT << std::endl;
|
fout << "# Triangles: " << nT << std::endl;
|
||||||
fout <<"" << std::endl;
|
fout << "" << std::endl;
|
||||||
fout <<"Group {" << std::endl;
|
fout << "Group {" << std::endl;
|
||||||
fout <<" children [" << std::endl;
|
fout << " children [" << std::endl;
|
||||||
fout <<" Shape {" << std::endl;
|
fout << " Shape {" << std::endl;
|
||||||
fout <<" appearance Appearance {" << std::endl;
|
fout << " appearance Appearance {" << std::endl;
|
||||||
fout <<" material Material {" << std::endl;
|
fout << " material Material {" << std::endl;
|
||||||
fout <<" diffuseColor " << material.m_diffuseColor.X() << " "
|
fout << " diffuseColor " << material.m_diffuseColor.X() << " "
|
||||||
<< material.m_diffuseColor.Y() << " "
|
<< material.m_diffuseColor.Y() << " "
|
||||||
<< material.m_diffuseColor.Z() << std::endl;
|
<< material.m_diffuseColor.Z() << std::endl;
|
||||||
fout <<" ambientIntensity " << material.m_ambientIntensity << std::endl;
|
fout << " ambientIntensity " << material.m_ambientIntensity << std::endl;
|
||||||
fout <<" specularColor " << material.m_specularColor.X() << " "
|
fout << " specularColor " << material.m_specularColor.X() << " "
|
||||||
<< material.m_specularColor.Y() << " "
|
<< material.m_specularColor.Y() << " "
|
||||||
<< material.m_specularColor.Z() << std::endl;
|
<< material.m_specularColor.Z() << std::endl;
|
||||||
fout <<" emissiveColor " << material.m_emissiveColor.X() << " "
|
fout << " emissiveColor " << material.m_emissiveColor.X() << " "
|
||||||
<< material.m_emissiveColor.Y() << " "
|
<< material.m_emissiveColor.Y() << " "
|
||||||
<< material.m_emissiveColor.Z() << std::endl;
|
<< material.m_emissiveColor.Z() << std::endl;
|
||||||
fout <<" shininess " << material.m_shininess << std::endl;
|
fout << " shininess " << material.m_shininess << std::endl;
|
||||||
fout <<" transparency " << material.m_transparency << std::endl;
|
fout << " transparency " << material.m_transparency << std::endl;
|
||||||
fout <<" }" << std::endl;
|
fout << " }" << std::endl;
|
||||||
fout <<" }" << std::endl;
|
fout << " }" << std::endl;
|
||||||
fout <<" geometry IndexedFaceSet {" << std::endl;
|
fout << " geometry IndexedFaceSet {" << std::endl;
|
||||||
fout <<" ccw TRUE" << std::endl;
|
fout << " ccw TRUE" << std::endl;
|
||||||
fout <<" solid TRUE" << std::endl;
|
fout << " solid TRUE" << std::endl;
|
||||||
fout <<" convex TRUE" << std::endl;
|
fout << " convex TRUE" << std::endl;
|
||||||
if (GetNVertices() > 0) {
|
if (GetNVertices() > 0)
|
||||||
fout <<" coord DEF co Coordinate {" << std::endl;
|
|
||||||
fout <<" point [" << std::endl;
|
|
||||||
for(size_t v = 0; v < nV; v++)
|
|
||||||
{
|
{
|
||||||
TMMVertex & currentVertex = m_vertices.GetData();
|
fout << " coord DEF co Coordinate {" << std::endl;
|
||||||
fout <<" " << currentVertex.m_pos.X() << " "
|
fout << " point [" << std::endl;
|
||||||
|
for (size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
TMMVertex ¤tVertex = m_vertices.GetData();
|
||||||
|
fout << " " << currentVertex.m_pos.X() << " "
|
||||||
<< currentVertex.m_pos.Y() << " "
|
<< currentVertex.m_pos.Y() << " "
|
||||||
<< currentVertex.m_pos.Z() << "," << std::endl;
|
<< currentVertex.m_pos.Z() << "," << std::endl;
|
||||||
currentVertex.m_id = v;
|
currentVertex.m_id = v;
|
||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
fout <<" ]" << std::endl;
|
fout << " ]" << std::endl;
|
||||||
fout <<" }" << std::endl;
|
fout << " }" << std::endl;
|
||||||
}
|
}
|
||||||
if (GetNTriangles() > 0) {
|
if (GetNTriangles() > 0)
|
||||||
fout <<" coordIndex [ " << std::endl;
|
|
||||||
for(size_t f = 0; f < nT; f++)
|
|
||||||
{
|
{
|
||||||
TMMTriangle & currentTriangle = m_triangles.GetData();
|
fout << " coordIndex [ " << std::endl;
|
||||||
fout <<" " << currentTriangle.m_vertices[0]->GetData().m_id << ", "
|
for (size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
TMMTriangle ¤tTriangle = m_triangles.GetData();
|
||||||
|
fout << " " << currentTriangle.m_vertices[0]->GetData().m_id << ", "
|
||||||
<< currentTriangle.m_vertices[1]->GetData().m_id << ", "
|
<< currentTriangle.m_vertices[1]->GetData().m_id << ", "
|
||||||
<< currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl;
|
<< currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl;
|
||||||
m_triangles.Next();
|
m_triangles.Next();
|
||||||
}
|
}
|
||||||
fout <<" ]" << std::endl;
|
fout << " ]" << std::endl;
|
||||||
}
|
}
|
||||||
fout <<" }" << std::endl;
|
fout << " }" << std::endl;
|
||||||
fout <<" }" << std::endl;
|
fout << " }" << std::endl;
|
||||||
fout <<" ]" << std::endl;
|
fout << " ]" << std::endl;
|
||||||
fout <<"}" << std::endl;
|
fout << "}" << std::endl;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void TMMesh::GetIFS(Vec3<Real> * const points, Vec3<long> * const triangles)
|
void TMMesh::GetIFS(Vec3<Real> *const points, Vec3<long> *const triangles)
|
||||||
{
|
{
|
||||||
size_t nV = m_vertices.GetSize();
|
size_t nV = m_vertices.GetSize();
|
||||||
size_t nT = m_triangles.GetSize();
|
size_t nT = m_triangles.GetSize();
|
||||||
|
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
points[v] = m_vertices.GetData().m_pos;
|
points[v] = m_vertices.GetData().m_pos;
|
||||||
m_vertices.GetData().m_id = v;
|
m_vertices.GetData().m_id = v;
|
||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
TMMTriangle & currentTriangle = m_triangles.GetData();
|
TMMTriangle ¤tTriangle = m_triangles.GetData();
|
||||||
triangles[f].X() = static_cast<long>(currentTriangle.m_vertices[0]->GetData().m_id);
|
triangles[f].X() = static_cast<long>(currentTriangle.m_vertices[0]->GetData().m_id);
|
||||||
triangles[f].Y() = static_cast<long>(currentTriangle.m_vertices[1]->GetData().m_id);
|
triangles[f].Y() = static_cast<long>(currentTriangle.m_vertices[1]->GetData().m_id);
|
||||||
triangles[f].Z() = static_cast<long>(currentTriangle.m_vertices[2]->GetData().m_id);
|
triangles[f].Z() = static_cast<long>(currentTriangle.m_vertices[2]->GetData().m_id);
|
||||||
m_triangles.Next();
|
m_triangles.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TMMesh::Clear()
|
void TMMesh::Clear()
|
||||||
{
|
{
|
||||||
m_vertices.Clear();
|
m_vertices.Clear();
|
||||||
m_edges.Clear();
|
m_edges.Clear();
|
||||||
m_triangles.Clear();
|
m_triangles.Clear();
|
||||||
}
|
}
|
||||||
void TMMesh::Copy(TMMesh & mesh)
|
void TMMesh::Copy(TMMesh &mesh)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
// updating the id's
|
// updating the id's
|
||||||
size_t nV = mesh.m_vertices.GetSize();
|
size_t nV = mesh.m_vertices.GetSize();
|
||||||
size_t nE = mesh. m_edges.GetSize();
|
size_t nE = mesh.m_edges.GetSize();
|
||||||
size_t nT = mesh.m_triangles.GetSize();
|
size_t nT = mesh.m_triangles.GetSize();
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
mesh.m_vertices.GetData().m_id = v;
|
mesh.m_vertices.GetData().m_id = v;
|
||||||
mesh.m_vertices.Next();
|
mesh.m_vertices.Next();
|
||||||
}
|
}
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
mesh.m_edges.GetData().m_id = e;
|
mesh.m_edges.GetData().m_id = e;
|
||||||
mesh.m_edges.Next();
|
mesh.m_edges.Next();
|
||||||
|
|
||||||
}
|
}
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
mesh.m_triangles.GetData().m_id = f;
|
mesh.m_triangles.GetData().m_id = f;
|
||||||
mesh.m_triangles.Next();
|
mesh.m_triangles.Next();
|
||||||
@@ -272,34 +271,34 @@ namespace HACD
|
|||||||
m_triangles = mesh.m_triangles;
|
m_triangles = mesh.m_triangles;
|
||||||
|
|
||||||
// generating mapping
|
// generating mapping
|
||||||
CircularListElement<TMMVertex> ** vertexMap = new CircularListElement<TMMVertex> * [nV];
|
CircularListElement<TMMVertex> **vertexMap = new CircularListElement<TMMVertex> *[nV];
|
||||||
CircularListElement<TMMEdge> ** edgeMap = new CircularListElement<TMMEdge> * [nE];
|
CircularListElement<TMMEdge> **edgeMap = new CircularListElement<TMMEdge> *[nE];
|
||||||
CircularListElement<TMMTriangle> ** triangleMap = new CircularListElement<TMMTriangle> * [nT];
|
CircularListElement<TMMTriangle> **triangleMap = new CircularListElement<TMMTriangle> *[nT];
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
vertexMap[v] = m_vertices.GetHead();
|
vertexMap[v] = m_vertices.GetHead();
|
||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
edgeMap[e] = m_edges.GetHead();
|
edgeMap[e] = m_edges.GetHead();
|
||||||
m_edges.Next();
|
m_edges.Next();
|
||||||
}
|
}
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
triangleMap[f] = m_triangles.GetHead();
|
triangleMap[f] = m_triangles.GetHead();
|
||||||
m_triangles.Next();
|
m_triangles.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// updating pointers
|
// updating pointers
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
if (vertexMap[v]->GetData().m_duplicate)
|
if (vertexMap[v]->GetData().m_duplicate)
|
||||||
{
|
{
|
||||||
vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id];
|
vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
if (edgeMap[e]->GetData().m_newFace)
|
if (edgeMap[e]->GetData().m_newFace)
|
||||||
{
|
{
|
||||||
@@ -307,7 +306,7 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
if (nT > 0)
|
if (nT > 0)
|
||||||
{
|
{
|
||||||
for(int f = 0; f < 2; f++)
|
for (int f = 0; f < 2; f++)
|
||||||
{
|
{
|
||||||
if (edgeMap[e]->GetData().m_triangles[f])
|
if (edgeMap[e]->GetData().m_triangles[f])
|
||||||
{
|
{
|
||||||
@@ -315,7 +314,7 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int v = 0; v < 2; v++)
|
for (int v = 0; v < 2; v++)
|
||||||
{
|
{
|
||||||
if (edgeMap[e]->GetData().m_vertices[v])
|
if (edgeMap[e]->GetData().m_vertices[v])
|
||||||
{
|
{
|
||||||
@@ -323,11 +322,11 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
if (nE > 0)
|
if (nE > 0)
|
||||||
{
|
{
|
||||||
for(int e = 0; e < 3; e++)
|
for (int e = 0; e < 3; e++)
|
||||||
{
|
{
|
||||||
if (triangleMap[f]->GetData().m_edges[e])
|
if (triangleMap[f]->GetData().m_edges[e])
|
||||||
{
|
{
|
||||||
@@ -335,7 +334,7 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int v = 0; v < 3; v++)
|
for (int v = 0; v < 3; v++)
|
||||||
{
|
{
|
||||||
if (triangleMap[f]->GetData().m_vertices[v])
|
if (triangleMap[f]->GetData().m_vertices[v])
|
||||||
{
|
{
|
||||||
@@ -343,15 +342,14 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] vertexMap;
|
delete[] vertexMap;
|
||||||
delete [] edgeMap;
|
delete[] edgeMap;
|
||||||
delete [] triangleMap;
|
delete[] triangleMap;
|
||||||
|
}
|
||||||
}
|
long IntersectRayTriangle(const Vec3<double> &P0, const Vec3<double> &dir,
|
||||||
long IntersectRayTriangle(const Vec3<double> & P0, const Vec3<double> & dir,
|
const Vec3<double> &V0, const Vec3<double> &V1,
|
||||||
const Vec3<double> & V0, const Vec3<double> & V1,
|
const Vec3<double> &V2, double &t)
|
||||||
const Vec3<double> & V2, double &t)
|
{
|
||||||
{
|
|
||||||
Vec3<double> edge1, edge2, edge3;
|
Vec3<double> edge1, edge2, edge3;
|
||||||
double det, invDet;
|
double det, invDet;
|
||||||
edge1 = V1 - V2;
|
edge1 = V1 - V2;
|
||||||
@@ -360,7 +358,7 @@ namespace HACD
|
|||||||
det = edge1 * pvec;
|
det = edge1 * pvec;
|
||||||
if (det == 0.0)
|
if (det == 0.0)
|
||||||
return 0;
|
return 0;
|
||||||
invDet = 1.0/det;
|
invDet = 1.0 / det;
|
||||||
Vec3<double> tvec = P0 - V0;
|
Vec3<double> tvec = P0 - V0;
|
||||||
Vec3<double> qvec = tvec ^ edge1;
|
Vec3<double> qvec = tvec ^ edge1;
|
||||||
t = (edge2 * qvec) * invDet;
|
t = (edge2 * qvec) * invDet;
|
||||||
@@ -370,24 +368,24 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
edge3 = V0 - V1;
|
edge3 = V0 - V1;
|
||||||
Vec3<double> I(P0 + t * dir);
|
Vec3<double> I(P0 + t * dir);
|
||||||
Vec3<double> s0 = (I-V0) ^ edge3;
|
Vec3<double> s0 = (I - V0) ^ edge3;
|
||||||
Vec3<double> s1 = (I-V1) ^ edge1;
|
Vec3<double> s1 = (I - V1) ^ edge1;
|
||||||
Vec3<double> s2 = (I-V2) ^ edge2;
|
Vec3<double> s2 = (I - V2) ^ edge2;
|
||||||
if (s0*s1 > -1e-9 && s2*s1 > -1e-9)
|
if (s0 * s1 > -1e-9 && s2 * s1 > -1e-9)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IntersectLineLine(const Vec3<double> & p1, const Vec3<double> & p2,
|
bool IntersectLineLine(const Vec3<double> &p1, const Vec3<double> &p2,
|
||||||
const Vec3<double> & p3, const Vec3<double> & p4,
|
const Vec3<double> &p3, const Vec3<double> &p4,
|
||||||
Vec3<double> & pa, Vec3<double> & pb,
|
Vec3<double> &pa, Vec3<double> &pb,
|
||||||
double & mua, double & mub)
|
double &mua, double &mub)
|
||||||
{
|
{
|
||||||
Vec3<double> p13,p43,p21;
|
Vec3<double> p13, p43, p21;
|
||||||
double d1343,d4321,d1321,d4343,d2121;
|
double d1343, d4321, d1321, d4343, d2121;
|
||||||
double numer,denom;
|
double numer, denom;
|
||||||
|
|
||||||
p13.X() = p1.X() - p3.X();
|
p13.X() = p1.X() - p3.X();
|
||||||
p13.Y() = p1.Y() - p3.Y();
|
p13.Y() = p1.Y() - p3.Y();
|
||||||
@@ -395,12 +393,12 @@ namespace HACD
|
|||||||
p43.X() = p4.X() - p3.X();
|
p43.X() = p4.X() - p3.X();
|
||||||
p43.Y() = p4.Y() - p3.Y();
|
p43.Y() = p4.Y() - p3.Y();
|
||||||
p43.Z() = p4.Z() - p3.Z();
|
p43.Z() = p4.Z() - p3.Z();
|
||||||
if (p43.X()==0.0 && p43.Y()==0.0 && p43.Z()==0.0)
|
if (p43.X() == 0.0 && p43.Y() == 0.0 && p43.Z() == 0.0)
|
||||||
return false;
|
return false;
|
||||||
p21.X() = p2.X() - p1.X();
|
p21.X() = p2.X() - p1.X();
|
||||||
p21.Y() = p2.Y() - p1.Y();
|
p21.Y() = p2.Y() - p1.Y();
|
||||||
p21.Z() = p2.Z() - p1.Z();
|
p21.Z() = p2.Z() - p1.Z();
|
||||||
if (p21.X()==0.0 && p21.Y()==0.0 && p21.Z()==0.0)
|
if (p21.X() == 0.0 && p21.Y() == 0.0 && p21.Z() == 0.0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
|
d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
|
||||||
@@ -410,7 +408,7 @@ namespace HACD
|
|||||||
d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
|
d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
|
||||||
|
|
||||||
denom = d2121 * d4343 - d4321 * d4321;
|
denom = d2121 * d4343 - d4321 * d4321;
|
||||||
if (denom==0.0)
|
if (denom == 0.0)
|
||||||
return false;
|
return false;
|
||||||
numer = d1343 * d4321 - d1321 * d4343;
|
numer = d1343 * d4321 - d1321 * d4343;
|
||||||
|
|
||||||
@@ -425,12 +423,12 @@ namespace HACD
|
|||||||
pb.Z() = p3.Z() + mub * p43.Z();
|
pb.Z() = p3.Z() + mub * p43.Z();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
long IntersectRayTriangle2(const Vec3<double> & P0, const Vec3<double> & dir,
|
long IntersectRayTriangle2(const Vec3<double> &P0, const Vec3<double> &dir,
|
||||||
const Vec3<double> & V0, const Vec3<double> & V1,
|
const Vec3<double> &V0, const Vec3<double> &V1,
|
||||||
const Vec3<double> & V2, double &r)
|
const Vec3<double> &V2, double &r)
|
||||||
{
|
{
|
||||||
Vec3<double> u, v, n; // triangle vectors
|
Vec3<double> u, v, n; // triangle vectors
|
||||||
Vec3<double> w0, w; // ray vectors
|
Vec3<double> w0, w; // ray vectors
|
||||||
double a, b; // params to calc ray-plane intersect
|
double a, b; // params to calc ray-plane intersect
|
||||||
@@ -443,12 +441,14 @@ namespace HACD
|
|||||||
return -1; // do not deal with this case
|
return -1; // do not deal with this case
|
||||||
|
|
||||||
w0 = P0 - V0;
|
w0 = P0 - V0;
|
||||||
a = - n * w0;
|
a = -n * w0;
|
||||||
b = n * dir;
|
b = n * dir;
|
||||||
if (fabs(b) <= 0.0) { // ray is parallel to triangle plane
|
if (fabs(b) <= 0.0)
|
||||||
|
{ // ray is parallel to triangle plane
|
||||||
if (a == 0.0) // ray lies in triangle plane
|
if (a == 0.0) // ray lies in triangle plane
|
||||||
return 2;
|
return 2;
|
||||||
else return 0; // ray disjoint from plane
|
else
|
||||||
|
return 0; // ray disjoint from plane
|
||||||
}
|
}
|
||||||
|
|
||||||
// get intersect point of ray with triangle plane
|
// get intersect point of ray with triangle plane
|
||||||
@@ -478,16 +478,15 @@ namespace HACD
|
|||||||
if (t < 0.0 || (s + t) > 1.0) // I is outside T
|
if (t < 0.0 || (s + t) > 1.0) // I is outside T
|
||||||
return 0;
|
return 0;
|
||||||
return 1; // I is in T
|
return 1; // I is in T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TMMesh::CheckConsistancy()
|
||||||
bool TMMesh::CheckConsistancy()
|
{
|
||||||
{
|
|
||||||
size_t nE = m_edges.GetSize();
|
size_t nE = m_edges.GetSize();
|
||||||
size_t nT = m_triangles.GetSize();
|
size_t nT = m_triangles.GetSize();
|
||||||
for(size_t e = 0; e < nE; e++)
|
for (size_t e = 0; e < nE; e++)
|
||||||
{
|
{
|
||||||
for(int f = 0; f < 2; f++)
|
for (int f = 0; f < 2; f++)
|
||||||
{
|
{
|
||||||
if (!m_edges.GetHead()->GetData().m_triangles[f])
|
if (!m_edges.GetHead()->GetData().m_triangles[f])
|
||||||
{
|
{
|
||||||
@@ -497,12 +496,12 @@ namespace HACD
|
|||||||
m_edges.Next();
|
m_edges.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t f = 0; f < nT; f++)
|
for (size_t f = 0; f < nT; f++)
|
||||||
{
|
{
|
||||||
for(int e = 0; e < 3; e++)
|
for (int e = 0; e < 3; e++)
|
||||||
{
|
{
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for(int k = 0; k < 2; k++)
|
for (int k = 0; k < 2; k++)
|
||||||
{
|
{
|
||||||
if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead())
|
if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead())
|
||||||
{
|
{
|
||||||
@@ -518,9 +517,9 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool TMMesh::Normalize()
|
bool TMMesh::Normalize()
|
||||||
{
|
{
|
||||||
size_t nV = m_vertices.GetSize();
|
size_t nV = m_vertices.GetSize();
|
||||||
if (nV == 0)
|
if (nV == 0)
|
||||||
{
|
{
|
||||||
@@ -530,35 +529,41 @@ namespace HACD
|
|||||||
Vec3<Real> min = m_barycenter;
|
Vec3<Real> min = m_barycenter;
|
||||||
Vec3<Real> max = m_barycenter;
|
Vec3<Real> max = m_barycenter;
|
||||||
Real x, y, z;
|
Real x, y, z;
|
||||||
for(size_t v = 1; v < nV; v++)
|
for (size_t v = 1; v < nV; v++)
|
||||||
{
|
{
|
||||||
m_barycenter += m_vertices.GetHead()->GetData().m_pos;
|
m_barycenter += m_vertices.GetHead()->GetData().m_pos;
|
||||||
x = m_vertices.GetHead()->GetData().m_pos.X();
|
x = m_vertices.GetHead()->GetData().m_pos.X();
|
||||||
y = m_vertices.GetHead()->GetData().m_pos.Y();
|
y = m_vertices.GetHead()->GetData().m_pos.Y();
|
||||||
z = m_vertices.GetHead()->GetData().m_pos.Z();
|
z = m_vertices.GetHead()->GetData().m_pos.Z();
|
||||||
if ( x < min.X()) min.X() = x;
|
if (x < min.X())
|
||||||
else if ( x > max.X()) max.X() = x;
|
min.X() = x;
|
||||||
if ( y < min.Y()) min.Y() = y;
|
else if (x > max.X())
|
||||||
else if ( y > max.Y()) max.Y() = y;
|
max.X() = x;
|
||||||
if ( z < min.Z()) min.Z() = z;
|
if (y < min.Y())
|
||||||
else if ( z > max.Z()) max.Z() = z;
|
min.Y() = y;
|
||||||
|
else if (y > max.Y())
|
||||||
|
max.Y() = y;
|
||||||
|
if (z < min.Z())
|
||||||
|
min.Z() = z;
|
||||||
|
else if (z > max.Z())
|
||||||
|
max.Z() = z;
|
||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
m_barycenter /= static_cast<Real>(nV);
|
m_barycenter /= static_cast<Real>(nV);
|
||||||
m_diag = static_cast<Real>(0.001 * (max-min).GetNorm());
|
m_diag = static_cast<Real>(0.001 * (max - min).GetNorm());
|
||||||
const Real invDiag = static_cast<Real>(1.0 / m_diag);
|
const Real invDiag = static_cast<Real>(1.0 / m_diag);
|
||||||
if (m_diag != 0.0)
|
if (m_diag != 0.0)
|
||||||
{
|
{
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag;
|
m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag;
|
||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool TMMesh::Denormalize()
|
bool TMMesh::Denormalize()
|
||||||
{
|
{
|
||||||
size_t nV = m_vertices.GetSize();
|
size_t nV = m_vertices.GetSize();
|
||||||
if (nV == 0)
|
if (nV == 0)
|
||||||
{
|
{
|
||||||
@@ -566,12 +571,12 @@ namespace HACD
|
|||||||
}
|
}
|
||||||
if (m_diag != 0.0)
|
if (m_diag != 0.0)
|
||||||
{
|
{
|
||||||
for(size_t v = 0; v < nV; v++)
|
for (size_t v = 0; v < nV; v++)
|
||||||
{
|
{
|
||||||
m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter;
|
m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter;
|
||||||
m_vertices.Next();
|
m_vertices.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace HACD
|
||||||
|
|||||||
@@ -38,21 +38,22 @@ All rights reserved.
|
|||||||
#include <set>
|
#include <set>
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
class TMMTriangle;
|
class TMMTriangle;
|
||||||
class TMMEdge;
|
class TMMEdge;
|
||||||
class TMMesh;
|
class TMMesh;
|
||||||
class ICHull;
|
class ICHull;
|
||||||
class HACD;
|
class HACD;
|
||||||
|
|
||||||
class DPoint
|
class DPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DPoint(Real dist=0, bool computed=false, bool distOnly=false)
|
DPoint(Real dist = 0, bool computed = false, bool distOnly = false)
|
||||||
:m_dist(dist),
|
: m_dist(dist),
|
||||||
m_computed(computed),
|
m_computed(computed),
|
||||||
m_distOnly(distOnly){};
|
m_distOnly(distOnly){};
|
||||||
~DPoint(){};
|
~DPoint(){};
|
||||||
private:
|
|
||||||
|
private:
|
||||||
Real m_dist;
|
Real m_dist;
|
||||||
bool m_computed;
|
bool m_computed;
|
||||||
bool m_distOnly;
|
bool m_distOnly;
|
||||||
@@ -63,81 +64,82 @@ namespace HACD
|
|||||||
friend class Graph;
|
friend class Graph;
|
||||||
friend class ICHull;
|
friend class ICHull;
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Vertex data structure used in a triangular manifold mesh (TMM).
|
//! Vertex data structure used in a triangular manifold mesh (TMM).
|
||||||
class TMMVertex
|
class TMMVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TMMVertex(void);
|
TMMVertex(void);
|
||||||
~TMMVertex(void);
|
~TMMVertex(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vec3<Real> m_pos;
|
Vec3<Real> m_pos;
|
||||||
long m_name;
|
long m_name;
|
||||||
size_t m_id;
|
size_t m_id;
|
||||||
CircularListElement<TMMEdge> * m_duplicate; // pointer to incident cone edge (or NULL)
|
CircularListElement<TMMEdge> *m_duplicate; // pointer to incident cone edge (or NULL)
|
||||||
bool m_onHull;
|
bool m_onHull;
|
||||||
bool m_tag;
|
bool m_tag;
|
||||||
TMMVertex(const TMMVertex & rhs);
|
TMMVertex(const TMMVertex &rhs);
|
||||||
|
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
friend class ICHull;
|
friend class ICHull;
|
||||||
friend class TMMesh;
|
friend class TMMesh;
|
||||||
friend class TMMTriangle;
|
friend class TMMTriangle;
|
||||||
friend class TMMEdge;
|
friend class TMMEdge;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Edge data structure used in a triangular manifold mesh (TMM).
|
//! Edge data structure used in a triangular manifold mesh (TMM).
|
||||||
class TMMEdge
|
class TMMEdge
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TMMEdge(void);
|
TMMEdge(void);
|
||||||
~TMMEdge(void);
|
~TMMEdge(void);
|
||||||
private:
|
|
||||||
|
private:
|
||||||
size_t m_id;
|
size_t m_id;
|
||||||
CircularListElement<TMMTriangle> * m_triangles[2];
|
CircularListElement<TMMTriangle> *m_triangles[2];
|
||||||
CircularListElement<TMMVertex> * m_vertices[2];
|
CircularListElement<TMMVertex> *m_vertices[2];
|
||||||
CircularListElement<TMMTriangle> * m_newFace;
|
CircularListElement<TMMTriangle> *m_newFace;
|
||||||
|
|
||||||
|
TMMEdge(const TMMEdge &rhs);
|
||||||
TMMEdge(const TMMEdge & rhs);
|
|
||||||
|
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
friend class ICHull;
|
friend class ICHull;
|
||||||
friend class TMMTriangle;
|
friend class TMMTriangle;
|
||||||
friend class TMMVertex;
|
friend class TMMVertex;
|
||||||
friend class TMMesh;
|
friend class TMMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Triangle data structure used in a triangular manifold mesh (TMM).
|
//! Triangle data structure used in a triangular manifold mesh (TMM).
|
||||||
class TMMTriangle
|
class TMMTriangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TMMTriangle(void);
|
TMMTriangle(void);
|
||||||
~TMMTriangle(void);
|
~TMMTriangle(void);
|
||||||
private:
|
|
||||||
|
private:
|
||||||
size_t m_id;
|
size_t m_id;
|
||||||
CircularListElement<TMMEdge> * m_edges[3];
|
CircularListElement<TMMEdge> *m_edges[3];
|
||||||
CircularListElement<TMMVertex> * m_vertices[3];
|
CircularListElement<TMMVertex> *m_vertices[3];
|
||||||
std::set<long> m_incidentPoints;
|
std::set<long> m_incidentPoints;
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
|
|
||||||
TMMTriangle(const TMMTriangle & rhs);
|
TMMTriangle(const TMMTriangle &rhs);
|
||||||
|
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
friend class ICHull;
|
friend class ICHull;
|
||||||
friend class TMMesh;
|
friend class TMMesh;
|
||||||
friend class TMMVertex;
|
friend class TMMVertex;
|
||||||
friend class TMMEdge;
|
friend class TMMEdge;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Material
|
class Material
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Material(void);
|
Material(void);
|
||||||
~Material(void){}
|
~Material(void) {}
|
||||||
// private:
|
// private:
|
||||||
Vec3<double> m_diffuseColor;
|
Vec3<double> m_diffuseColor;
|
||||||
double m_ambientIntensity;
|
double m_ambientIntensity;
|
||||||
Vec3<double> m_specularColor;
|
Vec3<double> m_specularColor;
|
||||||
@@ -147,51 +149,50 @@ namespace HACD
|
|||||||
|
|
||||||
friend class TMMesh;
|
friend class TMMesh;
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! triangular manifold mesh data structure.
|
|
||||||
class TMMesh
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
//! triangular manifold mesh data structure.
|
||||||
|
class TMMesh
|
||||||
|
{
|
||||||
|
public:
|
||||||
//! Returns the number of vertices>
|
//! Returns the number of vertices>
|
||||||
inline size_t GetNVertices() const { return m_vertices.GetSize();}
|
inline size_t GetNVertices() const { return m_vertices.GetSize(); }
|
||||||
//! Returns the number of edges
|
//! Returns the number of edges
|
||||||
inline size_t GetNEdges() const { return m_edges.GetSize();}
|
inline size_t GetNEdges() const { return m_edges.GetSize(); }
|
||||||
//! Returns the number of triangles
|
//! Returns the number of triangles
|
||||||
inline size_t GetNTriangles() const { return m_triangles.GetSize();}
|
inline size_t GetNTriangles() const { return m_triangles.GetSize(); }
|
||||||
//! Returns the vertices circular list
|
//! Returns the vertices circular list
|
||||||
inline const CircularList<TMMVertex> & GetVertices() const { return m_vertices;}
|
inline const CircularList<TMMVertex> &GetVertices() const { return m_vertices; }
|
||||||
//! Returns the edges circular list
|
//! Returns the edges circular list
|
||||||
inline const CircularList<TMMEdge> & GetEdges() const { return m_edges;}
|
inline const CircularList<TMMEdge> &GetEdges() const { return m_edges; }
|
||||||
//! Returns the triangles circular list
|
//! Returns the triangles circular list
|
||||||
inline const CircularList<TMMTriangle> & GetTriangles() const { return m_triangles;}
|
inline const CircularList<TMMTriangle> &GetTriangles() const { return m_triangles; }
|
||||||
//! Returns the vertices circular list
|
//! Returns the vertices circular list
|
||||||
inline CircularList<TMMVertex> & GetVertices() { return m_vertices;}
|
inline CircularList<TMMVertex> &GetVertices() { return m_vertices; }
|
||||||
//! Returns the edges circular list
|
//! Returns the edges circular list
|
||||||
inline CircularList<TMMEdge> & GetEdges() { return m_edges;}
|
inline CircularList<TMMEdge> &GetEdges() { return m_edges; }
|
||||||
//! Returns the triangles circular list
|
//! Returns the triangles circular list
|
||||||
inline CircularList<TMMTriangle> & GetTriangles() { return m_triangles;}
|
inline CircularList<TMMTriangle> &GetTriangles() { return m_triangles; }
|
||||||
//! Add vertex to the mesh
|
//! Add vertex to the mesh
|
||||||
CircularListElement<TMMVertex> * AddVertex() {return m_vertices.Add();}
|
CircularListElement<TMMVertex> *AddVertex() { return m_vertices.Add(); }
|
||||||
//! Add vertex to the mesh
|
//! Add vertex to the mesh
|
||||||
CircularListElement<TMMEdge> * AddEdge() {return m_edges.Add();}
|
CircularListElement<TMMEdge> *AddEdge() { return m_edges.Add(); }
|
||||||
//! Add vertex to the mesh
|
//! Add vertex to the mesh
|
||||||
CircularListElement<TMMTriangle> * AddTriangle() {return m_triangles.Add();}
|
CircularListElement<TMMTriangle> *AddTriangle() { return m_triangles.Add(); }
|
||||||
//! Print mesh information
|
//! Print mesh information
|
||||||
void Print();
|
void Print();
|
||||||
//!
|
//!
|
||||||
void GetIFS(Vec3<Real> * const points, Vec3<long> * const triangles);
|
void GetIFS(Vec3<Real> *const points, Vec3<long> *const triangles);
|
||||||
//! Save mesh
|
//! Save mesh
|
||||||
bool Save(const char *fileName);
|
bool Save(const char *fileName);
|
||||||
//! Save mesh to VRML 2.0 format
|
//! Save mesh to VRML 2.0 format
|
||||||
bool SaveVRML2(std::ofstream &fout);
|
bool SaveVRML2(std::ofstream &fout);
|
||||||
//! Save mesh to VRML 2.0 format
|
//! Save mesh to VRML 2.0 format
|
||||||
bool SaveVRML2(std::ofstream &fout, const Material & material);
|
bool SaveVRML2(std::ofstream &fout, const Material &material);
|
||||||
//!
|
//!
|
||||||
void Clear();
|
void Clear();
|
||||||
//!
|
//!
|
||||||
void Copy(TMMesh & mesh);
|
void Copy(TMMesh &mesh);
|
||||||
//!
|
//!
|
||||||
bool CheckConsistancy();
|
bool CheckConsistancy();
|
||||||
//!
|
//!
|
||||||
@@ -203,7 +204,7 @@ namespace HACD
|
|||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~TMMesh(void);
|
virtual ~TMMesh(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CircularList<TMMVertex> m_vertices;
|
CircularList<TMMVertex> m_vertices;
|
||||||
CircularList<TMMEdge> m_edges;
|
CircularList<TMMEdge> m_edges;
|
||||||
CircularList<TMMTriangle> m_triangles;
|
CircularList<TMMTriangle> m_triangles;
|
||||||
@@ -211,40 +212,40 @@ namespace HACD
|
|||||||
Vec3<Real> m_barycenter; //>! barycenter of the mesh
|
Vec3<Real> m_barycenter; //>! barycenter of the mesh
|
||||||
|
|
||||||
// not defined
|
// not defined
|
||||||
TMMesh(const TMMesh & rhs);
|
TMMesh(const TMMesh &rhs);
|
||||||
friend class ICHull;
|
friend class ICHull;
|
||||||
friend class HACD;
|
friend class HACD;
|
||||||
};
|
};
|
||||||
//! IntersectRayTriangle(): intersect a ray with a 3D triangle
|
//! IntersectRayTriangle(): intersect a ray with a 3D triangle
|
||||||
//! Input: a ray R, and a triangle T
|
//! Input: a ray R, and a triangle T
|
||||||
//! Output: *I = intersection point (when it exists)
|
//! Output: *I = intersection point (when it exists)
|
||||||
//! 0 = disjoint (no intersect)
|
//! 0 = disjoint (no intersect)
|
||||||
//! 1 = intersect in unique point I1
|
//! 1 = intersect in unique point I1
|
||||||
long IntersectRayTriangle( const Vec3<double> & P0, const Vec3<double> & dir,
|
long IntersectRayTriangle(const Vec3<double> &P0, const Vec3<double> &dir,
|
||||||
const Vec3<double> & V0, const Vec3<double> & V1,
|
const Vec3<double> &V0, const Vec3<double> &V1,
|
||||||
const Vec3<double> & V2, double &t);
|
const Vec3<double> &V2, double &t);
|
||||||
|
|
||||||
// intersect_RayTriangle(): intersect a ray with a 3D triangle
|
// intersect_RayTriangle(): intersect a ray with a 3D triangle
|
||||||
// Input: a ray R, and a triangle T
|
// Input: a ray R, and a triangle T
|
||||||
// Output: *I = intersection point (when it exists)
|
// Output: *I = intersection point (when it exists)
|
||||||
// Return: -1 = triangle is degenerate (a segment or point)
|
// Return: -1 = triangle is degenerate (a segment or point)
|
||||||
// 0 = disjoint (no intersect)
|
// 0 = disjoint (no intersect)
|
||||||
// 1 = intersect in unique point I1
|
// 1 = intersect in unique point I1
|
||||||
// 2 = are in the same plane
|
// 2 = are in the same plane
|
||||||
long IntersectRayTriangle2(const Vec3<double> & P0, const Vec3<double> & dir,
|
long IntersectRayTriangle2(const Vec3<double> &P0, const Vec3<double> &dir,
|
||||||
const Vec3<double> & V0, const Vec3<double> & V1,
|
const Vec3<double> &V0, const Vec3<double> &V1,
|
||||||
const Vec3<double> & V2, double &r);
|
const Vec3<double> &V2, double &r);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate the line segment PaPb that is the shortest route between
|
Calculate the line segment PaPb that is the shortest route between
|
||||||
two lines P1P2 and P3P4. Calculate also the values of mua and mub where
|
two lines P1P2 and P3P4. Calculate also the values of mua and mub where
|
||||||
Pa = P1 + mua (P2 - P1)
|
Pa = P1 + mua (P2 - P1)
|
||||||
Pb = P3 + mub (P4 - P3)
|
Pb = P3 + mub (P4 - P3)
|
||||||
Return FALSE if no solution exists.
|
Return FALSE if no solution exists.
|
||||||
*/
|
*/
|
||||||
bool IntersectLineLine(const Vec3<double> & p1, const Vec3<double> & p2,
|
bool IntersectLineLine(const Vec3<double> &p1, const Vec3<double> &p2,
|
||||||
const Vec3<double> & p3, const Vec3<double> & p4,
|
const Vec3<double> &p3, const Vec3<double> &p4,
|
||||||
Vec3<double> & pa, Vec3<double> & pb,
|
Vec3<double> &pa, Vec3<double> &pb,
|
||||||
double & mua, double &mub);
|
double &mua, double &mub);
|
||||||
}
|
} // namespace HACD
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,53 +15,54 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef HACD_VECTOR_H
|
#ifndef HACD_VECTOR_H
|
||||||
#define HACD_VECTOR_H
|
#define HACD_VECTOR_H
|
||||||
#include<math.h>
|
#include <math.h>
|
||||||
#include<iostream>
|
#include <iostream>
|
||||||
#include "hacdVersion.h"
|
#include "hacdVersion.h"
|
||||||
|
|
||||||
namespace HACD
|
namespace HACD
|
||||||
{
|
{
|
||||||
typedef double Real;
|
typedef double Real;
|
||||||
//! Vector dim 3.
|
//! Vector dim 3.
|
||||||
template < typename T > class Vec3
|
template <typename T>
|
||||||
{
|
class Vec3
|
||||||
public:
|
{
|
||||||
T & X();
|
public:
|
||||||
T & Y();
|
T& X();
|
||||||
T & Z();
|
T& Y();
|
||||||
const T & X() const;
|
T& Z();
|
||||||
const T & Y() const;
|
const T& X() const;
|
||||||
const T & Z() const;
|
const T& Y() const;
|
||||||
|
const T& Z() const;
|
||||||
void Normalize();
|
void Normalize();
|
||||||
T GetNorm() const;
|
T GetNorm() const;
|
||||||
void operator= (const Vec3 & rhs);
|
void operator=(const Vec3& rhs);
|
||||||
void operator+=(const Vec3 & rhs);
|
void operator+=(const Vec3& rhs);
|
||||||
void operator-=(const Vec3 & rhs);
|
void operator-=(const Vec3& rhs);
|
||||||
void operator-=(T a);
|
void operator-=(T a);
|
||||||
void operator+=(T a);
|
void operator+=(T a);
|
||||||
void operator/=(T a);
|
void operator/=(T a);
|
||||||
void operator*=(T a);
|
void operator*=(T a);
|
||||||
Vec3 operator^ (const Vec3 & rhs) const;
|
Vec3 operator^(const Vec3& rhs) const;
|
||||||
T operator* (const Vec3 & rhs) const;
|
T operator*(const Vec3& rhs) const;
|
||||||
Vec3 operator+ (const Vec3 & rhs) const;
|
Vec3 operator+(const Vec3& rhs) const;
|
||||||
Vec3 operator- (const Vec3 & rhs) const;
|
Vec3 operator-(const Vec3& rhs) const;
|
||||||
Vec3 operator- () const;
|
Vec3 operator-() const;
|
||||||
Vec3 operator* (T rhs) const;
|
Vec3 operator*(T rhs) const;
|
||||||
Vec3 operator/ (T rhs) const;
|
Vec3 operator/(T rhs) const;
|
||||||
Vec3();
|
Vec3();
|
||||||
Vec3(T a);
|
Vec3(T a);
|
||||||
Vec3(T x, T y, T z);
|
Vec3(T x, T y, T z);
|
||||||
Vec3(const Vec3 & rhs);
|
Vec3(const Vec3& rhs);
|
||||||
/*virtual*/ ~Vec3(void);
|
/*virtual*/ ~Vec3(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T m_data[3];
|
T m_data[3];
|
||||||
};
|
};
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool Colinear(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c);
|
bool Colinear(const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c);
|
||||||
template<typename T>
|
template <typename T>
|
||||||
const T Volume(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c, const Vec3<T> & d);
|
const T Volume(const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c, const Vec3<T>& d);
|
||||||
|
|
||||||
}
|
} // namespace HACD
|
||||||
#include "hacdVector.inl" // template implementation
|
#include "hacdVector.inl" // template implementation
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,6 +12,4 @@
|
|||||||
#include "MultiBodyNameMap.hpp"
|
#include "MultiBodyNameMap.hpp"
|
||||||
#include "User2InternalIndex.hpp"
|
#include "User2InternalIndex.hpp"
|
||||||
|
|
||||||
#endif//BULLET_INVERSE_DYNAMICS_UTILS_COMMON_H
|
#endif //BULLET_INVERSE_DYNAMICS_UTILS_COMMON_H
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,27 +2,36 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
#define CHECK_NULLPTR() \
|
#define CHECK_NULLPTR() \
|
||||||
do { \
|
do \
|
||||||
if (m_reference == 0x0) { \
|
{ \
|
||||||
|
if (m_reference == 0x0) \
|
||||||
|
{ \
|
||||||
bt_id_error_message("m_reference == 0x0\n"); \
|
bt_id_error_message("m_reference == 0x0\n"); \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TRY(x) \
|
#define TRY(x) \
|
||||||
do { \
|
do \
|
||||||
if (x == -1) { \
|
{ \
|
||||||
|
if (x == -1) \
|
||||||
|
{ \
|
||||||
bt_id_error_message("error calling " #x "\n"); \
|
bt_id_error_message("error calling " #x "\n"); \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
CloneTreeCreator::CloneTreeCreator(const MultiBodyTree* reference) { m_reference = reference; }
|
CloneTreeCreator::CloneTreeCreator(const MultiBodyTree* reference)
|
||||||
|
{
|
||||||
|
m_reference = reference;
|
||||||
|
}
|
||||||
|
|
||||||
CloneTreeCreator::~CloneTreeCreator() {}
|
CloneTreeCreator::~CloneTreeCreator() {}
|
||||||
|
|
||||||
int CloneTreeCreator::getNumBodies(int* num_bodies) const {
|
int CloneTreeCreator::getNumBodies(int* num_bodies) const
|
||||||
|
{
|
||||||
CHECK_NULLPTR();
|
CHECK_NULLPTR();
|
||||||
*num_bodies = m_reference->numBodies();
|
*num_bodies = m_reference->numBodies();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -31,7 +40,8 @@ int CloneTreeCreator::getNumBodies(int* num_bodies) const {
|
|||||||
int CloneTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
int CloneTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
||||||
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
||||||
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
||||||
mat33* body_I_body, int* user_int, void** user_ptr) const {
|
mat33* body_I_body, int* user_int, void** user_ptr) const
|
||||||
|
{
|
||||||
CHECK_NULLPTR();
|
CHECK_NULLPTR();
|
||||||
TRY(m_reference->getParentIndex(body_index, parent_index));
|
TRY(m_reference->getParentIndex(body_index, parent_index));
|
||||||
TRY(m_reference->getJointType(body_index, joint_type));
|
TRY(m_reference->getJointType(body_index, joint_type));
|
||||||
@@ -46,4 +56,4 @@ int CloneTreeCreator::getBody(const int body_index, int* parent_index, JointType
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
#include "BulletInverseDynamics/IDConfig.hpp"
|
#include "BulletInverseDynamics/IDConfig.hpp"
|
||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// Generate an identical multibody tree from a reference system.
|
/// Generate an identical multibody tree from a reference system.
|
||||||
class CloneTreeCreator : public MultiBodyTreeCreator {
|
class CloneTreeCreator : public MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor
|
/// ctor
|
||||||
/// @param reference the MultiBodyTree to clone
|
/// @param reference the MultiBodyTree to clone
|
||||||
CloneTreeCreator(const MultiBodyTree*reference);
|
CloneTreeCreator(const MultiBodyTree* reference);
|
||||||
~CloneTreeCreator();
|
~CloneTreeCreator();
|
||||||
///\copydoc MultiBodyTreeCreator::getNumBodies
|
///\copydoc MultiBodyTreeCreator::getNumBodies
|
||||||
int getNumBodies(int* num_bodies) const;
|
int getNumBodies(int* num_bodies) const;
|
||||||
@@ -21,7 +23,7 @@ public:
|
|||||||
void** user_ptr) const;
|
void** user_ptr) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const MultiBodyTree *m_reference;
|
const MultiBodyTree* m_reference;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif // CLONETREE_CREATOR_HPP_
|
#endif // CLONETREE_CREATOR_HPP_
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
#include "CoilCreator.hpp"
|
#include "CoilCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
CoilCreator::CoilCreator(int n) : m_num_bodies(n), m_parent(n) {
|
{
|
||||||
for (int i = 0; i < m_num_bodies; i++) {
|
CoilCreator::CoilCreator(int n) : m_num_bodies(n), m_parent(n)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_num_bodies; i++)
|
||||||
|
{
|
||||||
m_parent[i] = i - 1;
|
m_parent[i] = i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +41,8 @@ CoilCreator::CoilCreator(int n) : m_num_bodies(n), m_parent(n) {
|
|||||||
|
|
||||||
CoilCreator::~CoilCreator() {}
|
CoilCreator::~CoilCreator() {}
|
||||||
|
|
||||||
int CoilCreator::getNumBodies(int* num_bodies) const {
|
int CoilCreator::getNumBodies(int* num_bodies) const
|
||||||
|
{
|
||||||
*num_bodies = m_num_bodies;
|
*num_bodies = m_num_bodies;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -46,8 +50,10 @@ int CoilCreator::getNumBodies(int* num_bodies) const {
|
|||||||
int CoilCreator::getBody(int body_index, int* parent_index, JointType* joint_type,
|
int CoilCreator::getBody(int body_index, int* parent_index, JointType* joint_type,
|
||||||
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
||||||
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
||||||
mat33* body_I_body, int* user_int, void** user_ptr) const {
|
mat33* body_I_body, int* user_int, void** user_ptr) const
|
||||||
if (body_index < 0 || body_index >= m_num_bodies) {
|
{
|
||||||
|
if (body_index < 0 || body_index >= m_num_bodies)
|
||||||
|
{
|
||||||
bt_id_error_message("invalid body index %d\n", body_index);
|
bt_id_error_message("invalid body index %d\n", body_index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -64,4 +70,4 @@ int CoilCreator::getBody(int body_index, int* parent_index, JointType* joint_typ
|
|||||||
*user_ptr = 0;
|
*user_ptr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -3,15 +3,16 @@
|
|||||||
|
|
||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// Creator class for building a "coil" system as intruduced as benchmark example in
|
/// Creator class for building a "coil" system as intruduced as benchmark example in
|
||||||
/// Featherstone (1999), "A Divide-and-Conquer Articulated-Body Algorithm for Parallel O(log(n))
|
/// Featherstone (1999), "A Divide-and-Conquer Articulated-Body Algorithm for Parallel O(log(n))
|
||||||
/// Calculation of Rigid-Body Dynamics. Part 2: Trees, Loops, and Accuracy.", The International
|
/// Calculation of Rigid-Body Dynamics. Part 2: Trees, Loops, and Accuracy.", The International
|
||||||
/// Journal of Robotics Research 18 (9): 876–892. doi : 10.1177 / 02783649922066628.
|
/// Journal of Robotics Research 18 (9): 876–892. doi : 10.1177 / 02783649922066628.
|
||||||
///
|
///
|
||||||
/// This is a serial chain, with an initial configuration resembling a coil.
|
/// This is a serial chain, with an initial configuration resembling a coil.
|
||||||
class CoilCreator : public MultiBodyTreeCreator {
|
class CoilCreator : public MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor.
|
/// ctor.
|
||||||
/// @param n the number of bodies in the system
|
/// @param n the number of bodies in the system
|
||||||
@@ -36,5 +37,5 @@ private:
|
|||||||
vec3 m_body_r_body_com;
|
vec3 m_body_r_body_com;
|
||||||
mat33 m_body_I_body;
|
mat33 m_body_I_body;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "DillCreator.hpp"
|
#include "DillCreator.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
DillCreator::DillCreator(int level)
|
DillCreator::DillCreator(int level)
|
||||||
: m_level(level),
|
: m_level(level),
|
||||||
m_num_bodies(BT_ID_POW(2, level))
|
m_num_bodies(BT_ID_POW(2, level))
|
||||||
{
|
{
|
||||||
m_parent.resize(m_num_bodies);
|
m_parent.resize(m_num_bodies);
|
||||||
m_parent_r_parent_body_ref.resize(m_num_bodies);
|
m_parent_r_parent_body_ref.resize(m_num_bodies);
|
||||||
m_body_T_parent_ref.resize(m_num_bodies);
|
m_body_T_parent_ref.resize(m_num_bodies);
|
||||||
@@ -15,7 +15,8 @@ DillCreator::DillCreator(int level)
|
|||||||
m_body_I_body.resize(m_num_bodies);
|
m_body_I_body.resize(m_num_bodies);
|
||||||
|
|
||||||
// generate names (for debugging)
|
// generate names (for debugging)
|
||||||
for (int i = 0; i < m_num_bodies; i++) {
|
for (int i = 0; i < m_num_bodies; i++)
|
||||||
|
{
|
||||||
m_parent[i] = i - 1;
|
m_parent[i] = i - 1;
|
||||||
|
|
||||||
// all z-axis (DH convention)
|
// all z-axis (DH convention)
|
||||||
@@ -31,7 +32,8 @@ DillCreator::DillCreator(int level)
|
|||||||
const idScalar a_DH = 0.0;
|
const idScalar a_DH = 0.0;
|
||||||
const idScalar alpha_DH = 0.0;
|
const idScalar alpha_DH = 0.0;
|
||||||
|
|
||||||
if (-1 == recurseDill(m_level, parent, d_DH, a_DH, alpha_DH)) {
|
if (-1 == recurseDill(m_level, parent, d_DH, a_DH, alpha_DH))
|
||||||
|
{
|
||||||
bt_id_error_message("recurseDill failed\n");
|
bt_id_error_message("recurseDill failed\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@@ -39,7 +41,8 @@ DillCreator::DillCreator(int level)
|
|||||||
|
|
||||||
DillCreator::~DillCreator() {}
|
DillCreator::~DillCreator() {}
|
||||||
|
|
||||||
int DillCreator::getNumBodies(int* num_bodies) const {
|
int DillCreator::getNumBodies(int* num_bodies) const
|
||||||
|
{
|
||||||
*num_bodies = m_num_bodies;
|
*num_bodies = m_num_bodies;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -47,8 +50,10 @@ int DillCreator::getNumBodies(int* num_bodies) const {
|
|||||||
int DillCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
int DillCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
||||||
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
||||||
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
||||||
mat33* body_I_body, int* user_int, void** user_ptr) const {
|
mat33* body_I_body, int* user_int, void** user_ptr) const
|
||||||
if (body_index < 0 || body_index >= m_num_bodies) {
|
{
|
||||||
|
if (body_index < 0 || body_index >= m_num_bodies)
|
||||||
|
{
|
||||||
bt_id_error_message("invalid body index %d\n", body_index);
|
bt_id_error_message("invalid body index %d\n", body_index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -67,13 +72,16 @@ int DillCreator::getBody(const int body_index, int* parent_index, JointType* joi
|
|||||||
}
|
}
|
||||||
|
|
||||||
int DillCreator::recurseDill(const int level, const int parent, const idScalar d_DH_in,
|
int DillCreator::recurseDill(const int level, const int parent, const idScalar d_DH_in,
|
||||||
const idScalar a_DH_in, const idScalar alpha_DH_in) {
|
const idScalar a_DH_in, const idScalar alpha_DH_in)
|
||||||
if (level < 0) {
|
{
|
||||||
|
if (level < 0)
|
||||||
|
{
|
||||||
bt_id_error_message("invalid level parameter (%d)\n", level);
|
bt_id_error_message("invalid level parameter (%d)\n", level);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_current_body >= m_num_bodies || m_current_body < 0) {
|
if (m_current_body >= m_num_bodies || m_current_body < 0)
|
||||||
|
{
|
||||||
bt_id_error_message("invalid body parameter (%d, num_bodies: %d)\n", m_current_body,
|
bt_id_error_message("invalid body parameter (%d, num_bodies: %d)\n", m_current_body,
|
||||||
m_num_bodies);
|
m_num_bodies);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -92,9 +100,11 @@ int DillCreator::recurseDill(const int level, const int parent, const idScalar d
|
|||||||
m_body_r_body_com[body](1) = 0;
|
m_body_r_body_com[body](1) = 0;
|
||||||
m_body_r_body_com[body](2) = 0;
|
m_body_r_body_com[body](2) = 0;
|
||||||
// initialization
|
// initialization
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
m_parent_r_parent_body_ref[body](i) = 0;
|
m_parent_r_parent_body_ref[body](i) = 0;
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
m_body_I_body[body](i, j) = 0.0;
|
m_body_I_body[body](i, j) = 0.0;
|
||||||
m_body_T_parent_ref[body](i, j) = 0.0;
|
m_body_T_parent_ref[body](i, j) = 0.0;
|
||||||
}
|
}
|
||||||
@@ -108,9 +118,11 @@ int DillCreator::recurseDill(const int level, const int parent, const idScalar d
|
|||||||
&m_body_T_parent_ref[body]);
|
&m_body_T_parent_ref[body]);
|
||||||
|
|
||||||
// attach "level" Dill systems of levels 1...level
|
// attach "level" Dill systems of levels 1...level
|
||||||
for (int i = 1; i <= level; i++) {
|
for (int i = 1; i <= level; i++)
|
||||||
|
{
|
||||||
idScalar d_DH = 0.01 * size;
|
idScalar d_DH = 0.01 * size;
|
||||||
if (i == level) {
|
if (i == level)
|
||||||
|
{
|
||||||
d_DH = 0.0;
|
d_DH = 0.0;
|
||||||
}
|
}
|
||||||
const idScalar a_DH = i * 0.1;
|
const idScalar a_DH = i * 0.1;
|
||||||
@@ -121,4 +133,4 @@ int DillCreator::recurseDill(const int level, const int parent, const idScalar d
|
|||||||
|
|
||||||
return 0; // ok!
|
return 0; // ok!
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
|
|
||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
|
|
||||||
/// Creator class for building a "Dill" system as intruduced as benchmark example in
|
/// Creator class for building a "Dill" system as intruduced as benchmark example in
|
||||||
/// Featherstone (1999), "A Divide-and-Conquer Articulated-Body Algorithm for Parallel O(log(n))
|
/// Featherstone (1999), "A Divide-and-Conquer Articulated-Body Algorithm for Parallel O(log(n))
|
||||||
/// Calculation of Rigid-Body Dynamics. Part 2: Trees, Loops, and Accuracy.", The International
|
/// Calculation of Rigid-Body Dynamics. Part 2: Trees, Loops, and Accuracy.", The International
|
||||||
/// Journal of Robotics Research 18 (9): 876–892. doi : 10.1177 / 02783649922066628.
|
/// Journal of Robotics Research 18 (9): 876–892. doi : 10.1177 / 02783649922066628.
|
||||||
///
|
///
|
||||||
/// This is a self-similar branched tree, somewhat resembling a dill plant
|
/// This is a self-similar branched tree, somewhat resembling a dill plant
|
||||||
class DillCreator : public MultiBodyTreeCreator {
|
class DillCreator : public MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor
|
/// ctor
|
||||||
/// @param levels the number of dill levels
|
/// @param levels the number of dill levels
|
||||||
@@ -43,5 +43,5 @@ private:
|
|||||||
idArray<mat33>::type m_body_I_body;
|
idArray<mat33>::type m_body_I_body;
|
||||||
int m_current_body;
|
int m_current_body;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
#include "BulletInverseDynamics/IDMath.hpp"
|
#include "BulletInverseDynamics/IDMath.hpp"
|
||||||
#include "IDRandomUtil.hpp"
|
#include "IDRandomUtil.hpp"
|
||||||
|
|
||||||
|
namespace btInverseDynamics
|
||||||
namespace btInverseDynamics {
|
{
|
||||||
|
|
||||||
// constants for random mass and inertia generation
|
// constants for random mass and inertia generation
|
||||||
// these are arbitrary positive values.
|
// these are arbitrary positive values.
|
||||||
static const float mass_min = 0.001;
|
static const float mass_min = 0.001;
|
||||||
@@ -19,15 +18,18 @@ void randomInit(unsigned seed) { srand(seed); }
|
|||||||
|
|
||||||
int randomInt(int low, int high) { return rand() % (high + 1 - low) + low; }
|
int randomInt(int low, int high) { return rand() % (high + 1 - low) + low; }
|
||||||
|
|
||||||
float randomFloat(float low, float high) {
|
float randomFloat(float low, float high)
|
||||||
|
{
|
||||||
return low + static_cast<float>(rand()) / RAND_MAX * (high - low);
|
return low + static_cast<float>(rand()) / RAND_MAX * (high - low);
|
||||||
}
|
}
|
||||||
|
|
||||||
float randomMass() { return randomFloat(mass_min, mass_max); }
|
float randomMass() { return randomFloat(mass_min, mass_max); }
|
||||||
|
|
||||||
vec3 randomInertiaPrincipal() {
|
vec3 randomInertiaPrincipal()
|
||||||
|
{
|
||||||
vec3 inertia;
|
vec3 inertia;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
inertia(0) = randomFloat(mass_min, mass_max);
|
inertia(0) = randomFloat(mass_min, mass_max);
|
||||||
inertia(1) = randomFloat(mass_min, mass_max);
|
inertia(1) = randomFloat(mass_min, mass_max);
|
||||||
inertia(2) = randomFloat(mass_min, mass_max);
|
inertia(2) = randomFloat(mass_min, mass_max);
|
||||||
@@ -36,7 +38,8 @@ vec3 randomInertiaPrincipal() {
|
|||||||
return inertia;
|
return inertia;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat33 randomInertiaMatrix() {
|
mat33 randomInertiaMatrix()
|
||||||
|
{
|
||||||
// generate random valid inertia matrix by first getting valid components
|
// generate random valid inertia matrix by first getting valid components
|
||||||
// along major axes and then rotating by random amount
|
// along major axes and then rotating by random amount
|
||||||
vec3 principal = randomInertiaPrincipal();
|
vec3 principal = randomInertiaPrincipal();
|
||||||
@@ -55,10 +58,12 @@ mat33 randomInertiaMatrix() {
|
|||||||
return rot * inertia * rot.transpose();
|
return rot * inertia * rot.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 randomAxis() {
|
vec3 randomAxis()
|
||||||
|
{
|
||||||
vec3 axis;
|
vec3 axis;
|
||||||
idScalar length;
|
idScalar length;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
axis(0) = randomFloat(-1.0, 1.0);
|
axis(0) = randomFloat(-1.0, 1.0);
|
||||||
axis(1) = randomFloat(-1.0, 1.0);
|
axis(1) = randomFloat(-1.0, 1.0);
|
||||||
axis(2) = randomFloat(-1.0, 1.0);
|
axis(2) = randomFloat(-1.0, 1.0);
|
||||||
@@ -68,4 +73,4 @@ vec3 randomAxis() {
|
|||||||
|
|
||||||
return axis / length;
|
return axis / length;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#ifndef ID_RANDOM_UTIL_HPP_
|
#ifndef ID_RANDOM_UTIL_HPP_
|
||||||
#define ID_RANDOM_UTIL_HPP_
|
#define ID_RANDOM_UTIL_HPP_
|
||||||
#include "BulletInverseDynamics/IDConfig.hpp"
|
#include "BulletInverseDynamics/IDConfig.hpp"
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// seed random number generator using time()
|
/// seed random number generator using time()
|
||||||
void randomInit();
|
void randomInit();
|
||||||
/// seed random number generator with identical value to get repeatable results
|
/// seed random number generator with identical value to get repeatable results
|
||||||
@@ -32,5 +33,5 @@ vec3 randomInertiaPrincipal();
|
|||||||
mat33 randomInertiaMatrix();
|
mat33 randomInertiaMatrix();
|
||||||
/// generate a random unit vector
|
/// generate a random unit vector
|
||||||
vec3 randomAxis();
|
vec3 randomAxis();
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
#include "MultiBodyNameMap.hpp"
|
#include "MultiBodyNameMap.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
MultiBodyNameMap::MultiBodyNameMap() {}
|
MultiBodyNameMap::MultiBodyNameMap() {}
|
||||||
|
|
||||||
int MultiBodyNameMap::addBody(const int index, const std::string& name) {
|
int MultiBodyNameMap::addBody(const int index, const std::string& name)
|
||||||
if (m_index_to_body_name.count(index) > 0) {
|
{
|
||||||
|
if (m_index_to_body_name.count(index) > 0)
|
||||||
|
{
|
||||||
bt_id_error_message("trying to add index %d again\n", index);
|
bt_id_error_message("trying to add index %d again\n", index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (m_body_name_to_index.count(name) > 0) {
|
if (m_body_name_to_index.count(name) > 0)
|
||||||
|
{
|
||||||
bt_id_error_message("trying to add name %s again\n", name.c_str());
|
bt_id_error_message("trying to add name %s again\n", name.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -20,12 +23,15 @@ int MultiBodyNameMap::addBody(const int index, const std::string& name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiBodyNameMap::addJoint(const int index, const std::string& name) {
|
int MultiBodyNameMap::addJoint(const int index, const std::string& name)
|
||||||
if (m_index_to_joint_name.count(index) > 0) {
|
{
|
||||||
|
if (m_index_to_joint_name.count(index) > 0)
|
||||||
|
{
|
||||||
bt_id_error_message("trying to add index %d again\n", index);
|
bt_id_error_message("trying to add index %d again\n", index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (m_joint_name_to_index.count(name) > 0) {
|
if (m_joint_name_to_index.count(name) > 0)
|
||||||
|
{
|
||||||
bt_id_error_message("trying to add name %s again\n", name.c_str());
|
bt_id_error_message("trying to add name %s again\n", name.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -36,9 +42,11 @@ int MultiBodyNameMap::addJoint(const int index, const std::string& name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiBodyNameMap::getBodyName(const int index, std::string* name) const {
|
int MultiBodyNameMap::getBodyName(const int index, std::string* name) const
|
||||||
|
{
|
||||||
std::map<int, std::string>::const_iterator it = m_index_to_body_name.find(index);
|
std::map<int, std::string>::const_iterator it = m_index_to_body_name.find(index);
|
||||||
if (it == m_index_to_body_name.end()) {
|
if (it == m_index_to_body_name.end())
|
||||||
|
{
|
||||||
bt_id_error_message("index %d not known\n", index);
|
bt_id_error_message("index %d not known\n", index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -46,9 +54,11 @@ int MultiBodyNameMap::getBodyName(const int index, std::string* name) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiBodyNameMap::getJointName(const int index, std::string* name) const {
|
int MultiBodyNameMap::getJointName(const int index, std::string* name) const
|
||||||
|
{
|
||||||
std::map<int, std::string>::const_iterator it = m_index_to_joint_name.find(index);
|
std::map<int, std::string>::const_iterator it = m_index_to_joint_name.find(index);
|
||||||
if (it == m_index_to_joint_name.end()) {
|
if (it == m_index_to_joint_name.end())
|
||||||
|
{
|
||||||
bt_id_error_message("index %d not known\n", index);
|
bt_id_error_message("index %d not known\n", index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -56,9 +66,11 @@ int MultiBodyNameMap::getJointName(const int index, std::string* name) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiBodyNameMap::getBodyIndex(const std::string& name, int* index) const {
|
int MultiBodyNameMap::getBodyIndex(const std::string& name, int* index) const
|
||||||
|
{
|
||||||
std::map<std::string, int>::const_iterator it = m_body_name_to_index.find(name);
|
std::map<std::string, int>::const_iterator it = m_body_name_to_index.find(name);
|
||||||
if (it == m_body_name_to_index.end()) {
|
if (it == m_body_name_to_index.end())
|
||||||
|
{
|
||||||
bt_id_error_message("name %s not known\n", name.c_str());
|
bt_id_error_message("name %s not known\n", name.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -66,13 +78,15 @@ int MultiBodyNameMap::getBodyIndex(const std::string& name, int* index) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MultiBodyNameMap::getJointIndex(const std::string& name, int* index) const {
|
int MultiBodyNameMap::getJointIndex(const std::string& name, int* index) const
|
||||||
|
{
|
||||||
std::map<std::string, int>::const_iterator it = m_joint_name_to_index.find(name);
|
std::map<std::string, int>::const_iterator it = m_joint_name_to_index.find(name);
|
||||||
if (it == m_joint_name_to_index.end()) {
|
if (it == m_joint_name_to_index.end())
|
||||||
|
{
|
||||||
bt_id_error_message("name %s not known\n", name.c_str());
|
bt_id_error_message("name %s not known\n", name.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*index = it->second;
|
*index = it->second;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -5,11 +5,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// \brief The MultiBodyNameMap class
|
/// \brief The MultiBodyNameMap class
|
||||||
/// Utility class that stores a maps from body/joint indices to/from body and joint names
|
/// Utility class that stores a maps from body/joint indices to/from body and joint names
|
||||||
class MultiBodyNameMap {
|
class MultiBodyNameMap
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MultiBodyNameMap();
|
MultiBodyNameMap();
|
||||||
/// add a body to the map
|
/// add a body to the map
|
||||||
@@ -50,5 +51,5 @@ private:
|
|||||||
std::map<std::string, int> m_joint_name_to_index;
|
std::map<std::string, int> m_joint_name_to_index;
|
||||||
std::map<std::string, int> m_body_name_to_index;
|
std::map<std::string, int> m_body_name_to_index;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif // MULTIBODYNAMEMAP_HPP_
|
#endif // MULTIBODYNAMEMAP_HPP_
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) {
|
MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator)
|
||||||
|
{
|
||||||
int num_bodies;
|
int num_bodies;
|
||||||
int parent_index;
|
int parent_index;
|
||||||
JointType joint_type;
|
JointType joint_type;
|
||||||
@@ -16,7 +17,8 @@ MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) {
|
|||||||
void* user_ptr;
|
void* user_ptr;
|
||||||
|
|
||||||
MultiBodyTree* tree = new MultiBodyTree();
|
MultiBodyTree* tree = new MultiBodyTree();
|
||||||
if (0x0 == tree) {
|
if (0x0 == tree)
|
||||||
|
{
|
||||||
bt_id_error_message("cannot allocate tree\n");
|
bt_id_error_message("cannot allocate tree\n");
|
||||||
return 0x0;
|
return 0x0;
|
||||||
}
|
}
|
||||||
@@ -25,19 +27,22 @@ MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) {
|
|||||||
tree->setAcceptInvalidMassParameters(false);
|
tree->setAcceptInvalidMassParameters(false);
|
||||||
|
|
||||||
// get number of bodies in the system
|
// get number of bodies in the system
|
||||||
if (-1 == creator.getNumBodies(&num_bodies)) {
|
if (-1 == creator.getNumBodies(&num_bodies))
|
||||||
|
{
|
||||||
bt_id_error_message("getting body indices\n");
|
bt_id_error_message("getting body indices\n");
|
||||||
delete tree;
|
delete tree;
|
||||||
return 0x0;
|
return 0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get data for all bodies
|
// get data for all bodies
|
||||||
for (int index = 0; index < num_bodies; index++) {
|
for (int index = 0; index < num_bodies; index++)
|
||||||
|
{
|
||||||
// get body parameters from user callbacks
|
// get body parameters from user callbacks
|
||||||
if (-1 ==
|
if (-1 ==
|
||||||
creator.getBody(index, &parent_index, &joint_type, &body_r_parent_body_ref,
|
creator.getBody(index, &parent_index, &joint_type, &body_r_parent_body_ref,
|
||||||
&body_R_parent_ref, &body_axis_of_motion, &mass, &body_r_body_com,
|
&body_R_parent_ref, &body_axis_of_motion, &mass, &body_r_body_com,
|
||||||
&body_I_body, &user_int, &user_ptr)) {
|
&body_I_body, &user_int, &user_ptr))
|
||||||
|
{
|
||||||
bt_id_error_message("getting data for body %d\n", index);
|
bt_id_error_message("getting data for body %d\n", index);
|
||||||
delete tree;
|
delete tree;
|
||||||
return 0x0;
|
return 0x0;
|
||||||
@@ -46,14 +51,16 @@ MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) {
|
|||||||
if (-1 ==
|
if (-1 ==
|
||||||
tree->addBody(index, parent_index, joint_type, body_r_parent_body_ref,
|
tree->addBody(index, parent_index, joint_type, body_r_parent_body_ref,
|
||||||
body_R_parent_ref, body_axis_of_motion, mass, body_r_body_com,
|
body_R_parent_ref, body_axis_of_motion, mass, body_r_body_com,
|
||||||
body_I_body, user_int, user_ptr)) {
|
body_I_body, user_int, user_ptr))
|
||||||
|
{
|
||||||
bt_id_error_message("adding body %d\n", index);
|
bt_id_error_message("adding body %d\n", index);
|
||||||
delete tree;
|
delete tree;
|
||||||
return 0x0;
|
return 0x0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// finalize initialization
|
// finalize initialization
|
||||||
if (-1 == tree->finalize()) {
|
if (-1 == tree->finalize())
|
||||||
|
{
|
||||||
bt_id_error_message("building system\n");
|
bt_id_error_message("building system\n");
|
||||||
delete tree;
|
delete tree;
|
||||||
return 0x0;
|
return 0x0;
|
||||||
@@ -61,4 +68,4 @@ MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) {
|
|||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
#include "BulletInverseDynamics/MultiBodyTree.hpp"
|
#include "BulletInverseDynamics/MultiBodyTree.hpp"
|
||||||
#include "MultiBodyNameMap.hpp"
|
#include "MultiBodyNameMap.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// Interface class for initializing a MultiBodyTree instance.
|
/// Interface class for initializing a MultiBodyTree instance.
|
||||||
/// Data to be provided is modeled on the URDF specification.
|
/// Data to be provided is modeled on the URDF specification.
|
||||||
/// The user can derive from this class in order to programmatically
|
/// The user can derive from this class in order to programmatically
|
||||||
/// initialize a system.
|
/// initialize a system.
|
||||||
class MultiBodyTreeCreator {
|
class MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// the dtor
|
/// the dtor
|
||||||
virtual ~MultiBodyTreeCreator() {}
|
virtual ~MultiBodyTreeCreator() {}
|
||||||
@@ -29,7 +31,7 @@ public:
|
|||||||
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
||||||
mat33* body_I_body, int* user_int, void** user_ptr) const = 0;
|
mat33* body_I_body, int* user_int, void** user_ptr) const = 0;
|
||||||
/// @return a pointer to a name mapping utility class, or 0x0 if not available
|
/// @return a pointer to a name mapping utility class, or 0x0 if not available
|
||||||
virtual const MultiBodyNameMap* getNameMap() const {return 0x0;}
|
virtual const MultiBodyNameMap* getNameMap() const { return 0x0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create a multibody object.
|
/// Create a multibody object.
|
||||||
@@ -38,7 +40,7 @@ public:
|
|||||||
/// @return A pointer to an allocated multibodytree instance, or
|
/// @return A pointer to an allocated multibodytree instance, or
|
||||||
/// 0x0 if an error occured.
|
/// 0x0 if an error occured.
|
||||||
MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator);
|
MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator);
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|
||||||
// does urdf have gravity direction ??
|
// does urdf have gravity direction ??
|
||||||
|
|
||||||
|
|||||||
@@ -2,56 +2,69 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map,
|
int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map,
|
||||||
const char* filename) {
|
const char* filename)
|
||||||
if (0x0 == tree) {
|
{
|
||||||
|
if (0x0 == tree)
|
||||||
|
{
|
||||||
bt_id_error_message("tree pointer is null\n");
|
bt_id_error_message("tree pointer is null\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (0x0 == filename) {
|
if (0x0 == filename)
|
||||||
|
{
|
||||||
bt_id_error_message("filename is null\n");
|
bt_id_error_message("filename is null\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* fp = fopen(filename, "w");
|
FILE* fp = fopen(filename, "w");
|
||||||
if (NULL == fp) {
|
if (NULL == fp)
|
||||||
|
{
|
||||||
bt_id_error_message("cannot open file %s for writing\n", filename);
|
bt_id_error_message("cannot open file %s for writing\n", filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fprintf(fp, "// to generate postscript file, run dot -Tps %s -o %s.ps\n"
|
fprintf(fp,
|
||||||
|
"// to generate postscript file, run dot -Tps %s -o %s.ps\n"
|
||||||
"// details see graphviz documentation at http://graphviz.org\n"
|
"// details see graphviz documentation at http://graphviz.org\n"
|
||||||
"digraph tree {\n",
|
"digraph tree {\n",
|
||||||
filename, filename);
|
filename, filename);
|
||||||
|
|
||||||
for (int body = 0; body < tree->numBodies(); body++) {
|
for (int body = 0; body < tree->numBodies(); body++)
|
||||||
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
if (0x0 != map) {
|
if (0x0 != map)
|
||||||
if (-1 == map->getBodyName(body, &name)) {
|
{
|
||||||
|
if (-1 == map->getBodyName(body, &name))
|
||||||
|
{
|
||||||
bt_id_error_message("can't get name of body %d\n", body);
|
bt_id_error_message("can't get name of body %d\n", body);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fprintf(fp, " %d [label=\"%d/%s\"];\n", body, body, name.c_str());
|
fprintf(fp, " %d [label=\"%d/%s\"];\n", body, body, name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int body = 0; body < tree->numBodies(); body++) {
|
for (int body = 0; body < tree->numBodies(); body++)
|
||||||
|
{
|
||||||
int parent;
|
int parent;
|
||||||
const char* joint_type;
|
const char* joint_type;
|
||||||
int qi;
|
int qi;
|
||||||
if (-1 == tree->getParentIndex(body, &parent)) {
|
if (-1 == tree->getParentIndex(body, &parent))
|
||||||
|
{
|
||||||
bt_id_error_message("indexing error\n");
|
bt_id_error_message("indexing error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (-1 == tree->getJointTypeStr(body, &joint_type)) {
|
if (-1 == tree->getJointTypeStr(body, &joint_type))
|
||||||
|
{
|
||||||
bt_id_error_message("indexing error\n");
|
bt_id_error_message("indexing error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (-1 == tree->getDoFOffset(body, &qi)) {
|
if (-1 == tree->getDoFOffset(body, &qi))
|
||||||
|
{
|
||||||
bt_id_error_message("indexing error\n");
|
bt_id_error_message("indexing error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (-1 != parent) {
|
if (-1 != parent)
|
||||||
|
{
|
||||||
fprintf(fp, " %d -> %d [label= \"type:%s, q=%d\"];\n", parent, body,
|
fprintf(fp, " %d -> %d [label= \"type:%s, q=%d\"];\n", parent, body,
|
||||||
joint_type, qi);
|
joint_type, qi);
|
||||||
}
|
}
|
||||||
@@ -61,4 +74,4 @@ int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map,
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#include "BulletInverseDynamics/MultiBodyTree.hpp"
|
#include "BulletInverseDynamics/MultiBodyTree.hpp"
|
||||||
#include "MultiBodyNameMap.hpp"
|
#include "MultiBodyNameMap.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// generate a dot-file of the multibody tree for generating a graph using graphviz' dot tool
|
/// generate a dot-file of the multibody tree for generating a graph using graphviz' dot tool
|
||||||
/// @param tree the multibody tree
|
/// @param tree the multibody tree
|
||||||
/// @param map to add names of links (if 0x0, no names will be added)
|
/// @param map to add names of links (if 0x0, no names will be added)
|
||||||
@@ -12,6 +13,6 @@ namespace btInverseDynamics {
|
|||||||
/// @return 0 on success, -1 on error
|
/// @return 0 on success, -1 on error
|
||||||
int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map,
|
int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map,
|
||||||
const char* filename);
|
const char* filename);
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|
||||||
#endif // MULTIBODYTREEDEBUGGRAPH_HPP
|
#endif // MULTIBODYTREEDEBUGGRAPH_HPP
|
||||||
|
|||||||
@@ -4,13 +4,17 @@
|
|||||||
|
|
||||||
#include "IDRandomUtil.hpp"
|
#include "IDRandomUtil.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
RandomTreeCreator::RandomTreeCreator(const int max_bodies, bool random_seed) {
|
RandomTreeCreator::RandomTreeCreator(const int max_bodies, bool random_seed)
|
||||||
|
{
|
||||||
// seed generator
|
// seed generator
|
||||||
if(random_seed) {
|
if (random_seed)
|
||||||
|
{
|
||||||
randomInit(); // seeds with time()
|
randomInit(); // seeds with time()
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
randomInit(1); // seeds with 1
|
randomInit(1); // seeds with 1
|
||||||
}
|
}
|
||||||
m_num_bodies = randomInt(1, max_bodies);
|
m_num_bodies = randomInt(1, max_bodies);
|
||||||
@@ -18,7 +22,8 @@ RandomTreeCreator::RandomTreeCreator(const int max_bodies, bool random_seed) {
|
|||||||
|
|
||||||
RandomTreeCreator::~RandomTreeCreator() {}
|
RandomTreeCreator::~RandomTreeCreator() {}
|
||||||
|
|
||||||
int RandomTreeCreator::getNumBodies(int* num_bodies) const {
|
int RandomTreeCreator::getNumBodies(int* num_bodies) const
|
||||||
|
{
|
||||||
*num_bodies = m_num_bodies;
|
*num_bodies = m_num_bodies;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -26,14 +31,19 @@ int RandomTreeCreator::getNumBodies(int* num_bodies) const {
|
|||||||
int RandomTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
int RandomTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
||||||
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
||||||
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
||||||
mat33* body_I_body, int* user_int, void** user_ptr) const {
|
mat33* body_I_body, int* user_int, void** user_ptr) const
|
||||||
if(0 == body_index) { //root body
|
{
|
||||||
|
if (0 == body_index)
|
||||||
|
{ //root body
|
||||||
*parent_index = -1;
|
*parent_index = -1;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*parent_index = randomInt(0, body_index - 1);
|
*parent_index = randomInt(0, body_index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (randomInt(0, 3)) {
|
switch (randomInt(0, 3))
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
*joint_type = FIXED;
|
*joint_type = FIXED;
|
||||||
break;
|
break;
|
||||||
@@ -68,9 +78,9 @@ int RandomTreeCreator::getBody(const int body_index, int* parent_index, JointTyp
|
|||||||
vec3 ii = randomInertiaPrincipal();
|
vec3 ii = randomInertiaPrincipal();
|
||||||
mat33 ii_diag;
|
mat33 ii_diag;
|
||||||
setZero(ii_diag);
|
setZero(ii_diag);
|
||||||
ii_diag(0,0)=ii(0);
|
ii_diag(0, 0) = ii(0);
|
||||||
ii_diag(1,1)=ii(1);
|
ii_diag(1, 1) = ii(1);
|
||||||
ii_diag(2,2)=ii(2);
|
ii_diag(2, 2) = ii(2);
|
||||||
*body_I_body = transformX(a) * transformY(b) * transformZ(c) * ii_diag *
|
*body_I_body = transformX(a) * transformY(b) * transformZ(c) * ii_diag *
|
||||||
transformZ(-c) * transformY(-b) * transformX(-a);
|
transformZ(-c) * transformY(-b) * transformX(-a);
|
||||||
*user_int = 0;
|
*user_int = 0;
|
||||||
@@ -78,4 +88,4 @@ int RandomTreeCreator::getBody(const int body_index, int* parent_index, JointTyp
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -4,17 +4,19 @@
|
|||||||
#include "BulletInverseDynamics/IDConfig.hpp"
|
#include "BulletInverseDynamics/IDConfig.hpp"
|
||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// Generate a random MultiBodyTree with fixed or floating base and fixed, prismatic or revolute
|
/// Generate a random MultiBodyTree with fixed or floating base and fixed, prismatic or revolute
|
||||||
/// joints
|
/// joints
|
||||||
/// Uses a pseudo random number generator seeded from a random device.
|
/// Uses a pseudo random number generator seeded from a random device.
|
||||||
class RandomTreeCreator : public MultiBodyTreeCreator {
|
class RandomTreeCreator : public MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor
|
/// ctor
|
||||||
/// @param max_bodies maximum number of bodies
|
/// @param max_bodies maximum number of bodies
|
||||||
/// @param gravity gravitational acceleration
|
/// @param gravity gravitational acceleration
|
||||||
/// @param use_seed if true, seed random number generator
|
/// @param use_seed if true, seed random number generator
|
||||||
RandomTreeCreator(const int max_bodies, bool use_seed=false);
|
RandomTreeCreator(const int max_bodies, bool use_seed = false);
|
||||||
~RandomTreeCreator();
|
~RandomTreeCreator();
|
||||||
///\copydoc MultiBodyTreeCreator::getNumBodies
|
///\copydoc MultiBodyTreeCreator::getNumBodies
|
||||||
int getNumBodies(int* num_bodies) const;
|
int getNumBodies(int* num_bodies) const;
|
||||||
@@ -27,5 +29,5 @@ public:
|
|||||||
private:
|
private:
|
||||||
int m_num_bodies;
|
int m_num_bodies;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif // RANDOMTREE_CREATOR_HPP_
|
#endif // RANDOMTREE_CREATOR_HPP_
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// minimal "tree" (chain)
|
/// minimal "tree" (chain)
|
||||||
SimpleTreeCreator::SimpleTreeCreator(int dim) : m_num_bodies(dim) {
|
SimpleTreeCreator::SimpleTreeCreator(int dim) : m_num_bodies(dim)
|
||||||
|
{
|
||||||
m_mass = 1.0;
|
m_mass = 1.0;
|
||||||
m_body_T_parent_ref(0, 0) = 1;
|
m_body_T_parent_ref(0, 0) = 1;
|
||||||
m_body_T_parent_ref(0, 1) = 0;
|
m_body_T_parent_ref(0, 1) = 0;
|
||||||
@@ -38,7 +40,8 @@ SimpleTreeCreator::SimpleTreeCreator(int dim) : m_num_bodies(dim) {
|
|||||||
m_axis(1) = 0;
|
m_axis(1) = 0;
|
||||||
m_axis(2) = 1;
|
m_axis(2) = 1;
|
||||||
}
|
}
|
||||||
int SimpleTreeCreator::getNumBodies(int* num_bodies) const {
|
int SimpleTreeCreator::getNumBodies(int* num_bodies) const
|
||||||
|
{
|
||||||
*num_bodies = m_num_bodies;
|
*num_bodies = m_num_bodies;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -46,15 +49,20 @@ int SimpleTreeCreator::getNumBodies(int* num_bodies) const {
|
|||||||
int SimpleTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
int SimpleTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type,
|
||||||
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref,
|
||||||
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com,
|
||||||
mat33* body_I_body, int* user_int, void** user_ptr) const {
|
mat33* body_I_body, int* user_int, void** user_ptr) const
|
||||||
|
{
|
||||||
*parent_index = body_index - 1;
|
*parent_index = body_index - 1;
|
||||||
if (body_index % 2) {
|
if (body_index % 2)
|
||||||
|
{
|
||||||
*joint_type = PRISMATIC;
|
*joint_type = PRISMATIC;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*joint_type = REVOLUTE;
|
*joint_type = REVOLUTE;
|
||||||
}
|
}
|
||||||
*parent_r_parent_body_ref = m_parent_r_parent_body_ref;
|
*parent_r_parent_body_ref = m_parent_r_parent_body_ref;
|
||||||
if (0 == body_index) {
|
if (0 == body_index)
|
||||||
|
{
|
||||||
(*parent_r_parent_body_ref)(2) = 1.0;
|
(*parent_r_parent_body_ref)(2) = 1.0;
|
||||||
}
|
}
|
||||||
*body_T_parent_ref = m_body_T_parent_ref;
|
*body_T_parent_ref = m_body_T_parent_ref;
|
||||||
@@ -66,4 +74,4 @@ int SimpleTreeCreator::getBody(const int body_index, int* parent_index, JointTyp
|
|||||||
*user_ptr = 0;
|
*user_ptr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// minimal "tree" (chain)
|
/// minimal "tree" (chain)
|
||||||
class SimpleTreeCreator : public MultiBodyTreeCreator {
|
class SimpleTreeCreator : public MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor
|
/// ctor
|
||||||
/// @param dim number of bodies
|
/// @param dim number of bodies
|
||||||
@@ -30,5 +31,5 @@ private:
|
|||||||
mat33 m_body_I_body;
|
mat33 m_body_I_body;
|
||||||
vec3 m_axis;
|
vec3 m_axis;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif // SIMPLETREECREATOR_HPP_
|
#endif // SIMPLETREECREATOR_HPP_
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
#include "User2InternalIndex.hpp"
|
#include "User2InternalIndex.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
User2InternalIndex::User2InternalIndex() : m_map_built(false) {}
|
User2InternalIndex::User2InternalIndex() : m_map_built(false) {}
|
||||||
|
|
||||||
void User2InternalIndex::addBody(const int body, const int parent) {
|
void User2InternalIndex::addBody(const int body, const int parent)
|
||||||
|
{
|
||||||
m_user_parent_index_map[body] = parent;
|
m_user_parent_index_map[body] = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int User2InternalIndex::findRoot(int index) {
|
int User2InternalIndex::findRoot(int index)
|
||||||
if (0 == m_user_parent_index_map.count(index)) {
|
{
|
||||||
|
if (0 == m_user_parent_index_map.count(index))
|
||||||
|
{
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
return findRoot(m_user_parent_index_map[index]);
|
return findRoot(m_user_parent_index_map[index]);
|
||||||
@@ -17,24 +21,32 @@ int User2InternalIndex::findRoot(int index) {
|
|||||||
// modelled after URDF2Bullet.cpp:void ComputeParentIndices(const
|
// modelled after URDF2Bullet.cpp:void ComputeParentIndices(const
|
||||||
// URDFImporterInterface& u2b, URDF2BulletCachedData& cache, int urdfLinkIndex,
|
// URDFImporterInterface& u2b, URDF2BulletCachedData& cache, int urdfLinkIndex,
|
||||||
// int urdfParentIndex)
|
// int urdfParentIndex)
|
||||||
void User2InternalIndex::recurseIndexSets(const int user_body_index) {
|
void User2InternalIndex::recurseIndexSets(const int user_body_index)
|
||||||
|
{
|
||||||
m_user_to_internal[user_body_index] = m_current_index;
|
m_user_to_internal[user_body_index] = m_current_index;
|
||||||
m_current_index++;
|
m_current_index++;
|
||||||
for (size_t i = 0; i < m_user_child_indices[user_body_index].size(); i++) {
|
for (size_t i = 0; i < m_user_child_indices[user_body_index].size(); i++)
|
||||||
|
{
|
||||||
recurseIndexSets(m_user_child_indices[user_body_index][i]);
|
recurseIndexSets(m_user_child_indices[user_body_index][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int User2InternalIndex::buildMapping() {
|
int User2InternalIndex::buildMapping()
|
||||||
|
{
|
||||||
// find root index
|
// find root index
|
||||||
int user_root_index = -1;
|
int user_root_index = -1;
|
||||||
for (std::map<int, int>::iterator it = m_user_parent_index_map.begin();
|
for (std::map<int, int>::iterator it = m_user_parent_index_map.begin();
|
||||||
it != m_user_parent_index_map.end(); it++) {
|
it != m_user_parent_index_map.end(); it++)
|
||||||
|
{
|
||||||
int current_root_index = findRoot(it->second);
|
int current_root_index = findRoot(it->second);
|
||||||
if (it == m_user_parent_index_map.begin()) {
|
if (it == m_user_parent_index_map.begin())
|
||||||
|
{
|
||||||
user_root_index = current_root_index;
|
user_root_index = current_root_index;
|
||||||
} else {
|
}
|
||||||
if (user_root_index != current_root_index) {
|
else
|
||||||
|
{
|
||||||
|
if (user_root_index != current_root_index)
|
||||||
|
{
|
||||||
bt_id_error_message("multiple roots (at least) %d and %d\n", user_root_index,
|
bt_id_error_message("multiple roots (at least) %d and %d\n", user_root_index,
|
||||||
current_root_index);
|
current_root_index);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -44,7 +56,8 @@ int User2InternalIndex::buildMapping() {
|
|||||||
|
|
||||||
// build child index map
|
// build child index map
|
||||||
for (std::map<int, int>::iterator it = m_user_parent_index_map.begin();
|
for (std::map<int, int>::iterator it = m_user_parent_index_map.begin();
|
||||||
it != m_user_parent_index_map.end(); it++) {
|
it != m_user_parent_index_map.end(); it++)
|
||||||
|
{
|
||||||
m_user_child_indices[it->second].push_back(it->first);
|
m_user_child_indices[it->second].push_back(it->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +68,8 @@ int User2InternalIndex::buildMapping() {
|
|||||||
|
|
||||||
// reverse mapping
|
// reverse mapping
|
||||||
for (std::map<int, int>::iterator it = m_user_to_internal.begin();
|
for (std::map<int, int>::iterator it = m_user_to_internal.begin();
|
||||||
it != m_user_to_internal.end(); it++) {
|
it != m_user_to_internal.end(); it++)
|
||||||
|
{
|
||||||
m_internal_to_user[it->second] = it->first;
|
m_internal_to_user[it->second] = it->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,37 +77,45 @@ int User2InternalIndex::buildMapping() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int User2InternalIndex::user2internal(const int user, int *internal) const {
|
int User2InternalIndex::user2internal(const int user, int *internal) const
|
||||||
|
{
|
||||||
if (!m_map_built) {
|
if (!m_map_built)
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, int>::const_iterator it;
|
std::map<int, int>::const_iterator it;
|
||||||
it = m_user_to_internal.find(user);
|
it = m_user_to_internal.find(user);
|
||||||
if (it != m_user_to_internal.end()) {
|
if (it != m_user_to_internal.end())
|
||||||
|
{
|
||||||
*internal = it->second;
|
*internal = it->second;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
bt_id_error_message("no user index %d\n", user);
|
bt_id_error_message("no user index %d\n", user);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int User2InternalIndex::internal2user(const int internal, int *user) const {
|
int User2InternalIndex::internal2user(const int internal, int *user) const
|
||||||
|
{
|
||||||
if (!m_map_built) {
|
if (!m_map_built)
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, int>::const_iterator it;
|
std::map<int, int>::const_iterator it;
|
||||||
it = m_internal_to_user.find(internal);
|
it = m_internal_to_user.find(internal);
|
||||||
if (it != m_internal_to_user.end()) {
|
if (it != m_internal_to_user.end())
|
||||||
|
{
|
||||||
*user = it->second;
|
*user = it->second;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
bt_id_error_message("no internal index %d\n", internal);
|
bt_id_error_message("no internal index %d\n", internal);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -5,11 +5,12 @@
|
|||||||
|
|
||||||
#include "BulletInverseDynamics/IDConfig.hpp"
|
#include "BulletInverseDynamics/IDConfig.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// Convert arbitrary indexing scheme to internal indexing
|
/// Convert arbitrary indexing scheme to internal indexing
|
||||||
/// used for MultiBodyTree
|
/// used for MultiBodyTree
|
||||||
class User2InternalIndex {
|
class User2InternalIndex
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// Ctor
|
/// Ctor
|
||||||
User2InternalIndex();
|
User2InternalIndex();
|
||||||
@@ -41,6 +42,6 @@ private:
|
|||||||
std::map<int, std::vector<int> > m_user_child_indices;
|
std::map<int, std::vector<int> > m_user_child_indices;
|
||||||
int m_current_index;
|
int m_current_index;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|
||||||
#endif // USER2INTERNALINDEX_HPP
|
#endif // USER2INTERNALINDEX_HPP
|
||||||
|
|||||||
@@ -14,14 +14,16 @@
|
|||||||
|
|
||||||
/// Create a btMultiBody model from URDF.
|
/// Create a btMultiBody model from URDF.
|
||||||
/// This is adapted from Bullet URDF loader example
|
/// This is adapted from Bullet URDF loader example
|
||||||
class MyBtMultiBodyFromURDF {
|
class MyBtMultiBodyFromURDF
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor
|
/// ctor
|
||||||
/// @param gravity gravitational acceleration (in world frame)
|
/// @param gravity gravitational acceleration (in world frame)
|
||||||
/// @param base_fixed if true, the root body is treated as fixed,
|
/// @param base_fixed if true, the root body is treated as fixed,
|
||||||
/// if false, it is treated as floating
|
/// if false, it is treated as floating
|
||||||
MyBtMultiBodyFromURDF(const btVector3 &gravity, const bool base_fixed)
|
MyBtMultiBodyFromURDF(const btVector3 &gravity, const bool base_fixed)
|
||||||
: m_gravity(gravity), m_base_fixed(base_fixed) {
|
: m_gravity(gravity), m_base_fixed(base_fixed)
|
||||||
|
{
|
||||||
m_broadphase = 0x0;
|
m_broadphase = 0x0;
|
||||||
m_dispatcher = 0x0;
|
m_dispatcher = 0x0;
|
||||||
m_solver = 0x0;
|
m_solver = 0x0;
|
||||||
@@ -30,7 +32,8 @@ public:
|
|||||||
m_multibody = 0x0;
|
m_multibody = 0x0;
|
||||||
}
|
}
|
||||||
/// dtor
|
/// dtor
|
||||||
~MyBtMultiBodyFromURDF() {
|
~MyBtMultiBodyFromURDF()
|
||||||
|
{
|
||||||
delete m_dynamicsWorld;
|
delete m_dynamicsWorld;
|
||||||
delete m_solver;
|
delete m_solver;
|
||||||
delete m_broadphase;
|
delete m_broadphase;
|
||||||
@@ -41,14 +44,16 @@ public:
|
|||||||
/// @param name path to urdf file
|
/// @param name path to urdf file
|
||||||
void setFileName(const std::string name) { m_filename = name; }
|
void setFileName(const std::string name) { m_filename = name; }
|
||||||
/// load urdf file and build btMultiBody model
|
/// load urdf file and build btMultiBody model
|
||||||
void init() {
|
void init()
|
||||||
|
{
|
||||||
this->createEmptyDynamicsWorld();
|
this->createEmptyDynamicsWorld();
|
||||||
m_dynamicsWorld->setGravity(m_gravity);
|
m_dynamicsWorld->setGravity(m_gravity);
|
||||||
BulletURDFImporter urdf_importer(&m_nogfx,0,1,0);
|
BulletURDFImporter urdf_importer(&m_nogfx, 0, 1, 0);
|
||||||
URDFImporterInterface &u2b(urdf_importer);
|
URDFImporterInterface &u2b(urdf_importer);
|
||||||
bool loadOk = u2b.loadURDF(m_filename.c_str(), m_base_fixed);
|
bool loadOk = u2b.loadURDF(m_filename.c_str(), m_base_fixed);
|
||||||
|
|
||||||
if (loadOk) {
|
if (loadOk)
|
||||||
|
{
|
||||||
btTransform identityTrans;
|
btTransform identityTrans;
|
||||||
identityTrans.setIdentity();
|
identityTrans.setIdentity();
|
||||||
MyMultiBodyCreator creation(&m_nogfx);
|
MyMultiBodyCreator creation(&m_nogfx);
|
||||||
@@ -64,7 +69,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// internal utility function
|
// internal utility function
|
||||||
void createEmptyDynamicsWorld() {
|
void createEmptyDynamicsWorld()
|
||||||
|
{
|
||||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||||
|
|
||||||
/// use the default collision dispatcher. For parallel processing you can use a diffent
|
/// use the default collision dispatcher. For parallel processing you can use a diffent
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
#include "btMultiBodyTreeCreator.hpp"
|
#include "btMultiBodyTreeCreator.hpp"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
btMultiBodyTreeCreator::btMultiBodyTreeCreator() : m_initialized(false) {}
|
btMultiBodyTreeCreator::btMultiBodyTreeCreator() : m_initialized(false) {}
|
||||||
|
|
||||||
int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const bool verbose) {
|
int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const bool verbose)
|
||||||
if (0x0 == btmb) {
|
{
|
||||||
|
if (0x0 == btmb)
|
||||||
|
{
|
||||||
bt_id_error_message("cannot create MultiBodyTree from null pointer\n");
|
bt_id_error_message("cannot create MultiBodyTree from null pointer\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -22,12 +24,15 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
LinkData &link = m_data[0];
|
LinkData &link = m_data[0];
|
||||||
|
|
||||||
link.parent_index = -1;
|
link.parent_index = -1;
|
||||||
if (btmb->hasFixedBase()) {
|
if (btmb->hasFixedBase())
|
||||||
|
{
|
||||||
link.joint_type = FIXED;
|
link.joint_type = FIXED;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
link.joint_type = FLOATING;
|
link.joint_type = FLOATING;
|
||||||
}
|
}
|
||||||
btTransform transform=(btmb->getBaseWorldTransform());
|
btTransform transform = (btmb->getBaseWorldTransform());
|
||||||
//compute inverse dynamics in body-fixed frame
|
//compute inverse dynamics in body-fixed frame
|
||||||
transform.setIdentity();
|
transform.setIdentity();
|
||||||
|
|
||||||
@@ -70,8 +75,10 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
// shift reference point to link origin (in joint axis)
|
// shift reference point to link origin (in joint axis)
|
||||||
mat33 tilde_r_com = tildeOperator(link.body_r_body_com);
|
mat33 tilde_r_com = tildeOperator(link.body_r_body_com);
|
||||||
link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com;
|
link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com;
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
id_printf("base: mass= %f, bt_inertia= [%f %f %f]\n"
|
{
|
||||||
|
id_printf(
|
||||||
|
"base: mass= %f, bt_inertia= [%f %f %f]\n"
|
||||||
"Io= [%f %f %f;\n"
|
"Io= [%f %f %f;\n"
|
||||||
" %f %f %f;\n"
|
" %f %f %f;\n"
|
||||||
" %f %f %f]\n",
|
" %f %f %f]\n",
|
||||||
@@ -83,8 +90,10 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int bt_index = 0; bt_index < btmb->getNumLinks(); bt_index++) {
|
for (int bt_index = 0; bt_index < btmb->getNumLinks(); bt_index++)
|
||||||
if (verbose) {
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
id_printf("bt->id: converting link %d\n", bt_index);
|
id_printf("bt->id: converting link %d\n", bt_index);
|
||||||
}
|
}
|
||||||
const btMultibodyLink &bt_link = btmb->getLink(bt_index);
|
const btMultibodyLink &bt_link = btmb->getLink(bt_index);
|
||||||
@@ -93,14 +102,16 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
link.parent_index = bt_link.m_parent + 1;
|
link.parent_index = bt_link.m_parent + 1;
|
||||||
|
|
||||||
link.mass = bt_link.m_mass;
|
link.mass = bt_link.m_mass;
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
id_printf("mass= %f\n", link.mass);
|
id_printf("mass= %f\n", link.mass);
|
||||||
}
|
}
|
||||||
// from this body's pivot to this body's com in this body's frame
|
// from this body's pivot to this body's com in this body's frame
|
||||||
link.body_r_body_com[0] = bt_link.m_dVector[0];
|
link.body_r_body_com[0] = bt_link.m_dVector[0];
|
||||||
link.body_r_body_com[1] = bt_link.m_dVector[1];
|
link.body_r_body_com[1] = bt_link.m_dVector[1];
|
||||||
link.body_r_body_com[2] = bt_link.m_dVector[2];
|
link.body_r_body_com[2] = bt_link.m_dVector[2];
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
id_printf("com= %f %f %f\n", link.body_r_body_com[0], link.body_r_body_com[1],
|
id_printf("com= %f %f %f\n", link.body_r_body_com[0], link.body_r_body_com[1],
|
||||||
link.body_r_body_com[2]);
|
link.body_r_body_com[2]);
|
||||||
}
|
}
|
||||||
@@ -118,8 +129,10 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
mat33 tilde_r_com = tildeOperator(link.body_r_body_com);
|
mat33 tilde_r_com = tildeOperator(link.body_r_body_com);
|
||||||
link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com;
|
link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
id_printf("link %d: mass= %f, bt_inertia= [%f %f %f]\n"
|
{
|
||||||
|
id_printf(
|
||||||
|
"link %d: mass= %f, bt_inertia= [%f %f %f]\n"
|
||||||
"Io= [%f %f %f;\n"
|
"Io= [%f %f %f;\n"
|
||||||
" %f %f %f;\n"
|
" %f %f %f;\n"
|
||||||
" %f %f %f]\n",
|
" %f %f %f]\n",
|
||||||
@@ -140,17 +153,21 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
link.body_T_parent_ref(2, 0) = basis[2][0];
|
link.body_T_parent_ref(2, 0) = basis[2][0];
|
||||||
link.body_T_parent_ref(2, 1) = basis[2][1];
|
link.body_T_parent_ref(2, 1) = basis[2][1];
|
||||||
link.body_T_parent_ref(2, 2) = basis[2][2];
|
link.body_T_parent_ref(2, 2) = basis[2][2];
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
id_printf("body_T_parent_ref= %f %f %f\n"
|
{
|
||||||
|
id_printf(
|
||||||
|
"body_T_parent_ref= %f %f %f\n"
|
||||||
" %f %f %f\n"
|
" %f %f %f\n"
|
||||||
" %f %f %f\n",
|
" %f %f %f\n",
|
||||||
basis[0][0], basis[0][1], basis[0][2], basis[1][0], basis[1][1], basis[1][2],
|
basis[0][0], basis[0][1], basis[0][2], basis[1][0], basis[1][1], basis[1][2],
|
||||||
basis[2][0], basis[2][1], basis[2][2]);
|
basis[2][0], basis[2][1], basis[2][2]);
|
||||||
}
|
}
|
||||||
switch (bt_link.m_jointType) {
|
switch (bt_link.m_jointType)
|
||||||
|
{
|
||||||
case btMultibodyLink::eRevolute:
|
case btMultibodyLink::eRevolute:
|
||||||
link.joint_type = REVOLUTE;
|
link.joint_type = REVOLUTE;
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
id_printf("type= revolute\n");
|
id_printf("type= revolute\n");
|
||||||
}
|
}
|
||||||
link.body_axis_of_motion(0) = bt_link.m_axes[0].m_topVec[0];
|
link.body_axis_of_motion(0) = bt_link.m_axes[0].m_topVec[0];
|
||||||
@@ -166,7 +183,8 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
break;
|
break;
|
||||||
case btMultibodyLink::ePrismatic:
|
case btMultibodyLink::ePrismatic:
|
||||||
link.joint_type = PRISMATIC;
|
link.joint_type = PRISMATIC;
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
id_printf("type= prismatic\n");
|
id_printf("type= prismatic\n");
|
||||||
}
|
}
|
||||||
link.body_axis_of_motion(0) = bt_link.m_axes[0].m_bottomVec[0];
|
link.body_axis_of_motion(0) = bt_link.m_axes[0].m_bottomVec[0];
|
||||||
@@ -207,18 +225,22 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
bt_link.m_jointType);
|
bt_link.m_jointType);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (link.parent_index > 0) { // parent body isn't the root
|
if (link.parent_index > 0)
|
||||||
|
{ // parent body isn't the root
|
||||||
const btMultibodyLink &bt_parent_link = btmb->getLink(link.parent_index - 1);
|
const btMultibodyLink &bt_parent_link = btmb->getLink(link.parent_index - 1);
|
||||||
// from parent pivot to parent com, in parent frame
|
// from parent pivot to parent com, in parent frame
|
||||||
link.parent_r_parent_body_ref(0) += bt_parent_link.m_dVector[0];
|
link.parent_r_parent_body_ref(0) += bt_parent_link.m_dVector[0];
|
||||||
link.parent_r_parent_body_ref(1) += bt_parent_link.m_dVector[1];
|
link.parent_r_parent_body_ref(1) += bt_parent_link.m_dVector[1];
|
||||||
link.parent_r_parent_body_ref(2) += bt_parent_link.m_dVector[2];
|
link.parent_r_parent_body_ref(2) += bt_parent_link.m_dVector[2];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// parent is root body. btMultiBody only knows 6-DoF or 0-DoF root bodies,
|
// parent is root body. btMultiBody only knows 6-DoF or 0-DoF root bodies,
|
||||||
// whose link frame is in the CoM (ie, no notion of a pivot point)
|
// whose link frame is in the CoM (ie, no notion of a pivot point)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
id_printf("parent_r_parent_body_ref= %f %f %f\n", link.parent_r_parent_body_ref[0],
|
id_printf("parent_r_parent_body_ref= %f %f %f\n", link.parent_r_parent_body_ref[0],
|
||||||
link.parent_r_parent_body_ref[1], link.parent_r_parent_body_ref[2]);
|
link.parent_r_parent_body_ref[1], link.parent_r_parent_body_ref[2]);
|
||||||
}
|
}
|
||||||
@@ -229,8 +251,10 @@ int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int btMultiBodyTreeCreator::getNumBodies(int *num_bodies) const {
|
int btMultiBodyTreeCreator::getNumBodies(int *num_bodies) const
|
||||||
if (false == m_initialized) {
|
{
|
||||||
|
if (false == m_initialized)
|
||||||
|
{
|
||||||
bt_id_error_message("btMultiBody not converted yet\n");
|
bt_id_error_message("btMultiBody not converted yet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -243,13 +267,16 @@ int btMultiBodyTreeCreator::getBody(const int body_index, int *parent_index, Joi
|
|||||||
vec3 *parent_r_parent_body_ref, mat33 *body_T_parent_ref,
|
vec3 *parent_r_parent_body_ref, mat33 *body_T_parent_ref,
|
||||||
vec3 *body_axis_of_motion, idScalar *mass,
|
vec3 *body_axis_of_motion, idScalar *mass,
|
||||||
vec3 *body_r_body_com, mat33 *body_I_body, int *user_int,
|
vec3 *body_r_body_com, mat33 *body_I_body, int *user_int,
|
||||||
void **user_ptr) const {
|
void **user_ptr) const
|
||||||
if (false == m_initialized) {
|
{
|
||||||
|
if (false == m_initialized)
|
||||||
|
{
|
||||||
bt_id_error_message("MultiBodyTree not created yet\n");
|
bt_id_error_message("MultiBodyTree not created yet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body_index < 0 || body_index >= static_cast<int>(m_data.size())) {
|
if (body_index < 0 || body_index >= static_cast<int>(m_data.size()))
|
||||||
|
{
|
||||||
bt_id_error_message("index out of range (got %d but only %zu bodies)\n", body_index,
|
bt_id_error_message("index out of range (got %d but only %zu bodies)\n", body_index,
|
||||||
m_data.size());
|
m_data.size());
|
||||||
return -1;
|
return -1;
|
||||||
@@ -269,4 +296,4 @@ int btMultiBodyTreeCreator::getBody(const int body_index, int *parent_index, Joi
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -7,11 +7,12 @@
|
|||||||
#include "MultiBodyTreeCreator.hpp"
|
#include "MultiBodyTreeCreator.hpp"
|
||||||
#include "BulletDynamics/Featherstone/btMultiBody.h"
|
#include "BulletDynamics/Featherstone/btMultiBody.h"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
/// MultiBodyTreeCreator implementation for converting
|
/// MultiBodyTreeCreator implementation for converting
|
||||||
/// a btMultiBody forward dynamics model into a MultiBodyTree inverse dynamics model
|
/// a btMultiBody forward dynamics model into a MultiBodyTree inverse dynamics model
|
||||||
class btMultiBodyTreeCreator : public MultiBodyTreeCreator {
|
class btMultiBodyTreeCreator : public MultiBodyTreeCreator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// ctor
|
/// ctor
|
||||||
btMultiBodyTreeCreator();
|
btMultiBodyTreeCreator();
|
||||||
@@ -32,7 +33,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// internal struct holding data extracted from btMultiBody
|
// internal struct holding data extracted from btMultiBody
|
||||||
struct LinkData {
|
struct LinkData
|
||||||
|
{
|
||||||
int parent_index;
|
int parent_index;
|
||||||
JointType joint_type;
|
JointType joint_type;
|
||||||
vec3 parent_r_parent_body_ref;
|
vec3 parent_r_parent_body_ref;
|
||||||
@@ -45,6 +47,6 @@ private:
|
|||||||
idArray<LinkData>::type m_data;
|
idArray<LinkData>::type m_data;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
};
|
};
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|
||||||
#endif // BTMULTIBODYTREECREATOR_HPP_
|
#endif // BTMULTIBODYTREECREATOR_HPP_
|
||||||
|
|||||||
@@ -8,20 +8,25 @@
|
|||||||
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
|
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
|
||||||
#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
|
#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &gravity, bool verbose,
|
int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &gravity, bool verbose,
|
||||||
btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error,
|
btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error,
|
||||||
double *acc_error) {
|
double *acc_error)
|
||||||
|
{
|
||||||
// call function and return -1 if it does, printing an bt_id_error_message
|
// call function and return -1 if it does, printing an bt_id_error_message
|
||||||
#define RETURN_ON_FAILURE(x) \
|
#define RETURN_ON_FAILURE(x) \
|
||||||
do { \
|
do \
|
||||||
if (-1 == x) { \
|
{ \
|
||||||
|
if (-1 == x) \
|
||||||
|
{ \
|
||||||
bt_id_error_message("calling " #x "\n"); \
|
bt_id_error_message("calling " #x "\n"); \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("\n ===================================== \n");
|
printf("\n ===================================== \n");
|
||||||
}
|
}
|
||||||
vecx joint_forces(q.size());
|
vecx joint_forces(q.size());
|
||||||
@@ -50,37 +55,47 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
|
|
||||||
// remaining links
|
// remaining links
|
||||||
int q_index;
|
int q_index;
|
||||||
if (btmb->hasFixedBase()) {
|
if (btmb->hasFixedBase())
|
||||||
|
{
|
||||||
q_index = 0;
|
q_index = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
q_index = 6;
|
q_index = 6;
|
||||||
}
|
}
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("bt:num_links= %d, num_dofs= %d\n", btmb->getNumLinks(), btmb->getNumDofs());
|
printf("bt:num_links= %d, num_dofs= %d\n", btmb->getNumLinks(), btmb->getNumDofs());
|
||||||
}
|
}
|
||||||
for (int l = 0; l < btmb->getNumLinks(); l++) {
|
for (int l = 0; l < btmb->getNumLinks(); l++)
|
||||||
|
{
|
||||||
const btMultibodyLink &link = btmb->getLink(l);
|
const btMultibodyLink &link = btmb->getLink(l);
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("link %d, pos_var_count= %d, dof_count= %d\n", l, link.m_posVarCount,
|
printf("link %d, pos_var_count= %d, dof_count= %d\n", l, link.m_posVarCount,
|
||||||
link.m_dofCount);
|
link.m_dofCount);
|
||||||
}
|
}
|
||||||
if (link.m_posVarCount == 1) {
|
if (link.m_posVarCount == 1)
|
||||||
|
{
|
||||||
btmb->setJointPosMultiDof(l, &q(q_index));
|
btmb->setJointPosMultiDof(l, &q(q_index));
|
||||||
btmb->setJointVelMultiDof(l, &u(q_index));
|
btmb->setJointVelMultiDof(l, &u(q_index));
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("set q[%d]= %f, u[%d]= %f\n", q_index, q(q_index), q_index, u(q_index));
|
printf("set q[%d]= %f, u[%d]= %f\n", q_index, q(q_index), q_index, u(q_index));
|
||||||
}
|
}
|
||||||
q_index++;
|
q_index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sanity check
|
// sanity check
|
||||||
if (q_index != q.size()) {
|
if (q_index != q.size())
|
||||||
|
{
|
||||||
bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n");
|
bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run inverse dynamics to determine joint_forces for given q, u, dot_u
|
// run inverse dynamics to determine joint_forces for given q, u, dot_u
|
||||||
if (-1 == id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces)) {
|
if (-1 == id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces))
|
||||||
|
{
|
||||||
bt_id_error_message("calculating inverse dynamics\n");
|
bt_id_error_message("calculating inverse dynamics\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -95,9 +110,11 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
// apply gravity forces for btMultiBody model. Must be done manually.
|
// apply gravity forces for btMultiBody model. Must be done manually.
|
||||||
btmb->addBaseForce(btmb->getBaseMass() * gravity);
|
btmb->addBaseForce(btmb->getBaseMass() * gravity);
|
||||||
|
|
||||||
for (int link = 0; link < btmb->getNumLinks(); link++) {
|
for (int link = 0; link < btmb->getNumLinks(); link++)
|
||||||
|
{
|
||||||
btmb->addLinkForce(link, gravity * btmb->getLinkMass(link));
|
btmb->addLinkForce(link, gravity * btmb->getLinkMass(link));
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("link %d, applying gravity %f %f %f\n", link,
|
printf("link %d, applying gravity %f %f %f\n", link,
|
||||||
gravity[0] * btmb->getLinkMass(link), gravity[1] * btmb->getLinkMass(link),
|
gravity[0] * btmb->getLinkMass(link), gravity[1] * btmb->getLinkMass(link),
|
||||||
gravity[2] * btmb->getLinkMass(link));
|
gravity[2] * btmb->getLinkMass(link));
|
||||||
@@ -105,9 +122,12 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply generalized forces
|
// apply generalized forces
|
||||||
if (btmb->hasFixedBase()) {
|
if (btmb->hasFixedBase())
|
||||||
|
{
|
||||||
q_index = 0;
|
q_index = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vec3 base_force;
|
vec3 base_force;
|
||||||
base_force(0) = joint_forces(3);
|
base_force(0) = joint_forces(3);
|
||||||
base_force(1) = joint_forces(4);
|
base_force(1) = joint_forces(4);
|
||||||
@@ -120,7 +140,8 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
|
|
||||||
btmb->addBaseForce(world_T_base * base_force);
|
btmb->addBaseForce(world_T_base * base_force);
|
||||||
btmb->addBaseTorque(world_T_base * base_moment);
|
btmb->addBaseTorque(world_T_base * base_moment);
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("base force from id: %f %f %f\n", joint_forces(3), joint_forces(4),
|
printf("base force from id: %f %f %f\n", joint_forces(3), joint_forces(4),
|
||||||
joint_forces(5));
|
joint_forces(5));
|
||||||
printf("base moment from id: %f %f %f\n", joint_forces(0), joint_forces(1),
|
printf("base moment from id: %f %f %f\n", joint_forces(0), joint_forces(1),
|
||||||
@@ -129,10 +150,13 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
q_index = 6;
|
q_index = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int l = 0; l < btmb->getNumLinks(); l++) {
|
for (int l = 0; l < btmb->getNumLinks(); l++)
|
||||||
|
{
|
||||||
const btMultibodyLink &link = btmb->getLink(l);
|
const btMultibodyLink &link = btmb->getLink(l);
|
||||||
if (link.m_posVarCount == 1) {
|
if (link.m_posVarCount == 1)
|
||||||
if (verbose) {
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
printf("id:joint_force[%d]= %f, applied to link %d\n", q_index,
|
printf("id:joint_force[%d]= %f, applied to link %d\n", q_index,
|
||||||
joint_forces(q_index), l);
|
joint_forces(q_index), l);
|
||||||
}
|
}
|
||||||
@@ -142,7 +166,8 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (q_index != q.size()) {
|
if (q_index != q.size())
|
||||||
|
{
|
||||||
bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n");
|
bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -160,21 +185,29 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
btScalar *joint_accel = base_accel + 6;
|
btScalar *joint_accel = base_accel + 6;
|
||||||
*acc_error = 0;
|
*acc_error = 0;
|
||||||
int dot_u_offset = 0;
|
int dot_u_offset = 0;
|
||||||
if (btmb->hasFixedBase()) {
|
if (btmb->hasFixedBase())
|
||||||
|
{
|
||||||
dot_u_offset = 0;
|
dot_u_offset = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
dot_u_offset = 6;
|
dot_u_offset = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true == btmb->hasFixedBase()) {
|
if (true == btmb->hasFixedBase())
|
||||||
for (int i = 0; i < btmb->getNumDofs(); i++) {
|
{
|
||||||
if (verbose) {
|
for (int i = 0; i < btmb->getNumDofs(); i++)
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i],
|
printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i],
|
||||||
dot_u(i + dot_u_offset), joint_accel[i] - dot_u(i));
|
dot_u(i + dot_u_offset), joint_accel[i] - dot_u(i));
|
||||||
}
|
}
|
||||||
*acc_error += BT_ID_POW(joint_accel[i] - dot_u(i + dot_u_offset), 2);
|
*acc_error += BT_ID_POW(joint_accel[i] - dot_u(i + dot_u_offset), 2);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
vec3 base_dot_omega;
|
vec3 base_dot_omega;
|
||||||
vec3 world_dot_omega;
|
vec3 world_dot_omega;
|
||||||
world_dot_omega(0) = base_accel[0];
|
world_dot_omega(0) = base_accel[0];
|
||||||
@@ -189,25 +222,31 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
world_ddot_com(0) = base_accel[3];
|
world_ddot_com(0) = base_accel[3];
|
||||||
world_ddot_com(1) = base_accel[4];
|
world_ddot_com(1) = base_accel[4];
|
||||||
world_ddot_com(2) = base_accel[5];
|
world_ddot_com(2) = base_accel[5];
|
||||||
base_ddot_com = world_T_base.transpose()*world_ddot_com;
|
base_ddot_com = world_T_base.transpose() * world_ddot_com;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++)
|
||||||
if (verbose) {
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
printf("bt::base_dot_omega(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_dot_omega(i),
|
printf("bt::base_dot_omega(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_dot_omega(i),
|
||||||
i, dot_u[i], base_dot_omega(i) - dot_u[i]);
|
i, dot_u[i], base_dot_omega(i) - dot_u[i]);
|
||||||
}
|
}
|
||||||
*acc_error += BT_ID_POW(base_dot_omega(i) - dot_u(i), 2);
|
*acc_error += BT_ID_POW(base_dot_omega(i) - dot_u(i), 2);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++)
|
||||||
if (verbose) {
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
printf("bt::base_ddot_com(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_ddot_com(i),
|
printf("bt::base_ddot_com(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_ddot_com(i),
|
||||||
i, dot_u[i + 3], base_ddot_com(i) - dot_u[i + 3]);
|
i, dot_u[i + 3], base_ddot_com(i) - dot_u[i + 3]);
|
||||||
}
|
}
|
||||||
*acc_error += BT_ID_POW(base_ddot_com(i) - dot_u(i + 3), 2);
|
*acc_error += BT_ID_POW(base_ddot_com(i) - dot_u(i + 3), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < btmb->getNumDofs(); i++) {
|
for (int i = 0; i < btmb->getNumDofs(); i++)
|
||||||
if (verbose) {
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i],
|
printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i],
|
||||||
dot_u(i + 6), joint_accel[i] - dot_u(i + 6));
|
dot_u(i + 6), joint_accel[i] - dot_u(i + 6));
|
||||||
}
|
}
|
||||||
@@ -215,26 +254,31 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*acc_error = std::sqrt(*acc_error);
|
*acc_error = std::sqrt(*acc_error);
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("======dynamics-err: %e\n", *acc_error);
|
printf("======dynamics-err: %e\n", *acc_error);
|
||||||
}
|
}
|
||||||
*pos_error = 0.0;
|
*pos_error = 0.0;
|
||||||
|
|
||||||
{
|
{
|
||||||
mat33 world_T_body;
|
mat33 world_T_body;
|
||||||
if (-1 == id_tree->getBodyTransform(0, &world_T_body)) {
|
if (-1 == id_tree->getBodyTransform(0, &world_T_body))
|
||||||
|
{
|
||||||
bt_id_error_message("getting transform for body %d\n", 0);
|
bt_id_error_message("getting transform for body %d\n", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
vec3 world_com;
|
vec3 world_com;
|
||||||
if (-1 == id_tree->getBodyCoM(0, &world_com)) {
|
if (-1 == id_tree->getBodyCoM(0, &world_com))
|
||||||
|
{
|
||||||
bt_id_error_message("getting com for body %d\n", 0);
|
bt_id_error_message("getting com for body %d\n", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("id:com: %f %f %f\n", world_com(0), world_com(1), world_com(2));
|
printf("id:com: %f %f %f\n", world_com(0), world_com(1), world_com(2));
|
||||||
|
|
||||||
printf("id:transform: %f %f %f\n"
|
printf(
|
||||||
|
"id:transform: %f %f %f\n"
|
||||||
" %f %f %f\n"
|
" %f %f %f\n"
|
||||||
" %f %f %f\n",
|
" %f %f %f\n",
|
||||||
world_T_body(0, 0), world_T_body(0, 1), world_T_body(0, 2), world_T_body(1, 0),
|
world_T_body(0, 0), world_T_body(0, 1), world_T_body(0, 2), world_T_body(1, 0),
|
||||||
@@ -243,15 +287,18 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int l = 0; l < btmb->getNumLinks(); l++) {
|
for (int l = 0; l < btmb->getNumLinks(); l++)
|
||||||
|
{
|
||||||
const btMultibodyLink &bt_link = btmb->getLink(l);
|
const btMultibodyLink &bt_link = btmb->getLink(l);
|
||||||
|
|
||||||
vec3 bt_origin = bt_link.m_cachedWorldTransform.getOrigin();
|
vec3 bt_origin = bt_link.m_cachedWorldTransform.getOrigin();
|
||||||
mat33 bt_basis = bt_link.m_cachedWorldTransform.getBasis();
|
mat33 bt_basis = bt_link.m_cachedWorldTransform.getBasis();
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("------------- link %d\n", l + 1);
|
printf("------------- link %d\n", l + 1);
|
||||||
printf("bt:com: %f %f %f\n", bt_origin(0), bt_origin(1), bt_origin(2));
|
printf("bt:com: %f %f %f\n", bt_origin(0), bt_origin(1), bt_origin(2));
|
||||||
printf("bt:transform: %f %f %f\n"
|
printf(
|
||||||
|
"bt:transform: %f %f %f\n"
|
||||||
" %f %f %f\n"
|
" %f %f %f\n"
|
||||||
" %f %f %f\n",
|
" %f %f %f\n",
|
||||||
bt_basis(0, 0), bt_basis(0, 1), bt_basis(0, 2), bt_basis(1, 0), bt_basis(1, 1),
|
bt_basis(0, 0), bt_basis(0, 1), bt_basis(0, 2), bt_basis(1, 0), bt_basis(1, 1),
|
||||||
@@ -260,18 +307,22 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
mat33 id_world_T_body;
|
mat33 id_world_T_body;
|
||||||
vec3 id_world_com;
|
vec3 id_world_com;
|
||||||
|
|
||||||
if (-1 == id_tree->getBodyTransform(l + 1, &id_world_T_body)) {
|
if (-1 == id_tree->getBodyTransform(l + 1, &id_world_T_body))
|
||||||
|
{
|
||||||
bt_id_error_message("getting transform for body %d\n", l);
|
bt_id_error_message("getting transform for body %d\n", l);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (-1 == id_tree->getBodyCoM(l + 1, &id_world_com)) {
|
if (-1 == id_tree->getBodyCoM(l + 1, &id_world_com))
|
||||||
|
{
|
||||||
bt_id_error_message("getting com for body %d\n", l);
|
bt_id_error_message("getting com for body %d\n", l);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("id:com: %f %f %f\n", id_world_com(0), id_world_com(1), id_world_com(2));
|
printf("id:com: %f %f %f\n", id_world_com(0), id_world_com(1), id_world_com(2));
|
||||||
|
|
||||||
printf("id:transform: %f %f %f\n"
|
printf(
|
||||||
|
"id:transform: %f %f %f\n"
|
||||||
" %f %f %f\n"
|
" %f %f %f\n"
|
||||||
" %f %f %f\n",
|
" %f %f %f\n",
|
||||||
id_world_T_body(0, 0), id_world_T_body(0, 1), id_world_T_body(0, 2),
|
id_world_T_body(0, 0), id_world_T_body(0, 1), id_world_T_body(0, 2),
|
||||||
@@ -280,7 +331,8 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
}
|
}
|
||||||
vec3 diff_com = bt_origin - id_world_com;
|
vec3 diff_com = bt_origin - id_world_com;
|
||||||
mat33 diff_basis = bt_basis - id_world_T_body;
|
mat33 diff_basis = bt_basis - id_world_T_body;
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("diff-com: %e %e %e\n", diff_com(0), diff_com(1), diff_com(2));
|
printf("diff-com: %e %e %e\n", diff_com(0), diff_com(1), diff_com(2));
|
||||||
|
|
||||||
printf("diff-transform: %e %e %e %e %e %e %e %e %e\n", diff_basis(0, 0),
|
printf("diff-transform: %e %e %e %e %e %e %e %e %e\n", diff_basis(0, 0),
|
||||||
@@ -294,14 +346,16 @@ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &g
|
|||||||
BT_ID_POW(diff_basis(1, 0), 2) + BT_ID_POW(diff_basis(1, 1), 2) +
|
BT_ID_POW(diff_basis(1, 0), 2) + BT_ID_POW(diff_basis(1, 1), 2) +
|
||||||
BT_ID_POW(diff_basis(1, 2), 2) + BT_ID_POW(diff_basis(2, 0), 2) +
|
BT_ID_POW(diff_basis(1, 2), 2) + BT_ID_POW(diff_basis(2, 0), 2) +
|
||||||
BT_ID_POW(diff_basis(2, 1), 2) + BT_ID_POW(diff_basis(2, 2), 2));
|
BT_ID_POW(diff_basis(2, 1), 2) + BT_ID_POW(diff_basis(2, 2), 2));
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
printf("======kin-pos-err: %e\n", total_pos_err);
|
printf("======kin-pos-err: %e\n", total_pos_err);
|
||||||
}
|
}
|
||||||
if (total_pos_err > *pos_error) {
|
if (total_pos_err > *pos_error)
|
||||||
|
{
|
||||||
*pos_error = total_pos_err;
|
*pos_error = total_pos_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
class btMultiBody;
|
class btMultiBody;
|
||||||
class btVector3;
|
class btVector3;
|
||||||
|
|
||||||
namespace btInverseDynamics {
|
namespace btInverseDynamics
|
||||||
|
{
|
||||||
class MultiBodyTree;
|
class MultiBodyTree;
|
||||||
|
|
||||||
/// this function compares the forward dynamics computations implemented in btMultiBody to
|
/// this function compares the forward dynamics computations implemented in btMultiBody to
|
||||||
@@ -31,5 +32,5 @@ class MultiBodyTree;
|
|||||||
int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &gravity, bool verbose,
|
int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &gravity, bool verbose,
|
||||||
btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error,
|
btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error,
|
||||||
double *acc_error);
|
double *acc_error);
|
||||||
}
|
} // namespace btInverseDynamics
|
||||||
#endif // INVDYN_BULLET_COMPARISON_HPP
|
#endif // INVDYN_BULLET_COMPARISON_HPP
|
||||||
|
|||||||
@@ -27,32 +27,27 @@ extern int DNAlen;
|
|||||||
extern unsigned char DNAstr64[];
|
extern unsigned char DNAstr64[];
|
||||||
extern int DNAlen64;
|
extern int DNAlen64;
|
||||||
|
|
||||||
|
|
||||||
using namespace bParse;
|
using namespace bParse;
|
||||||
|
|
||||||
bBlenderFile::bBlenderFile(const char* fileName)
|
bBlenderFile::bBlenderFile(const char *fileName)
|
||||||
:bFile(fileName, "BLENDER")
|
: bFile(fileName, "BLENDER")
|
||||||
{
|
{
|
||||||
mMain= new bMain(this, fileName, mVersion);
|
mMain = new bMain(this, fileName, mVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bBlenderFile::bBlenderFile(char *memoryBuffer, int len)
|
bBlenderFile::bBlenderFile(char *memoryBuffer, int len)
|
||||||
:bFile(memoryBuffer,len, "BLENDER"),
|
: bFile(memoryBuffer, len, "BLENDER"),
|
||||||
mMain(0)
|
mMain(0)
|
||||||
{
|
{
|
||||||
mMain= new bMain(this, "memoryBuf", mVersion);
|
mMain = new bMain(this, "memoryBuf", mVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bBlenderFile::~bBlenderFile()
|
bBlenderFile::~bBlenderFile()
|
||||||
{
|
{
|
||||||
delete mMain;
|
delete mMain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bMain *bBlenderFile::getMain()
|
||||||
bMain* bBlenderFile::getMain()
|
|
||||||
{
|
{
|
||||||
return mMain;
|
return mMain;
|
||||||
}
|
}
|
||||||
@@ -60,20 +55,17 @@ bMain* bBlenderFile::getMain()
|
|||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
void bBlenderFile::parseData()
|
void bBlenderFile::parseData()
|
||||||
{
|
{
|
||||||
// printf ("Building datablocks\n");
|
// printf ("Building datablocks\n");
|
||||||
// printf ("Chunk size = %d\n",CHUNK_HEADER_LEN);
|
// printf ("Chunk size = %d\n",CHUNK_HEADER_LEN);
|
||||||
// printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags));
|
// printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags));
|
||||||
|
|
||||||
const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
|
const bool swap = (mFlags & FD_ENDIAN_SWAP) != 0;
|
||||||
|
|
||||||
|
char *dataPtr = mFileBuffer + mDataStart;
|
||||||
|
|
||||||
char *dataPtr = mFileBuffer+mDataStart;
|
|
||||||
|
|
||||||
bChunkInd dataChunk;
|
bChunkInd dataChunk;
|
||||||
dataChunk.code = 0;
|
dataChunk.code = 0;
|
||||||
|
|
||||||
|
|
||||||
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||||
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||||
//dataPtr += ChunkUtils::getOffset(mFlags);
|
//dataPtr += ChunkUtils::getOffset(mFlags);
|
||||||
@@ -81,34 +73,30 @@ void bBlenderFile::parseData()
|
|||||||
|
|
||||||
while (dataChunk.code != DNA1)
|
while (dataChunk.code != DNA1)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// one behind
|
// one behind
|
||||||
if (dataChunk.code == SDNA) break;
|
if (dataChunk.code == SDNA) break;
|
||||||
//if (dataChunk.code == DNA1) break;
|
//if (dataChunk.code == DNA1) break;
|
||||||
|
|
||||||
// same as (BHEAD+DATA dependency)
|
// same as (BHEAD+DATA dependency)
|
||||||
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
|
dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags);
|
||||||
char *id = readStruct(dataPtrHead, dataChunk);
|
char *id = readStruct(dataPtrHead, dataChunk);
|
||||||
|
|
||||||
// lookup maps
|
// lookup maps
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
|
m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk);
|
||||||
mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id);
|
mLibPointers.insert(dataChunk.oldPtr, (bStructHandle *)id);
|
||||||
|
|
||||||
m_chunks.push_back(dataChunk);
|
m_chunks.push_back(dataChunk);
|
||||||
// block it
|
// block it
|
||||||
bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
|
bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code);
|
||||||
if (listID)
|
if (listID)
|
||||||
listID->push_back((bStructHandle*)id);
|
listID->push_back((bStructHandle *)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == GLOB)
|
if (dataChunk.code == GLOB)
|
||||||
{
|
{
|
||||||
m_glob = (bStructHandle*) id;
|
m_glob = (bStructHandle *)id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// next please!
|
// next please!
|
||||||
@@ -118,18 +106,13 @@ void bBlenderFile::parseData()
|
|||||||
if (seek < 0)
|
if (seek < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bBlenderFile::addDataBlock(char* dataBlock)
|
void bBlenderFile::addDataBlock(char *dataBlock)
|
||||||
{
|
{
|
||||||
mMain->addDatablock(dataBlock);
|
mMain->addDatablock(dataBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 32 && 64 bit versions
|
// 32 && 64 bit versions
|
||||||
extern unsigned char DNAstr[];
|
extern unsigned char DNAstr[];
|
||||||
extern int DNAlen;
|
extern int DNAlen;
|
||||||
@@ -137,14 +120,11 @@ extern int DNAlen;
|
|||||||
//unsigned char DNAstr[]={0};
|
//unsigned char DNAstr[]={0};
|
||||||
//int DNAlen=0;
|
//int DNAlen=0;
|
||||||
|
|
||||||
|
|
||||||
extern unsigned char DNAstr64[];
|
extern unsigned char DNAstr64[];
|
||||||
extern int DNAlen64;
|
extern int DNAlen64;
|
||||||
|
|
||||||
|
void bBlenderFile::writeDNA(FILE *fp)
|
||||||
void bBlenderFile::writeDNA(FILE* fp)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
bChunkInd dataChunk;
|
bChunkInd dataChunk;
|
||||||
dataChunk.code = DNA1;
|
dataChunk.code = DNA1;
|
||||||
dataChunk.dna_nr = 0;
|
dataChunk.dna_nr = 0;
|
||||||
@@ -154,15 +134,15 @@ void bBlenderFile::writeDNA(FILE* fp)
|
|||||||
{
|
{
|
||||||
dataChunk.len = DNAlen64;
|
dataChunk.len = DNAlen64;
|
||||||
dataChunk.oldPtr = DNAstr64;
|
dataChunk.oldPtr = DNAstr64;
|
||||||
fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
|
fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
|
||||||
fwrite(DNAstr64, DNAlen64,1,fp);
|
fwrite(DNAstr64, DNAlen64, 1, fp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataChunk.len = DNAlen;
|
dataChunk.len = DNAlen;
|
||||||
dataChunk.oldPtr = DNAstr;
|
dataChunk.oldPtr = DNAstr;
|
||||||
fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
|
fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
|
||||||
fwrite(DNAstr, DNAlen,1,fp);
|
fwrite(DNAstr, DNAlen, 1, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,55 +150,57 @@ void bBlenderFile::parse(int verboseMode)
|
|||||||
{
|
{
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
parseInternal(verboseMode,(char*)DNAstr64,DNAlen64);
|
parseInternal(verboseMode, (char *)DNAstr64, DNAlen64);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parseInternal(verboseMode,(char*)DNAstr,DNAlen);
|
parseInternal(verboseMode, (char *)DNAstr, DNAlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// experimental
|
// experimental
|
||||||
int bBlenderFile::write(const char* fileName, bool fixupPointers)
|
int bBlenderFile::write(const char *fileName, bool fixupPointers)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(fileName, "wb");
|
FILE *fp = fopen(fileName, "wb");
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
char header[SIZEOFBLENDERHEADER] ;
|
char header[SIZEOFBLENDERHEADER];
|
||||||
memcpy(header, m_headerString, 7);
|
memcpy(header, m_headerString, 7);
|
||||||
int endian= 1;
|
int endian = 1;
|
||||||
endian= ((char*)&endian)[0];
|
endian = ((char *)&endian)[0];
|
||||||
|
|
||||||
if (endian)
|
if (endian)
|
||||||
{
|
{
|
||||||
header[7] = '_';
|
header[7] = '_';
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
header[7] = '-';
|
header[7] = '-';
|
||||||
}
|
}
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
header[8]='V';
|
header[8] = 'V';
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
header[8]='v';
|
header[8] = 'v';
|
||||||
}
|
}
|
||||||
|
|
||||||
header[9] = '2';
|
header[9] = '2';
|
||||||
header[10] = '4';
|
header[10] = '4';
|
||||||
header[11] = '9';
|
header[11] = '9';
|
||||||
|
|
||||||
fwrite(header,SIZEOFBLENDERHEADER,1,fp);
|
fwrite(header, SIZEOFBLENDERHEADER, 1, fp);
|
||||||
|
|
||||||
writeChunks(fp, fixupPointers);
|
writeChunks(fp, fixupPointers);
|
||||||
|
|
||||||
writeDNA(fp);
|
writeDNA(fp);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
}
|
||||||
} else
|
else
|
||||||
{
|
{
|
||||||
printf("Error: cannot open file %s for writing\n",fileName);
|
printf("Error: cannot open file %s for writing\n", fileName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -16,26 +16,22 @@ subject to the following restrictions:
|
|||||||
#ifndef B_BLENDER_FILE_H
|
#ifndef B_BLENDER_FILE_H
|
||||||
#define B_BLENDER_FILE_H
|
#define B_BLENDER_FILE_H
|
||||||
|
|
||||||
|
|
||||||
#include "bFile.h"
|
#include "bFile.h"
|
||||||
|
|
||||||
namespace bParse {
|
namespace bParse
|
||||||
|
{
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
class bBlenderFile : public bFile
|
class bBlenderFile : public bFile
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
protected:
|
|
||||||
bMain* mMain;
|
bMain* mMain;
|
||||||
|
|
||||||
bStructHandle* m_glob;
|
bStructHandle* m_glob;
|
||||||
|
|
||||||
|
public:
|
||||||
public:
|
|
||||||
|
|
||||||
bBlenderFile(const char* fileName);
|
bBlenderFile(const char* fileName);
|
||||||
|
|
||||||
bBlenderFile(char *memoryBuffer, int len);
|
bBlenderFile(char* memoryBuffer, int len);
|
||||||
|
|
||||||
virtual ~bBlenderFile();
|
virtual ~bBlenderFile();
|
||||||
|
|
||||||
@@ -56,8 +52,7 @@ namespace bParse {
|
|||||||
virtual void parseData();
|
virtual void parseData();
|
||||||
|
|
||||||
virtual void writeDNA(FILE* fp);
|
virtual void writeDNA(FILE* fp);
|
||||||
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
}; // namespace bParse
|
||||||
|
|
||||||
#endif //B_BLENDER_FILE_H
|
#endif //B_BLENDER_FILE_H
|
||||||
|
|||||||
@@ -21,51 +21,49 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
using namespace bParse;
|
using namespace bParse;
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
bMain::bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion)
|
bMain::bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion)
|
||||||
: mFP(filePtr),
|
: mFP(filePtr),
|
||||||
mVersion(fileVersion),
|
mVersion(fileVersion),
|
||||||
mName(baseName)
|
mName(baseName)
|
||||||
{
|
{
|
||||||
mData.insert(ID_SCE,bListBasePtr());
|
mData.insert(ID_SCE, bListBasePtr());
|
||||||
mData.insert(ID_LI,bListBasePtr());
|
mData.insert(ID_LI, bListBasePtr());
|
||||||
mData.insert(ID_OB,bListBasePtr());
|
mData.insert(ID_OB, bListBasePtr());
|
||||||
mData.insert(ID_ME,bListBasePtr());
|
mData.insert(ID_ME, bListBasePtr());
|
||||||
mData.insert(ID_CU,bListBasePtr());
|
mData.insert(ID_CU, bListBasePtr());
|
||||||
mData.insert(ID_MB,bListBasePtr());
|
mData.insert(ID_MB, bListBasePtr());
|
||||||
mData.insert(ID_MA,bListBasePtr());
|
mData.insert(ID_MA, bListBasePtr());
|
||||||
mData.insert(ID_TE,bListBasePtr());
|
mData.insert(ID_TE, bListBasePtr());
|
||||||
mData.insert(ID_IM,bListBasePtr());
|
mData.insert(ID_IM, bListBasePtr());
|
||||||
mData.insert(ID_WV,bListBasePtr());
|
mData.insert(ID_WV, bListBasePtr());
|
||||||
mData.insert(ID_LT,bListBasePtr());
|
mData.insert(ID_LT, bListBasePtr());
|
||||||
mData.insert(ID_LA,bListBasePtr());
|
mData.insert(ID_LA, bListBasePtr());
|
||||||
mData.insert(ID_CA,bListBasePtr());
|
mData.insert(ID_CA, bListBasePtr());
|
||||||
mData.insert(ID_IP,bListBasePtr());
|
mData.insert(ID_IP, bListBasePtr());
|
||||||
mData.insert(ID_KE,bListBasePtr());
|
mData.insert(ID_KE, bListBasePtr());
|
||||||
mData.insert(ID_WO,bListBasePtr());
|
mData.insert(ID_WO, bListBasePtr());
|
||||||
mData.insert(ID_SCR,bListBasePtr());
|
mData.insert(ID_SCR, bListBasePtr());
|
||||||
mData.insert(ID_VF,bListBasePtr());
|
mData.insert(ID_VF, bListBasePtr());
|
||||||
mData.insert(ID_TXT,bListBasePtr());
|
mData.insert(ID_TXT, bListBasePtr());
|
||||||
mData.insert(ID_SO,bListBasePtr());
|
mData.insert(ID_SO, bListBasePtr());
|
||||||
mData.insert(ID_GR,bListBasePtr());
|
mData.insert(ID_GR, bListBasePtr());
|
||||||
mData.insert(ID_AR,bListBasePtr());
|
mData.insert(ID_AR, bListBasePtr());
|
||||||
mData.insert(ID_AC,bListBasePtr());
|
mData.insert(ID_AC, bListBasePtr());
|
||||||
mData.insert(ID_NT,bListBasePtr());
|
mData.insert(ID_NT, bListBasePtr());
|
||||||
mData.insert(ID_BR,bListBasePtr());
|
mData.insert(ID_BR, bListBasePtr());
|
||||||
mData.insert(ID_SCRIPT, bListBasePtr());
|
mData.insert(ID_SCRIPT, bListBasePtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
bMain::~bMain()
|
bMain::~bMain()
|
||||||
{
|
{
|
||||||
// allocated data blocks!
|
// allocated data blocks!
|
||||||
|
|
||||||
int sz = mPool.size();
|
int sz = mPool.size();
|
||||||
for (int i=0;i<sz;i++)
|
for (int i = 0; i < sz; i++)
|
||||||
{
|
{
|
||||||
delete [] mPool[i];
|
delete[] mPool[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,16 +83,12 @@ const char *bMain::getName()
|
|||||||
void bMain::addDatablock(void *allocated)
|
void bMain::addDatablock(void *allocated)
|
||||||
{
|
{
|
||||||
assert(allocated);
|
assert(allocated);
|
||||||
mPool.push_back((bStructHandle*)allocated);
|
mPool.push_back((bStructHandle *)allocated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
void bMain::linkList(void *listBasePtr)
|
void bMain::linkList(void *listBasePtr)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ListBase // local Blender::ListBase
|
struct ListBase // local Blender::ListBase
|
||||||
{
|
{
|
||||||
void *first;
|
void *first;
|
||||||
@@ -107,8 +101,7 @@ void bMain::linkList(void *listBasePtr)
|
|||||||
void *prev;
|
void *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ListBase *base = (ListBase *)listBasePtr;
|
||||||
ListBase *base = (ListBase*)listBasePtr;
|
|
||||||
|
|
||||||
if (!base || !base->first)
|
if (!base || !base->first)
|
||||||
return;
|
return;
|
||||||
@@ -121,18 +114,18 @@ void bMain::linkList(void *listBasePtr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *prev = 0;
|
void *prev = 0;
|
||||||
Link *l = (Link*)base->first;
|
Link *l = (Link *)base->first;
|
||||||
while (l)
|
while (l)
|
||||||
{
|
{
|
||||||
l->next = mFP->findLibPointer(l->next);
|
l->next = mFP->findLibPointer(l->next);
|
||||||
l->prev = l->next;
|
l->prev = l->next;
|
||||||
prev = l->next;
|
prev = l->next;
|
||||||
l = (Link*)l->next;
|
l = (Link *)l->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr* bMain::getListBasePtr(int listBaseCode)
|
bListBasePtr *bMain::getListBasePtr(int listBaseCode)
|
||||||
{
|
{
|
||||||
bListBasePtr *ptr = _findCode(listBaseCode);
|
bListBasePtr *ptr = _findCode(listBaseCode);
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
@@ -143,12 +136,10 @@ bListBasePtr* bMain::getListBasePtr(int listBaseCode)
|
|||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr *bMain::_findCode(int code)
|
bListBasePtr *bMain::_findCode(int code)
|
||||||
{
|
{
|
||||||
|
bListBasePtr *lbPtr = mData.find(code);
|
||||||
bListBasePtr* lbPtr = mData.find(code);
|
|
||||||
return lbPtr;
|
return lbPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr *bMain::getScene()
|
bListBasePtr *bMain::getScene()
|
||||||
{
|
{
|
||||||
@@ -193,8 +184,6 @@ bListBasePtr *bMain::getCurve()
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr *bMain::getMball()
|
bListBasePtr *bMain::getMball()
|
||||||
{
|
{
|
||||||
@@ -222,7 +211,6 @@ bListBasePtr *bMain::getTex()
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr *bMain::getImage()
|
bListBasePtr *bMain::getImage()
|
||||||
{
|
{
|
||||||
@@ -295,7 +283,6 @@ bListBasePtr *bMain::getWorld()
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr *bMain::getScreen()
|
bListBasePtr *bMain::getScreen()
|
||||||
{
|
{
|
||||||
@@ -368,7 +355,6 @@ bListBasePtr *bMain::getAction()
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------//
|
// ------------------------------------------------------------//
|
||||||
bListBasePtr *bMain::getNodetree()
|
bListBasePtr *bMain::getNodetree()
|
||||||
{
|
{
|
||||||
@@ -387,6 +373,4 @@ bListBasePtr *bMain::getBrush()
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//eof
|
//eof
|
||||||
|
|||||||
@@ -20,44 +20,35 @@ subject to the following restrictions:
|
|||||||
#include "bChunk.h"
|
#include "bChunk.h"
|
||||||
#include "LinearMath/btHashMap.h"
|
#include "LinearMath/btHashMap.h"
|
||||||
|
|
||||||
|
namespace bParse
|
||||||
|
{
|
||||||
|
class bDNA;
|
||||||
|
|
||||||
|
class bBlenderFile;
|
||||||
|
}; // namespace bParse
|
||||||
|
|
||||||
namespace bParse
|
namespace bParse
|
||||||
{
|
{
|
||||||
class bDNA;
|
// ----------------------------------------------------- //
|
||||||
|
|
||||||
class bBlenderFile;
|
typedef btHashMap<btHashInt, bListBasePtr> bMainDataMap;
|
||||||
};
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------- //
|
||||||
|
class bMain
|
||||||
namespace bParse {
|
{
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
|
||||||
|
|
||||||
typedef btHashMap<btHashInt,bListBasePtr> bMainDataMap;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
|
||||||
class bMain
|
|
||||||
{
|
|
||||||
//private:
|
//private:
|
||||||
public:
|
public:
|
||||||
bBlenderFile* mFP;
|
bBlenderFile *mFP;
|
||||||
bListBasePtr mPool;
|
bListBasePtr mPool;
|
||||||
|
|
||||||
int mVersion;
|
int mVersion;
|
||||||
const char* mName;
|
const char *mName;
|
||||||
|
|
||||||
bMainDataMap mData;
|
bMainDataMap mData;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bListBasePtr *_findCode(int code);
|
bListBasePtr *_findCode(int code);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion);
|
bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion);
|
||||||
~bMain();
|
~bMain();
|
||||||
|
|
||||||
@@ -66,7 +57,6 @@ namespace bParse {
|
|||||||
|
|
||||||
bListBasePtr *getListBasePtr(int listBaseCode);
|
bListBasePtr *getListBasePtr(int listBaseCode);
|
||||||
|
|
||||||
|
|
||||||
bListBasePtr *getScene();
|
bListBasePtr *getScene();
|
||||||
bListBasePtr *getLibrary();
|
bListBasePtr *getLibrary();
|
||||||
bListBasePtr *getObject();
|
bListBasePtr *getObject();
|
||||||
@@ -94,17 +84,13 @@ namespace bParse {
|
|||||||
bListBasePtr *getNodetree();
|
bListBasePtr *getNodetree();
|
||||||
bListBasePtr *getBrush();
|
bListBasePtr *getBrush();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tracking allocated memory
|
// tracking allocated memory
|
||||||
void addDatablock(void *allocated);
|
void addDatablock(void *allocated);
|
||||||
|
|
||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
void linkList(void *listBasePtr);
|
void linkList(void *listBasePtr);
|
||||||
};
|
};
|
||||||
}
|
} // namespace bParse
|
||||||
|
|
||||||
|
#endif //__BMAIN_H__
|
||||||
#endif//__BMAIN_H__
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -17,15 +17,13 @@ subject to the following restrictions:
|
|||||||
#include "bDefines.h"
|
#include "bDefines.h"
|
||||||
#include "bFile.h"
|
#include "bFile.h"
|
||||||
|
|
||||||
#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
|
#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__)
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace bParse;
|
using namespace bParse;
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
short ChunkUtils::swapShort(short sht)
|
short ChunkUtils::swapShort(short sht)
|
||||||
{
|
{
|
||||||
@@ -57,19 +55,15 @@ int ChunkUtils::getOffset(int flags)
|
|||||||
|
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
if (flags &FD_BITS_VARIES)
|
if (flags & FD_BITS_VARIES)
|
||||||
res = sizeof(bChunkPtr4);
|
res = sizeof(bChunkPtr4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (flags &FD_BITS_VARIES)
|
if (flags & FD_BITS_VARIES)
|
||||||
res = sizeof(bChunkPtr8);
|
res = sizeof(bChunkPtr8);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//eof
|
//eof
|
||||||
|
|||||||
@@ -16,64 +16,58 @@ subject to the following restrictions:
|
|||||||
#ifndef __BCHUNK_H__
|
#ifndef __BCHUNK_H__
|
||||||
#define __BCHUNK_H__
|
#define __BCHUNK_H__
|
||||||
|
|
||||||
#if defined (_WIN32) && ! defined (__MINGW32__)
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||||
#define long64 __int64
|
#define long64 __int64
|
||||||
#elif defined (__MINGW32__)
|
#elif defined(__MINGW32__)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define long64 int64_t
|
#define long64 int64_t
|
||||||
#else
|
#else
|
||||||
#define long64 long long
|
#define long64 long long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace bParse
|
||||||
namespace bParse {
|
{
|
||||||
|
// ----------------------------------------------------- //
|
||||||
|
class bChunkPtr4
|
||||||
// ----------------------------------------------------- //
|
{
|
||||||
class bChunkPtr4
|
public:
|
||||||
{
|
bChunkPtr4() {}
|
||||||
public:
|
|
||||||
bChunkPtr4(){}
|
|
||||||
int code;
|
int code;
|
||||||
int len;
|
int len;
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
int m_uniqueInt;
|
int m_uniqueInt;
|
||||||
};
|
};
|
||||||
int dna_nr;
|
int dna_nr;
|
||||||
int nr;
|
int nr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
class bChunkPtr8
|
class bChunkPtr8
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bChunkPtr8(){}
|
bChunkPtr8() {}
|
||||||
int code, len;
|
int code, len;
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
long64 oldPrev;
|
long64 oldPrev;
|
||||||
int m_uniqueInts[2];
|
int m_uniqueInts[2];
|
||||||
};
|
};
|
||||||
int dna_nr, nr;
|
int dna_nr, nr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
class bChunkInd
|
class bChunkInd
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bChunkInd(){}
|
bChunkInd() {}
|
||||||
int code, len;
|
int code, len;
|
||||||
void *oldPtr;
|
void *oldPtr;
|
||||||
int dna_nr, nr;
|
int dna_nr, nr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
|
||||||
class ChunkUtils
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------- //
|
||||||
|
class ChunkUtils
|
||||||
|
{
|
||||||
|
public:
|
||||||
// file chunk offset
|
// file chunk offset
|
||||||
static int getOffset(int flags);
|
static int getOffset(int flags);
|
||||||
|
|
||||||
@@ -81,12 +75,10 @@ namespace bParse {
|
|||||||
static short swapShort(short sht);
|
static short swapShort(short sht);
|
||||||
static int swapInt(int inte);
|
static int swapInt(int inte);
|
||||||
static long64 swapLong64(long64 lng);
|
static long64 swapLong64(long64 lng);
|
||||||
|
};
|
||||||
|
|
||||||
};
|
const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd)));
|
||||||
|
const bool VOID_IS_8 = ((sizeof(void *) == 8));
|
||||||
|
} // namespace bParse
|
||||||
|
|
||||||
|
#endif //__BCHUNK_H__
|
||||||
const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd)));
|
|
||||||
const bool VOID_IS_8 = ((sizeof(void*)==8));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif//__BCHUNK_H__
|
|
||||||
|
|||||||
@@ -16,24 +16,25 @@ subject to the following restrictions:
|
|||||||
#ifndef __BCOMMON_H__
|
#ifndef __BCOMMON_H__
|
||||||
#define __BCOMMON_H__
|
#define __BCOMMON_H__
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
//#include "bLog.h"
|
//#include "bLog.h"
|
||||||
#include "LinearMath/btAlignedObjectArray.h"
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
#include "LinearMath/btHashMap.h"
|
#include "LinearMath/btHashMap.h"
|
||||||
|
|
||||||
namespace bParse {
|
namespace bParse
|
||||||
|
{
|
||||||
|
class bMain;
|
||||||
|
class bFileData;
|
||||||
|
class bFile;
|
||||||
|
class bDNA;
|
||||||
|
|
||||||
class bMain;
|
// delete void* undefined
|
||||||
class bFileData;
|
typedef struct bStructHandle
|
||||||
class bFile;
|
{
|
||||||
class bDNA;
|
int unused;
|
||||||
|
} bStructHandle;
|
||||||
|
typedef btAlignedObjectArray<bStructHandle*> bListBasePtr;
|
||||||
|
typedef btHashMap<btHashPtr, bStructHandle*> bPtrMap;
|
||||||
|
} // namespace bParse
|
||||||
|
|
||||||
// delete void* undefined
|
#endif //__BCOMMON_H__
|
||||||
typedef struct bStructHandle {int unused;}bStructHandle;
|
|
||||||
typedef btAlignedObjectArray<bStructHandle*> bListBasePtr;
|
|
||||||
typedef btHashMap<btHashPtr, bStructHandle*> bPtrMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif//__BCOMMON_H__
|
|
||||||
|
|||||||
@@ -23,10 +23,8 @@ subject to the following restrictions:
|
|||||||
//this define will force traversal of structures, to check backward (and forward) compatibility
|
//this define will force traversal of structures, to check backward (and forward) compatibility
|
||||||
//#define TEST_BACKWARD_FORWARD_COMPATIBILITY
|
//#define TEST_BACKWARD_FORWARD_COMPATIBILITY
|
||||||
|
|
||||||
|
|
||||||
using namespace bParse;
|
using namespace bParse;
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
bDNA::bDNA()
|
bDNA::bDNA()
|
||||||
: mPtrLen(0)
|
: mPtrLen(0)
|
||||||
@@ -43,7 +41,7 @@ bDNA::~bDNA()
|
|||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
bool bDNA::lessThan(bDNA *file)
|
bool bDNA::lessThan(bDNA *file)
|
||||||
{
|
{
|
||||||
return ( m_Names.size() < file->m_Names.size());
|
return (m_Names.size() < file->m_Names.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
@@ -53,15 +51,13 @@ char *bDNA::getName(int ind)
|
|||||||
return m_Names[ind].m_name;
|
return m_Names[ind].m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
char *bDNA::getType(int ind)
|
char *bDNA::getType(int ind)
|
||||||
{
|
{
|
||||||
assert(ind<= (int)mTypes.size());
|
assert(ind <= (int)mTypes.size());
|
||||||
return mTypes[ind];
|
return mTypes[ind];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
short *bDNA::getStruct(int ind)
|
short *bDNA::getStruct(int ind)
|
||||||
{
|
{
|
||||||
@@ -69,7 +65,6 @@ short *bDNA::getStruct(int ind)
|
|||||||
return mStructs[ind];
|
return mStructs[ind];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
short bDNA::getLength(int ind)
|
short bDNA::getLength(int ind)
|
||||||
{
|
{
|
||||||
@@ -77,12 +72,10 @@ short bDNA::getLength(int ind)
|
|||||||
return mTlens[ind];
|
return mTlens[ind];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
int bDNA::getReverseType(short type)
|
int bDNA::getReverseType(short type)
|
||||||
{
|
{
|
||||||
|
int *intPtr = mStructReverse.find(type);
|
||||||
int* intPtr = mStructReverse.find(type);
|
|
||||||
if (intPtr)
|
if (intPtr)
|
||||||
return *intPtr;
|
return *intPtr;
|
||||||
|
|
||||||
@@ -92,9 +85,8 @@ int bDNA::getReverseType(short type)
|
|||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
int bDNA::getReverseType(const char *type)
|
int bDNA::getReverseType(const char *type)
|
||||||
{
|
{
|
||||||
|
|
||||||
btHashString key(type);
|
btHashString key(type);
|
||||||
int* valuePtr = mTypeLookup.find(key);
|
int *valuePtr = mTypeLookup.find(key);
|
||||||
if (valuePtr)
|
if (valuePtr)
|
||||||
return *valuePtr;
|
return *valuePtr;
|
||||||
|
|
||||||
@@ -143,15 +135,15 @@ void bDNA::initRecurseCmpFlags(int iter)
|
|||||||
short *oldStrc = mStructs[iter];
|
short *oldStrc = mStructs[iter];
|
||||||
short type = oldStrc[0];
|
short type = oldStrc[0];
|
||||||
|
|
||||||
for (int i=0; i<(int)mStructs.size(); i++)
|
for (int i = 0; i < (int)mStructs.size(); i++)
|
||||||
{
|
{
|
||||||
if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU )
|
if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU)
|
||||||
{
|
{
|
||||||
short *curStruct = mStructs[i];
|
short *curStruct = mStructs[i];
|
||||||
int eleLen = curStruct[1];
|
int eleLen = curStruct[1];
|
||||||
curStruct+=2;
|
curStruct += 2;
|
||||||
|
|
||||||
for (int j=0; j<eleLen; j++, curStruct+=2)
|
for (int j = 0; j < eleLen; j++, curStruct += 2)
|
||||||
{
|
{
|
||||||
if (curStruct[0] == type)
|
if (curStruct[0] == type)
|
||||||
{
|
{
|
||||||
@@ -171,19 +163,15 @@ void bDNA::initRecurseCmpFlags(int iter)
|
|||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
void bDNA::initCmpFlags(bDNA *memDNA)
|
void bDNA::initCmpFlags(bDNA *memDNA)
|
||||||
{
|
{
|
||||||
|
|
||||||
// compare the file to memory
|
// compare the file to memory
|
||||||
// this ptr should be the file data
|
// this ptr should be the file data
|
||||||
|
|
||||||
|
assert(!(m_Names.size() == 0)); //DNA empty!
|
||||||
assert(!(m_Names.size() == 0));//DNA empty!
|
|
||||||
|
|
||||||
mCMPFlags.resize(mStructs.size(), FDF_NONE);
|
mCMPFlags.resize(mStructs.size(), FDF_NONE);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for ( i=0; i<(int)mStructs.size(); i++)
|
for (i = 0; i < (int)mStructs.size(); i++)
|
||||||
{
|
{
|
||||||
short *oldStruct = mStructs[i];
|
short *oldStruct = mStructs[i];
|
||||||
|
|
||||||
@@ -197,7 +185,7 @@ void bDNA::initCmpFlags(bDNA *memDNA)
|
|||||||
|
|
||||||
//#define SLOW_FORWARD_COMPATIBLE 1
|
//#define SLOW_FORWARD_COMPATIBLE 1
|
||||||
#ifdef SLOW_FORWARD_COMPATIBLE
|
#ifdef SLOW_FORWARD_COMPATIBLE
|
||||||
char* typeName = mTypes[oldLookup];
|
char *typeName = mTypes[oldLookup];
|
||||||
int newLookup = memDNA->getReverseType(typeName);
|
int newLookup = memDNA->getReverseType(typeName);
|
||||||
if (newLookup == -1)
|
if (newLookup == -1)
|
||||||
{
|
{
|
||||||
@@ -213,8 +201,6 @@ void bDNA::initCmpFlags(bDNA *memDNA)
|
|||||||
short *curStruct = memDNA->mStructs[oldLookup];
|
short *curStruct = memDNA->mStructs[oldLookup];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// rebuild...
|
// rebuild...
|
||||||
mCMPFlags[i] = FDF_STRUCT_NEQU;
|
mCMPFlags[i] = FDF_STRUCT_NEQU;
|
||||||
|
|
||||||
@@ -228,26 +214,24 @@ void bDNA::initCmpFlags(bDNA *memDNA)
|
|||||||
bool isSame = true;
|
bool isSame = true;
|
||||||
int elementLength = oldStruct[1];
|
int elementLength = oldStruct[1];
|
||||||
|
|
||||||
|
curStruct += 2;
|
||||||
|
oldStruct += 2;
|
||||||
|
|
||||||
curStruct+=2;
|
for (int j = 0; j < elementLength; j++, curStruct += 2, oldStruct += 2)
|
||||||
oldStruct+=2;
|
|
||||||
|
|
||||||
|
|
||||||
for (int j=0; j<elementLength; j++, curStruct+=2, oldStruct+=2)
|
|
||||||
{
|
{
|
||||||
// type the same
|
// type the same
|
||||||
//const char* typeFileDNA = mTypes[oldStruct[0]];
|
//const char* typeFileDNA = mTypes[oldStruct[0]];
|
||||||
//const char* typeMemDNA = mTypes[curStruct[0]];
|
//const char* typeMemDNA = mTypes[curStruct[0]];
|
||||||
if (strcmp(mTypes[oldStruct[0]], memDNA->mTypes[curStruct[0]])!=0)
|
if (strcmp(mTypes[oldStruct[0]], memDNA->mTypes[curStruct[0]]) != 0)
|
||||||
{
|
{
|
||||||
isSame=false;
|
isSame = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// name the same
|
// name the same
|
||||||
if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name)!=0)
|
if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name) != 0)
|
||||||
{
|
{
|
||||||
isSame=false;
|
isSame = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,24 +242,18 @@ void bDNA::initCmpFlags(bDNA *memDNA)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// recurse in
|
|
||||||
for ( i=0; i<(int)mStructs.size(); i++)
|
|
||||||
{
|
|
||||||
if (mCMPFlags[i] == FDF_STRUCT_NEQU)
|
|
||||||
initRecurseCmpFlags(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// recurse in
|
||||||
|
for (i = 0; i < (int)mStructs.size(); i++)
|
||||||
|
{
|
||||||
|
if (mCMPFlags[i] == FDF_STRUCT_NEQU)
|
||||||
|
initRecurseCmpFlags(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int name_is_array(char *name, int *dim1, int *dim2)
|
||||||
|
{
|
||||||
static int name_is_array(char* name, int* dim1, int* dim2) {
|
|
||||||
int len = strlen(name);
|
int len = strlen(name);
|
||||||
/*fprintf(stderr,"[%s]",name);*/
|
/*fprintf(stderr,"[%s]",name);*/
|
||||||
/*if (len >= 1) {
|
/*if (len >= 1) {
|
||||||
@@ -285,58 +263,77 @@ static int name_is_array(char* name, int* dim1, int* dim2) {
|
|||||||
return 0;*/
|
return 0;*/
|
||||||
char *bp;
|
char *bp;
|
||||||
int num;
|
int num;
|
||||||
if (dim1) {
|
if (dim1)
|
||||||
|
{
|
||||||
*dim1 = 1;
|
*dim1 = 1;
|
||||||
}
|
}
|
||||||
if (dim2) {
|
if (dim2)
|
||||||
|
{
|
||||||
*dim2 = 1;
|
*dim2 = 1;
|
||||||
}
|
}
|
||||||
bp = strchr(name, '[');
|
bp = strchr(name, '[');
|
||||||
if (!bp) {
|
if (!bp)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
num = 0;
|
num = 0;
|
||||||
while (++bp < name+len-1) {
|
while (++bp < name + len - 1)
|
||||||
|
{
|
||||||
const char c = *bp;
|
const char c = *bp;
|
||||||
if (c == ']') {
|
if (c == ']')
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c <= '9' && c >= '0') {
|
if (c <= '9' && c >= '0')
|
||||||
|
{
|
||||||
num *= 10;
|
num *= 10;
|
||||||
num += (c - '0');
|
num += (c - '0');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("array parse error.\n");
|
printf("array parse error.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dim2) {
|
if (dim2)
|
||||||
|
{
|
||||||
*dim2 = num;
|
*dim2 = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find second dim, if any. */
|
/* find second dim, if any. */
|
||||||
bp = strchr(bp, '[');
|
bp = strchr(bp, '[');
|
||||||
if (!bp) {
|
if (!bp)
|
||||||
|
{
|
||||||
return 1; /* at least we got the first dim. */
|
return 1; /* at least we got the first dim. */
|
||||||
}
|
}
|
||||||
num = 0;
|
num = 0;
|
||||||
while (++bp < name+len-1) {
|
while (++bp < name + len - 1)
|
||||||
|
{
|
||||||
const char c = *bp;
|
const char c = *bp;
|
||||||
if (c == ']') {
|
if (c == ']')
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c <= '9' && c >= '0') {
|
if (c <= '9' && c >= '0')
|
||||||
|
{
|
||||||
num *= 10;
|
num *= 10;
|
||||||
num += (c - '0');
|
num += (c - '0');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("array2 parse error.\n");
|
printf("array2 parse error.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dim1) {
|
if (dim1)
|
||||||
if (dim2) {
|
{
|
||||||
|
if (dim2)
|
||||||
|
{
|
||||||
*dim1 = *dim2;
|
*dim1 = *dim2;
|
||||||
*dim2 = num;
|
*dim2 = num;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*dim1 = num;
|
*dim1 = num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,14 +341,15 @@ static int name_is_array(char* name, int* dim1, int* dim2) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
void bDNA::init(char *data, int len, bool swap)
|
void bDNA::init(char *data, int len, bool swap)
|
||||||
{
|
{
|
||||||
int *intPtr=0;short *shtPtr=0;
|
int *intPtr = 0;
|
||||||
char *cp = 0;int dataLen =0;
|
short *shtPtr = 0;
|
||||||
|
char *cp = 0;
|
||||||
|
int dataLen = 0;
|
||||||
//long nr=0;
|
//long nr=0;
|
||||||
intPtr = (int*)data;
|
intPtr = (int *)data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SDNA (4 bytes) (magic number)
|
SDNA (4 bytes) (magic number)
|
||||||
@@ -361,14 +359,13 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
<string>
|
<string>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (strncmp(data, "SDNA", 4)==0)
|
if (strncmp(data, "SDNA", 4) == 0)
|
||||||
{
|
{
|
||||||
// skip ++ NAME
|
// skip ++ NAME
|
||||||
intPtr++; intPtr++;
|
intPtr++;
|
||||||
|
intPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Parse names
|
// Parse names
|
||||||
if (swap)
|
if (swap)
|
||||||
{
|
{
|
||||||
@@ -377,22 +374,20 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
dataLen = *intPtr;
|
dataLen = *intPtr;
|
||||||
intPtr++;
|
intPtr++;
|
||||||
|
|
||||||
cp = (char*)intPtr;
|
cp = (char *)intPtr;
|
||||||
int i;
|
int i;
|
||||||
for ( i=0; i<dataLen; i++)
|
for (i = 0; i < dataLen; i++)
|
||||||
{
|
{
|
||||||
bNameInfo info;
|
bNameInfo info;
|
||||||
info.m_name = cp;
|
info.m_name = cp;
|
||||||
info.m_isPointer = (info.m_name[0] == '*') || (info.m_name[1] == '*');
|
info.m_isPointer = (info.m_name[0] == '*') || (info.m_name[1] == '*');
|
||||||
name_is_array(info.m_name,&info.m_dim0,&info.m_dim1);
|
name_is_array(info.m_name, &info.m_dim0, &info.m_dim1);
|
||||||
m_Names.push_back(info);
|
m_Names.push_back(info);
|
||||||
while (*cp)cp++;
|
while (*cp) cp++;
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cp = btAlignPointer(cp, 4);
|
||||||
|
|
||||||
cp = btAlignPointer(cp,4);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TYPE (4 bytes)
|
TYPE (4 bytes)
|
||||||
@@ -401,8 +396,9 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
<string>
|
<string>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
intPtr = (int*)cp;
|
intPtr = (int *)cp;
|
||||||
assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
|
assert(strncmp(cp, "TYPE", 4) == 0);
|
||||||
|
intPtr++;
|
||||||
|
|
||||||
if (swap)
|
if (swap)
|
||||||
{
|
{
|
||||||
@@ -411,15 +407,15 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
dataLen = *intPtr;
|
dataLen = *intPtr;
|
||||||
intPtr++;
|
intPtr++;
|
||||||
|
|
||||||
cp = (char*)intPtr;
|
cp = (char *)intPtr;
|
||||||
for ( i=0; i<dataLen; i++)
|
for (i = 0; i < dataLen; i++)
|
||||||
{
|
{
|
||||||
mTypes.push_back(cp);
|
mTypes.push_back(cp);
|
||||||
while (*cp)cp++;
|
while (*cp) cp++;
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = btAlignPointer(cp,4);
|
cp = btAlignPointer(cp, 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TLEN (4 bytes)
|
TLEN (4 bytes)
|
||||||
@@ -428,13 +424,14 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Parse type lens
|
// Parse type lens
|
||||||
intPtr = (int*)cp;
|
intPtr = (int *)cp;
|
||||||
assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
|
assert(strncmp(cp, "TLEN", 4) == 0);
|
||||||
|
intPtr++;
|
||||||
|
|
||||||
dataLen = (int)mTypes.size();
|
dataLen = (int)mTypes.size();
|
||||||
|
|
||||||
shtPtr = (short*)intPtr;
|
shtPtr = (short *)intPtr;
|
||||||
for ( i=0; i<dataLen; i++, shtPtr++)
|
for (i = 0; i < dataLen; i++, shtPtr++)
|
||||||
{
|
{
|
||||||
if (swap)
|
if (swap)
|
||||||
shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
|
shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
|
||||||
@@ -454,9 +451,10 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
<namenr>
|
<namenr>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
intPtr = (int*)shtPtr;
|
intPtr = (int *)shtPtr;
|
||||||
cp = (char*)intPtr;
|
cp = (char *)intPtr;
|
||||||
assert(strncmp(cp, "STRC", 4)==0); intPtr++;
|
assert(strncmp(cp, "STRC", 4) == 0);
|
||||||
|
intPtr++;
|
||||||
|
|
||||||
if (swap)
|
if (swap)
|
||||||
{
|
{
|
||||||
@@ -465,83 +463,77 @@ void bDNA::init(char *data, int len, bool swap)
|
|||||||
dataLen = *intPtr;
|
dataLen = *intPtr;
|
||||||
intPtr++;
|
intPtr++;
|
||||||
|
|
||||||
|
shtPtr = (short *)intPtr;
|
||||||
shtPtr = (short*)intPtr;
|
for (i = 0; i < dataLen; i++)
|
||||||
for ( i=0; i<dataLen; i++)
|
|
||||||
{
|
{
|
||||||
mStructs.push_back (shtPtr);
|
mStructs.push_back(shtPtr);
|
||||||
if (swap)
|
if (swap)
|
||||||
{
|
{
|
||||||
shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
|
shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
|
||||||
shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
|
shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]);
|
||||||
|
|
||||||
int len = shtPtr[1];
|
int len = shtPtr[1];
|
||||||
shtPtr+= 2;
|
shtPtr += 2;
|
||||||
|
|
||||||
for (int a=0; a<len; a++, shtPtr+=2)
|
for (int a = 0; a < len; a++, shtPtr += 2)
|
||||||
{
|
{
|
||||||
shtPtr[0]= ChunkUtils::swapShort(shtPtr[0]);
|
shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]);
|
||||||
shtPtr[1]= ChunkUtils::swapShort(shtPtr[1]);
|
shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
shtPtr+= (2*shtPtr[1])+2;
|
shtPtr += (2 * shtPtr[1]) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// build reverse lookups
|
// build reverse lookups
|
||||||
for ( i=0; i<(int)mStructs.size(); i++)
|
for (i = 0; i < (int)mStructs.size(); i++)
|
||||||
{
|
{
|
||||||
short *strc = mStructs.at(i);
|
short *strc = mStructs.at(i);
|
||||||
if (!mPtrLen && strcmp(mTypes[strc[0]],"ListBase")==0)
|
if (!mPtrLen && strcmp(mTypes[strc[0]], "ListBase") == 0)
|
||||||
{
|
{
|
||||||
mPtrLen = mTlens[strc[0]]/2;
|
mPtrLen = mTlens[strc[0]] / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
mStructReverse.insert(strc[0], i);
|
mStructReverse.insert(strc[0], i);
|
||||||
mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
|
mTypeLookup.insert(btHashString(mTypes[strc[0]]), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
int bDNA::getArraySize(char* string)
|
int bDNA::getArraySize(char *string)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
int len = strlen(string);
|
int len = strlen(string);
|
||||||
|
|
||||||
|
char *next = 0;
|
||||||
char* next = 0;
|
for (int i = 0; i < len; i++)
|
||||||
for (int i=0; i<len; i++)
|
|
||||||
{
|
{
|
||||||
char c = string[i];
|
char c = string[i];
|
||||||
|
|
||||||
if (c == '[')
|
if (c == '[')
|
||||||
next = &string[i+1];
|
next = &string[i + 1];
|
||||||
else if (c==']')
|
else if (c == ']')
|
||||||
if (next)
|
if (next)
|
||||||
ret *= atoi(next);
|
ret *= atoi(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// print (string << ' ' << ret);
|
// print (string << ' ' << ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bDNA::dumpTypeDefinitions()
|
void bDNA::dumpTypeDefinitions()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
int numTypes = mTypes.size();
|
int numTypes = mTypes.size();
|
||||||
|
|
||||||
for (i=0;i<numTypes;i++)
|
for (i = 0; i < numTypes; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( i=0; i<(int)mStructs.size(); i++)
|
for (i = 0; i < (int)mStructs.size(); i++)
|
||||||
{
|
{
|
||||||
int totalBytes=0;
|
int totalBytes = 0;
|
||||||
short *oldStruct = mStructs[i];
|
short *oldStruct = mStructs[i];
|
||||||
|
|
||||||
int oldLookup = getReverseType(oldStruct[0]);
|
int oldLookup = getReverseType(oldStruct[0]);
|
||||||
@@ -551,45 +543,47 @@ void bDNA::dumpTypeDefinitions()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
short* newStruct = mStructs[oldLookup];
|
short *newStruct = mStructs[oldLookup];
|
||||||
char* typeName = mTypes[newStruct[0]];
|
char *typeName = mTypes[newStruct[0]];
|
||||||
printf("%3d: %s ",i,typeName);
|
printf("%3d: %s ", i, typeName);
|
||||||
|
|
||||||
//char *name = mNames[oldStruct[1]];
|
//char *name = mNames[oldStruct[1]];
|
||||||
int len = oldStruct[1];
|
int len = oldStruct[1];
|
||||||
printf(" (%d fields) ",len);
|
printf(" (%d fields) ", len);
|
||||||
oldStruct+=2;
|
oldStruct += 2;
|
||||||
|
|
||||||
printf("{");
|
printf("{");
|
||||||
int j;
|
int j;
|
||||||
for (j=0; j<len; ++j,oldStruct+=2) {
|
for (j = 0; j < len; ++j, oldStruct += 2)
|
||||||
const char* name = m_Names[oldStruct[1]].m_name;
|
{
|
||||||
printf("%s %s", mTypes[oldStruct[0]],name);
|
const char *name = m_Names[oldStruct[1]].m_name;
|
||||||
int elemNumBytes= 0;
|
printf("%s %s", mTypes[oldStruct[0]], name);
|
||||||
|
int elemNumBytes = 0;
|
||||||
int arrayDimensions = getArraySizeNew(oldStruct[1]);
|
int arrayDimensions = getArraySizeNew(oldStruct[1]);
|
||||||
|
|
||||||
if (m_Names[oldStruct[1]].m_isPointer)
|
if (m_Names[oldStruct[1]].m_isPointer)
|
||||||
{
|
{
|
||||||
elemNumBytes = VOID_IS_8 ? 8 : 4;
|
elemNumBytes = VOID_IS_8 ? 8 : 4;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
elemNumBytes = getLength(oldStruct[0]);
|
elemNumBytes = getLength(oldStruct[0]);
|
||||||
}
|
}
|
||||||
printf(" /* %d bytes */",elemNumBytes*arrayDimensions);
|
printf(" /* %d bytes */", elemNumBytes * arrayDimensions);
|
||||||
|
|
||||||
if (j == len-1) {
|
if (j == len - 1)
|
||||||
|
{
|
||||||
printf(";}");
|
printf(";}");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("; ");
|
printf("; ");
|
||||||
}
|
}
|
||||||
totalBytes+=elemNumBytes*arrayDimensions;
|
totalBytes += elemNumBytes * arrayDimensions;
|
||||||
}
|
}
|
||||||
printf("\ntotalBytes=%d\n\n",totalBytes);
|
printf("\ntotalBytes=%d\n\n", totalBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* dump out display of types and their sizes */
|
/* dump out display of types and their sizes */
|
||||||
for (i=0; i<bf->types_count; ++i) {
|
for (i=0; i<bf->types_count; ++i) {
|
||||||
@@ -618,12 +612,6 @@ void bDNA::dumpTypeDefinitions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//eof
|
//eof
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,37 +16,36 @@ subject to the following restrictions:
|
|||||||
#ifndef __BDNA_H__
|
#ifndef __BDNA_H__
|
||||||
#define __BDNA_H__
|
#define __BDNA_H__
|
||||||
|
|
||||||
|
|
||||||
#include "bCommon.h"
|
#include "bCommon.h"
|
||||||
|
|
||||||
namespace bParse {
|
namespace bParse
|
||||||
|
{
|
||||||
struct bNameInfo
|
struct bNameInfo
|
||||||
{
|
{
|
||||||
char* m_name;
|
char *m_name;
|
||||||
bool m_isPointer;
|
bool m_isPointer;
|
||||||
int m_dim0;
|
int m_dim0;
|
||||||
int m_dim1;
|
int m_dim1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class bDNA
|
class bDNA
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bDNA();
|
bDNA();
|
||||||
~bDNA();
|
~bDNA();
|
||||||
|
|
||||||
void init(char *data, int len, bool swap=false);
|
void init(char *data, int len, bool swap = false);
|
||||||
|
|
||||||
int getArraySize(char* str);
|
int getArraySize(char *str);
|
||||||
int getArraySizeNew(short name)
|
int getArraySizeNew(short name)
|
||||||
{
|
{
|
||||||
const bNameInfo& nameInfo = m_Names[name];
|
const bNameInfo &nameInfo = m_Names[name];
|
||||||
return nameInfo.m_dim0*nameInfo.m_dim1;
|
return nameInfo.m_dim0 * nameInfo.m_dim1;
|
||||||
}
|
}
|
||||||
int getElementSize(short type, short name)
|
int getElementSize(short type, short name)
|
||||||
{
|
{
|
||||||
const bNameInfo& nameInfo = m_Names[name];
|
const bNameInfo &nameInfo = m_Names[name];
|
||||||
int size = nameInfo.m_isPointer ? mPtrLen*nameInfo.m_dim0*nameInfo.m_dim1 : mTlens[type]*nameInfo.m_dim0*nameInfo.m_dim1;
|
int size = nameInfo.m_isPointer ? mPtrLen * nameInfo.m_dim0 * nameInfo.m_dim1 : mTlens[type] * nameInfo.m_dim0 * nameInfo.m_dim1;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,27 +61,24 @@ namespace bParse {
|
|||||||
int getReverseType(short type);
|
int getReverseType(short type);
|
||||||
int getReverseType(const char *type);
|
int getReverseType(const char *type);
|
||||||
|
|
||||||
|
|
||||||
int getNumStructs();
|
int getNumStructs();
|
||||||
|
|
||||||
//
|
//
|
||||||
bool lessThan(bDNA* other);
|
bool lessThan(bDNA *other);
|
||||||
|
|
||||||
void initCmpFlags(bDNA *memDNA);
|
void initCmpFlags(bDNA *memDNA);
|
||||||
bool flagNotEqual(int dna_nr);
|
bool flagNotEqual(int dna_nr);
|
||||||
bool flagEqual(int dna_nr);
|
bool flagEqual(int dna_nr);
|
||||||
bool flagNone(int dna_nr);
|
bool flagNone(int dna_nr);
|
||||||
|
|
||||||
|
|
||||||
int getPointerSize();
|
int getPointerSize();
|
||||||
|
|
||||||
void dumpTypeDefinitions();
|
void dumpTypeDefinitions();
|
||||||
|
|
||||||
|
private:
|
||||||
private:
|
|
||||||
enum FileDNAFlags
|
enum FileDNAFlags
|
||||||
{
|
{
|
||||||
FDF_NONE=0,
|
FDF_NONE = 0,
|
||||||
FDF_STRUCT_NEQU,
|
FDF_STRUCT_NEQU,
|
||||||
FDF_STRUCT_EQU
|
FDF_STRUCT_EQU
|
||||||
};
|
};
|
||||||
@@ -92,19 +88,14 @@ namespace bParse {
|
|||||||
btAlignedObjectArray<int> mCMPFlags;
|
btAlignedObjectArray<int> mCMPFlags;
|
||||||
|
|
||||||
btAlignedObjectArray<bNameInfo> m_Names;
|
btAlignedObjectArray<bNameInfo> m_Names;
|
||||||
btAlignedObjectArray<char*> mTypes;
|
btAlignedObjectArray<char *> mTypes;
|
||||||
btAlignedObjectArray<short*> mStructs;
|
btAlignedObjectArray<short *> mStructs;
|
||||||
btAlignedObjectArray<short> mTlens;
|
btAlignedObjectArray<short> mTlens;
|
||||||
btHashMap<btHashInt, int> mStructReverse;
|
btHashMap<btHashInt, int> mStructReverse;
|
||||||
btHashMap<btHashString,int> mTypeLookup;
|
btHashMap<btHashString, int> mTypeLookup;
|
||||||
|
|
||||||
int mPtrLen;
|
int mPtrLen;
|
||||||
|
};
|
||||||
|
} // namespace bParse
|
||||||
|
|
||||||
|
#endif //__BDNA_H__
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif//__BDNA_H__
|
|
||||||
|
|||||||
@@ -19,28 +19,25 @@
|
|||||||
#ifndef __B_DEFINES_H__
|
#ifndef __B_DEFINES_H__
|
||||||
#define __B_DEFINES_H__
|
#define __B_DEFINES_H__
|
||||||
|
|
||||||
|
|
||||||
// MISC defines, see BKE_global.h, BKE_utildefines.h
|
// MISC defines, see BKE_global.h, BKE_utildefines.h
|
||||||
#define SIZEOFBLENDERHEADER 12
|
#define SIZEOFBLENDERHEADER 12
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
|
#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__)
|
||||||
# define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
|
#define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
|
||||||
#else
|
#else
|
||||||
# define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
|
#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
|
#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__)
|
||||||
# define MAKE_ID2(c, d) ( (c)<<8 | (d) )
|
#define MAKE_ID2(c, d) ((c) << 8 | (d))
|
||||||
# define MOST_SIG_BYTE 0
|
#define MOST_SIG_BYTE 0
|
||||||
# define BBIG_ENDIAN
|
#define BBIG_ENDIAN
|
||||||
#else
|
#else
|
||||||
# define MAKE_ID2(c, d) ( (d)<<8 | (c) )
|
#define MAKE_ID2(c, d) ((d) << 8 | (c))
|
||||||
# define MOST_SIG_BYTE 1
|
#define MOST_SIG_BYTE 1
|
||||||
# define BLITTLE_ENDIAN
|
#define BLITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
@@ -77,7 +74,6 @@
|
|||||||
#define ID_NT MAKE_ID2('N', 'T')
|
#define ID_NT MAKE_ID2('N', 'T')
|
||||||
#define ID_BR MAKE_ID2('B', 'R')
|
#define ID_BR MAKE_ID2('B', 'R')
|
||||||
|
|
||||||
|
|
||||||
#define ID_SEQ MAKE_ID2('S', 'Q')
|
#define ID_SEQ MAKE_ID2('S', 'Q')
|
||||||
#define ID_CO MAKE_ID2('C', 'O')
|
#define ID_CO MAKE_ID2('C', 'O')
|
||||||
#define ID_PO MAKE_ID2('A', 'C')
|
#define ID_PO MAKE_ID2('A', 'C')
|
||||||
@@ -86,54 +82,71 @@
|
|||||||
#define ID_VS MAKE_ID2('V', 'S')
|
#define ID_VS MAKE_ID2('V', 'S')
|
||||||
#define ID_VN MAKE_ID2('V', 'N')
|
#define ID_VN MAKE_ID2('V', 'N')
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
#define FORM MAKE_ID('F', 'O', 'R', 'M')
|
||||||
|
#define DDG1 MAKE_ID('3', 'D', 'G', '1')
|
||||||
|
#define DDG2 MAKE_ID('3', 'D', 'G', '2')
|
||||||
|
#define DDG3 MAKE_ID('3', 'D', 'G', '3')
|
||||||
|
#define DDG4 MAKE_ID('3', 'D', 'G', '4')
|
||||||
|
#define GOUR MAKE_ID('G', 'O', 'U', 'R')
|
||||||
|
#define BLEN MAKE_ID('B', 'L', 'E', 'N')
|
||||||
|
#define DER_ MAKE_ID('D', 'E', 'R', '_')
|
||||||
|
#define V100 MAKE_ID('V', '1', '0', '0')
|
||||||
|
#define DATA MAKE_ID('D', 'A', 'T', 'A')
|
||||||
|
#define GLOB MAKE_ID('G', 'L', 'O', 'B')
|
||||||
|
#define IMAG MAKE_ID('I', 'M', 'A', 'G')
|
||||||
|
#define USER MAKE_ID('U', 'S', 'E', 'R')
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
#define FORM MAKE_ID('F','O','R','M')
|
#define DNA1 MAKE_ID('D', 'N', 'A', '1')
|
||||||
#define DDG1 MAKE_ID('3','D','G','1')
|
#define REND MAKE_ID('R', 'E', 'N', 'D')
|
||||||
#define DDG2 MAKE_ID('3','D','G','2')
|
#define ENDB MAKE_ID('E', 'N', 'D', 'B')
|
||||||
#define DDG3 MAKE_ID('3','D','G','3')
|
#define NAME MAKE_ID('N', 'A', 'M', 'E')
|
||||||
#define DDG4 MAKE_ID('3','D','G','4')
|
#define SDNA MAKE_ID('S', 'D', 'N', 'A')
|
||||||
#define GOUR MAKE_ID('G','O','U','R')
|
#define TYPE MAKE_ID('T', 'Y', 'P', 'E')
|
||||||
#define BLEN MAKE_ID('B','L','E','N')
|
#define TLEN MAKE_ID('T', 'L', 'E', 'N')
|
||||||
#define DER_ MAKE_ID('D','E','R','_')
|
#define STRC MAKE_ID('S', 'T', 'R', 'C')
|
||||||
#define V100 MAKE_ID('V','1','0','0')
|
|
||||||
#define DATA MAKE_ID('D','A','T','A')
|
|
||||||
#define GLOB MAKE_ID('G','L','O','B')
|
|
||||||
#define IMAG MAKE_ID('I','M','A','G')
|
|
||||||
#define USER MAKE_ID('U','S','E','R')
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
#define DNA1 MAKE_ID('D','N','A','1')
|
#define SWITCH_INT(a) \
|
||||||
#define REND MAKE_ID('R','E','N','D')
|
{ \
|
||||||
#define ENDB MAKE_ID('E','N','D','B')
|
|
||||||
#define NAME MAKE_ID('N','A','M','E')
|
|
||||||
#define SDNA MAKE_ID('S','D','N','A')
|
|
||||||
#define TYPE MAKE_ID('T','Y','P','E')
|
|
||||||
#define TLEN MAKE_ID('T','L','E','N')
|
|
||||||
#define STRC MAKE_ID('S','T','R','C')
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
#define SWITCH_INT(a) { \
|
|
||||||
char s_i, *p_i; \
|
char s_i, *p_i; \
|
||||||
p_i= (char *)&(a); \
|
p_i = (char *)&(a); \
|
||||||
s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \
|
s_i = p_i[0]; \
|
||||||
s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; }
|
p_i[0] = p_i[3]; \
|
||||||
|
p_i[3] = s_i; \
|
||||||
|
s_i = p_i[1]; \
|
||||||
|
p_i[1] = p_i[2]; \
|
||||||
|
p_i[2] = s_i; \
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
#define SWITCH_SHORT(a) { \
|
#define SWITCH_SHORT(a) \
|
||||||
|
{ \
|
||||||
char s_i, *p_i; \
|
char s_i, *p_i; \
|
||||||
p_i= (char *)&(a); \
|
p_i = (char *)&(a); \
|
||||||
s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; }
|
s_i = p_i[0]; \
|
||||||
|
p_i[0] = p_i[1]; \
|
||||||
|
p_i[1] = s_i; \
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
#define SWITCH_LONGINT(a) { \
|
#define SWITCH_LONGINT(a) \
|
||||||
|
{ \
|
||||||
char s_i, *p_i; \
|
char s_i, *p_i; \
|
||||||
p_i= (char *)&(a); \
|
p_i = (char *)&(a); \
|
||||||
s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
|
s_i = p_i[0]; \
|
||||||
s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
|
p_i[0] = p_i[7]; \
|
||||||
s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
|
p_i[7] = s_i; \
|
||||||
s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; }
|
s_i = p_i[1]; \
|
||||||
|
p_i[1] = p_i[6]; \
|
||||||
|
p_i[6] = s_i; \
|
||||||
|
s_i = p_i[2]; \
|
||||||
|
p_i[2] = p_i[5]; \
|
||||||
|
p_i[5] = s_i; \
|
||||||
|
s_i = p_i[3]; \
|
||||||
|
p_i[3] = p_i[4]; \
|
||||||
|
p_i[4] = s_i; \
|
||||||
|
}
|
||||||
|
|
||||||
#endif//__B_DEFINES_H__
|
#endif //__B_DEFINES_H__
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -20,35 +20,34 @@ subject to the following restrictions:
|
|||||||
#include "bChunk.h"
|
#include "bChunk.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace bParse {
|
namespace bParse
|
||||||
|
{
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
enum bFileFlags
|
enum bFileFlags
|
||||||
{
|
{
|
||||||
FD_INVALID =0,
|
FD_INVALID = 0,
|
||||||
FD_OK =1,
|
FD_OK = 1,
|
||||||
FD_VOID_IS_8 =2,
|
FD_VOID_IS_8 = 2,
|
||||||
FD_ENDIAN_SWAP =4,
|
FD_ENDIAN_SWAP = 4,
|
||||||
FD_FILE_64 =8,
|
FD_FILE_64 = 8,
|
||||||
FD_BITS_VARIES =16,
|
FD_BITS_VARIES = 16,
|
||||||
FD_VERSION_VARIES = 32,
|
FD_VERSION_VARIES = 32,
|
||||||
FD_DOUBLE_PRECISION =64,
|
FD_DOUBLE_PRECISION = 64,
|
||||||
FD_BROKEN_DNA = 128,
|
FD_BROKEN_DNA = 128,
|
||||||
FD_FILEDNA_IS_MEMDNA = 256
|
FD_FILEDNA_IS_MEMDNA = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
enum bFileVerboseMode
|
enum bFileVerboseMode
|
||||||
{
|
{
|
||||||
FD_VERBOSE_EXPORT_XML = 1,
|
FD_VERBOSE_EXPORT_XML = 1,
|
||||||
FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2,
|
FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2,
|
||||||
FD_VERBOSE_DUMP_CHUNKS = 4,
|
FD_VERBOSE_DUMP_CHUNKS = 4,
|
||||||
FD_VERBOSE_DUMP_FILE_INFO=8,
|
FD_VERBOSE_DUMP_FILE_INFO = 8,
|
||||||
};
|
};
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
class bFile
|
class bFile
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
char m_headerString[7];
|
char m_headerString[7];
|
||||||
|
|
||||||
bool mOwnsBuffer;
|
bool mOwnsBuffer;
|
||||||
@@ -56,7 +55,6 @@ namespace bParse {
|
|||||||
int mFileLen;
|
int mFileLen;
|
||||||
int mVersion;
|
int mVersion;
|
||||||
|
|
||||||
|
|
||||||
bPtrMap mLibPointers;
|
bPtrMap mLibPointers;
|
||||||
|
|
||||||
int mDataStart;
|
int mDataStart;
|
||||||
@@ -73,14 +71,13 @@ namespace bParse {
|
|||||||
|
|
||||||
bPtrMap mDataPointers;
|
bPtrMap mDataPointers;
|
||||||
|
|
||||||
|
|
||||||
int mFlags;
|
int mFlags;
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////////////////
|
// ////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// buffer offset util
|
// buffer offset util
|
||||||
int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags);
|
int getNextBlock(bChunkInd* dataChunk, const char* dataPtr, const int flags);
|
||||||
void safeSwapPtr(char *dst, const char *src);
|
void safeSwapPtr(char* dst, const char* src);
|
||||||
|
|
||||||
virtual void parseHeader();
|
virtual void parseHeader();
|
||||||
|
|
||||||
@@ -89,32 +86,30 @@ namespace bParse {
|
|||||||
void resolvePointersMismatch();
|
void resolvePointersMismatch();
|
||||||
void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode);
|
void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode);
|
||||||
|
|
||||||
int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion);
|
int resolvePointersStructRecursive(char* strcPtr, int old_dna, int verboseMode, int recursion);
|
||||||
//void swapPtr(char *dst, char *src);
|
//void swapPtr(char *dst, char *src);
|
||||||
|
|
||||||
void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers);
|
void parseStruct(char* strcPtr, char* dtPtr, int old_dna, int new_dna, bool fixupPointers);
|
||||||
void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers);
|
void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char* strcData, char* data, bool fixupPointers);
|
||||||
char* getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos);
|
char* getFileElement(short* firstStruct, char* lookupName, char* lookupType, char* data, short** foundPos);
|
||||||
|
|
||||||
|
void swap(char* head, class bChunkInd& ch, bool ignoreEndianFlag);
|
||||||
void swap(char *head, class bChunkInd& ch, bool ignoreEndianFlag);
|
void swapData(char* data, short type, int arraySize, bool ignoreEndianFlag);
|
||||||
void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag);
|
void swapStruct(int dna_nr, char* data, bool ignoreEndianFlag);
|
||||||
void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag);
|
void swapLen(char* dataPtr);
|
||||||
void swapLen(char *dataPtr);
|
|
||||||
void swapDNA(char* ptr);
|
void swapDNA(char* ptr);
|
||||||
|
|
||||||
|
char* readStruct(char* head, class bChunkInd& chunk);
|
||||||
|
char* getAsString(int code);
|
||||||
|
|
||||||
char* readStruct(char *head, class bChunkInd& chunk);
|
virtual void parseInternal(int verboseMode, char* memDna, int memDnaLength);
|
||||||
char *getAsString(int code);
|
|
||||||
|
|
||||||
virtual void parseInternal(int verboseMode, char* memDna,int memDnaLength);
|
public:
|
||||||
|
bFile(const char* filename, const char headerString[7]);
|
||||||
public:
|
|
||||||
bFile(const char *filename, const char headerString[7]);
|
|
||||||
|
|
||||||
//todo: make memoryBuffer const char
|
//todo: make memoryBuffer const char
|
||||||
//bFile( const char *memoryBuffer, int len);
|
//bFile( const char *memoryBuffer, int len);
|
||||||
bFile( char *memoryBuffer, int len, const char headerString[7]);
|
bFile(char* memoryBuffer, int len, const char headerString[7]);
|
||||||
virtual ~bFile();
|
virtual ~bFile();
|
||||||
|
|
||||||
bDNA* getFileDNA()
|
bDNA* getFileDNA()
|
||||||
@@ -139,15 +134,15 @@ namespace bParse {
|
|||||||
return mLibPointers;
|
return mLibPointers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* findLibPointer(void *ptr);
|
void* findLibPointer(void* ptr);
|
||||||
|
|
||||||
bool ok();
|
bool ok();
|
||||||
|
|
||||||
virtual void parse(int verboseMode) = 0;
|
virtual void parse(int verboseMode) = 0;
|
||||||
|
|
||||||
virtual int write(const char* fileName, bool fixupPointers=false) = 0;
|
virtual int write(const char* fileName, bool fixupPointers = false) = 0;
|
||||||
|
|
||||||
virtual void writeChunks(FILE* fp, bool fixupPointers );
|
virtual void writeChunks(FILE* fp, bool fixupPointers);
|
||||||
|
|
||||||
virtual void writeDNA(FILE* fp) = 0;
|
virtual void writeDNA(FILE* fp) = 0;
|
||||||
|
|
||||||
@@ -165,11 +160,7 @@ namespace bParse {
|
|||||||
//pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped
|
//pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped
|
||||||
void preSwap();
|
void preSwap();
|
||||||
void writeFile(const char* fileName);
|
void writeFile(const char* fileName);
|
||||||
|
};
|
||||||
|
} // namespace bParse
|
||||||
|
|
||||||
|
#endif //__BFILE_H__
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif//__BFILE_H__
|
|
||||||
|
|||||||
@@ -17,12 +17,11 @@ subject to the following restrictions:
|
|||||||
#include "bDefines.h"
|
#include "bDefines.h"
|
||||||
#include "bDNA.h"
|
#include "bDNA.h"
|
||||||
|
|
||||||
#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
|
#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__)
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
// 32 && 64 bit versions
|
// 32 && 64 bit versions
|
||||||
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
@@ -32,7 +31,7 @@ extern int sBulletDNAlen64;
|
|||||||
extern char sBulletDNAstr[];
|
extern char sBulletDNAstr[];
|
||||||
extern int sBulletDNAlen;
|
extern int sBulletDNAlen;
|
||||||
#endif //_WIN64
|
#endif //_WIN64
|
||||||
#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
|
|
||||||
extern char sBulletDNAstr64[];
|
extern char sBulletDNAstr64[];
|
||||||
extern int sBulletDNAlen64;
|
extern int sBulletDNAlen64;
|
||||||
@@ -44,124 +43,110 @@ extern int sBulletDNAlen;
|
|||||||
using namespace bParse;
|
using namespace bParse;
|
||||||
|
|
||||||
btBulletFile::btBulletFile()
|
btBulletFile::btBulletFile()
|
||||||
:bFile("", "BULLET ")
|
: bFile("", "BULLET ")
|
||||||
{
|
{
|
||||||
mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it"
|
mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it"
|
||||||
|
|
||||||
m_DnaCopy = 0;
|
m_DnaCopy = 0;
|
||||||
|
|
||||||
|
|
||||||
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
|
memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
|
||||||
mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64);
|
mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64);
|
||||||
#else//_WIN64
|
#else //_WIN64
|
||||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
|
memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
|
||||||
mMemoryDNA->init(m_DnaCopy,sBulletDNAlen);
|
mMemoryDNA->init(m_DnaCopy, sBulletDNAlen);
|
||||||
#endif//_WIN64
|
#endif //_WIN64
|
||||||
#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
m_DnaCopy = (char*) btAlignedAlloc(sBulletDNAlen64,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
|
memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
|
||||||
mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64);
|
mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_DnaCopy =(char*) btAlignedAlloc(sBulletDNAlen,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
|
memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
|
||||||
mMemoryDNA->init(m_DnaCopy,sBulletDNAlen);
|
mMemoryDNA->init(m_DnaCopy, sBulletDNAlen);
|
||||||
}
|
}
|
||||||
#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
btBulletFile::btBulletFile(const char* fileName)
|
btBulletFile::btBulletFile(const char* fileName)
|
||||||
:bFile(fileName, "BULLET ")
|
: bFile(fileName, "BULLET ")
|
||||||
{
|
{
|
||||||
m_DnaCopy = 0;
|
m_DnaCopy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btBulletFile::btBulletFile(char* memoryBuffer, int len)
|
||||||
|
: bFile(memoryBuffer, len, "BULLET ")
|
||||||
btBulletFile::btBulletFile(char *memoryBuffer, int len)
|
|
||||||
:bFile(memoryBuffer,len, "BULLET ")
|
|
||||||
{
|
{
|
||||||
m_DnaCopy = 0;
|
m_DnaCopy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btBulletFile::~btBulletFile()
|
btBulletFile::~btBulletFile()
|
||||||
{
|
{
|
||||||
if (m_DnaCopy)
|
if (m_DnaCopy)
|
||||||
btAlignedFree(m_DnaCopy);
|
btAlignedFree(m_DnaCopy);
|
||||||
|
|
||||||
|
|
||||||
while (m_dataBlocks.size())
|
while (m_dataBlocks.size())
|
||||||
{
|
{
|
||||||
char* dataBlock = m_dataBlocks[m_dataBlocks.size()-1];
|
char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1];
|
||||||
delete[] dataBlock;
|
delete[] dataBlock;
|
||||||
m_dataBlocks.pop_back();
|
m_dataBlocks.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------- //
|
// ----------------------------------------------------- //
|
||||||
void btBulletFile::parseData()
|
void btBulletFile::parseData()
|
||||||
{
|
{
|
||||||
// printf ("Building datablocks");
|
// printf ("Building datablocks");
|
||||||
// printf ("Chunk size = %d",CHUNK_HEADER_LEN);
|
// printf ("Chunk size = %d",CHUNK_HEADER_LEN);
|
||||||
// printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
|
// printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
|
||||||
|
|
||||||
const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
|
const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0;
|
||||||
|
|
||||||
//const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
|
//const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
|
||||||
|
|
||||||
|
|
||||||
int remain = mFileLen;
|
int remain = mFileLen;
|
||||||
|
|
||||||
mDataStart = 12;
|
mDataStart = 12;
|
||||||
remain-=12;
|
remain -= 12;
|
||||||
|
|
||||||
//invalid/empty file?
|
//invalid/empty file?
|
||||||
if (remain < sizeof(bChunkInd))
|
if (remain < sizeof(bChunkInd))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char *dataPtr = mFileBuffer+mDataStart;
|
char* dataPtr = mFileBuffer + mDataStart;
|
||||||
|
|
||||||
bChunkInd dataChunk;
|
bChunkInd dataChunk;
|
||||||
dataChunk.code = 0;
|
dataChunk.code = 0;
|
||||||
|
|
||||||
|
|
||||||
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
//dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||||
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
int seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||||
|
|
||||||
|
if (mFlags & FD_ENDIAN_SWAP)
|
||||||
if (mFlags &FD_ENDIAN_SWAP)
|
|
||||||
swapLen(dataPtr);
|
swapLen(dataPtr);
|
||||||
|
|
||||||
//dataPtr += ChunkUtils::getOffset(mFlags);
|
//dataPtr += ChunkUtils::getOffset(mFlags);
|
||||||
char *dataPtrHead = 0;
|
char* dataPtrHead = 0;
|
||||||
|
|
||||||
while (dataChunk.code != DNA1)
|
while (dataChunk.code != DNA1)
|
||||||
{
|
{
|
||||||
if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE) )
|
if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE))
|
||||||
{
|
{
|
||||||
|
|
||||||
// one behind
|
// one behind
|
||||||
if (dataChunk.code == SDNA) break;
|
if (dataChunk.code == SDNA) break;
|
||||||
//if (dataChunk.code == DNA1) break;
|
//if (dataChunk.code == DNA1) break;
|
||||||
|
|
||||||
// same as (BHEAD+DATA dependency)
|
// same as (BHEAD+DATA dependency)
|
||||||
dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags);
|
dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags);
|
||||||
if (dataChunk.dna_nr>=0)
|
if (dataChunk.dna_nr >= 0)
|
||||||
{
|
{
|
||||||
char *id = readStruct(dataPtrHead, dataChunk);
|
char* id = readStruct(dataPtrHead, dataChunk);
|
||||||
|
|
||||||
// lookup maps
|
// lookup maps
|
||||||
if (id)
|
if (id)
|
||||||
@@ -192,87 +177,82 @@ void btBulletFile::parseData()
|
|||||||
|
|
||||||
if (dataChunk.code == BT_SOFTBODY_CODE)
|
if (dataChunk.code == BT_SOFTBODY_CODE)
|
||||||
{
|
{
|
||||||
m_softBodies.push_back((bStructHandle*) id);
|
m_softBodies.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_RIGIDBODY_CODE)
|
if (dataChunk.code == BT_RIGIDBODY_CODE)
|
||||||
{
|
{
|
||||||
m_rigidBodies.push_back((bStructHandle*) id);
|
m_rigidBodies.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
|
if (dataChunk.code == BT_DYNAMICSWORLD_CODE)
|
||||||
{
|
{
|
||||||
m_dynamicsWorldInfo.push_back((bStructHandle*) id);
|
m_dynamicsWorldInfo.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_CONSTRAINT_CODE)
|
if (dataChunk.code == BT_CONSTRAINT_CODE)
|
||||||
{
|
{
|
||||||
m_constraints.push_back((bStructHandle*) id);
|
m_constraints.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
|
if (dataChunk.code == BT_QUANTIZED_BVH_CODE)
|
||||||
{
|
{
|
||||||
m_bvhs.push_back((bStructHandle*) id);
|
m_bvhs.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
|
if (dataChunk.code == BT_TRIANLGE_INFO_MAP)
|
||||||
{
|
{
|
||||||
m_triangleInfoMaps.push_back((bStructHandle*) id);
|
m_triangleInfoMaps.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
|
if (dataChunk.code == BT_COLLISIONOBJECT_CODE)
|
||||||
{
|
{
|
||||||
m_collisionObjects.push_back((bStructHandle*) id);
|
m_collisionObjects.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk.code == BT_SHAPE_CODE)
|
if (dataChunk.code == BT_SHAPE_CODE)
|
||||||
{
|
{
|
||||||
m_collisionShapes.push_back((bStructHandle*) id);
|
m_collisionShapes.push_back((bStructHandle*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (dataChunk.code == GLOB)
|
// if (dataChunk.code == GLOB)
|
||||||
// {
|
// {
|
||||||
// m_glob = (bStructHandle*) id;
|
// m_glob = (bStructHandle*) id;
|
||||||
// }
|
// }
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//printf("unknown chunk\n");
|
//printf("unknown chunk\n");
|
||||||
|
|
||||||
mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
|
mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead);
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
|
printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dataPtr += seek;
|
dataPtr += seek;
|
||||||
remain-=seek;
|
remain -= seek;
|
||||||
if (remain<=0)
|
if (remain <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
seek = getNextBlock(&dataChunk, dataPtr, mFlags);
|
||||||
if (mFlags &FD_ENDIAN_SWAP)
|
if (mFlags & FD_ENDIAN_SWAP)
|
||||||
swapLen(dataPtr);
|
swapLen(dataPtr);
|
||||||
|
|
||||||
if (seek < 0)
|
if (seek < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletFile::addDataBlock(char* dataBlock)
|
void btBulletFile::addDataBlock(char* dataBlock)
|
||||||
{
|
{
|
||||||
m_dataBlocks.push_back(dataBlock);
|
m_dataBlocks.push_back(dataBlock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void btBulletFile::writeDNA(FILE* fp)
|
void btBulletFile::writeDNA(FILE* fp)
|
||||||
{
|
{
|
||||||
|
|
||||||
bChunkInd dataChunk;
|
bChunkInd dataChunk;
|
||||||
dataChunk.code = DNA1;
|
dataChunk.code = DNA1;
|
||||||
dataChunk.dna_nr = 0;
|
dataChunk.dna_nr = 0;
|
||||||
@@ -283,8 +263,8 @@ void btBulletFile::writeDNA(FILE* fp)
|
|||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
dataChunk.len = sBulletDNAlen64;
|
dataChunk.len = sBulletDNAlen64;
|
||||||
dataChunk.oldPtr = sBulletDNAstr64;
|
dataChunk.oldPtr = sBulletDNAstr64;
|
||||||
fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
|
fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
|
||||||
fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
|
fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp);
|
||||||
#else
|
#else
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
#endif
|
#endif
|
||||||
@@ -294,31 +274,30 @@ void btBulletFile::writeDNA(FILE* fp)
|
|||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
dataChunk.len = sBulletDNAlen;
|
dataChunk.len = sBulletDNAlen;
|
||||||
dataChunk.oldPtr = sBulletDNAstr;
|
dataChunk.oldPtr = sBulletDNAstr;
|
||||||
fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
|
fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
|
||||||
fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
|
fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp);
|
||||||
#else//_WIN64
|
#else //_WIN64
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
#endif//_WIN64
|
#endif //_WIN64
|
||||||
}
|
}
|
||||||
#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
dataChunk.len = sBulletDNAlen64;
|
dataChunk.len = sBulletDNAlen64;
|
||||||
dataChunk.oldPtr = sBulletDNAstr64;
|
dataChunk.oldPtr = sBulletDNAstr64;
|
||||||
fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
|
fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
|
||||||
fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp);
|
fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataChunk.len = sBulletDNAlen;
|
dataChunk.len = sBulletDNAlen;
|
||||||
dataChunk.oldPtr = sBulletDNAstr;
|
dataChunk.oldPtr = sBulletDNAstr;
|
||||||
fwrite(&dataChunk,sizeof(bChunkInd),1,fp);
|
fwrite(&dataChunk, sizeof(bChunkInd), 1, fp);
|
||||||
fwrite(sBulletDNAstr, sBulletDNAlen,1,fp);
|
fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp);
|
||||||
}
|
}
|
||||||
#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void btBulletFile::parse(int verboseMode)
|
void btBulletFile::parse(int verboseMode)
|
||||||
{
|
{
|
||||||
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
@@ -328,9 +307,9 @@ void btBulletFile::parse(int verboseMode)
|
|||||||
|
|
||||||
if (m_DnaCopy)
|
if (m_DnaCopy)
|
||||||
delete m_DnaCopy;
|
delete m_DnaCopy;
|
||||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
|
memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
|
||||||
parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64);
|
parseInternal(verboseMode, (char*)sBulletDNAstr64, sBulletDNAlen64);
|
||||||
#else
|
#else
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
#endif
|
#endif
|
||||||
@@ -341,93 +320,91 @@ void btBulletFile::parse(int verboseMode)
|
|||||||
|
|
||||||
if (m_DnaCopy)
|
if (m_DnaCopy)
|
||||||
delete m_DnaCopy;
|
delete m_DnaCopy;
|
||||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
|
memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
|
||||||
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
|
parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen);
|
||||||
#else
|
#else
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
if (m_DnaCopy)
|
if (m_DnaCopy)
|
||||||
delete m_DnaCopy;
|
delete m_DnaCopy;
|
||||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
|
memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64);
|
||||||
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen64);
|
parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen64);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_DnaCopy)
|
if (m_DnaCopy)
|
||||||
delete m_DnaCopy;
|
delete m_DnaCopy;
|
||||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
|
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16);
|
||||||
memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
|
memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen);
|
||||||
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
|
parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen);
|
||||||
}
|
}
|
||||||
#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||||
|
|
||||||
//the parsing will convert to cpu endian
|
//the parsing will convert to cpu endian
|
||||||
mFlags &=~FD_ENDIAN_SWAP;
|
mFlags &= ~FD_ENDIAN_SWAP;
|
||||||
|
|
||||||
int littleEndian= 1;
|
int littleEndian = 1;
|
||||||
littleEndian= ((char*)&littleEndian)[0];
|
littleEndian = ((char*)&littleEndian)[0];
|
||||||
|
|
||||||
mFileBuffer[8] = littleEndian?'v':'V';
|
|
||||||
|
|
||||||
|
mFileBuffer[8] = littleEndian ? 'v' : 'V';
|
||||||
}
|
}
|
||||||
|
|
||||||
// experimental
|
// experimental
|
||||||
int btBulletFile::write(const char* fileName, bool fixupPointers)
|
int btBulletFile::write(const char* fileName, bool fixupPointers)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(fileName, "wb");
|
FILE* fp = fopen(fileName, "wb");
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
char header[SIZEOFBLENDERHEADER] ;
|
char header[SIZEOFBLENDERHEADER];
|
||||||
memcpy(header, m_headerString, 7);
|
memcpy(header, m_headerString, 7);
|
||||||
int endian= 1;
|
int endian = 1;
|
||||||
endian= ((char*)&endian)[0];
|
endian = ((char*)&endian)[0];
|
||||||
|
|
||||||
if (endian)
|
if (endian)
|
||||||
{
|
{
|
||||||
header[7] = '_';
|
header[7] = '_';
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
header[7] = '-';
|
header[7] = '-';
|
||||||
}
|
}
|
||||||
if (VOID_IS_8)
|
if (VOID_IS_8)
|
||||||
{
|
{
|
||||||
header[8]='V';
|
header[8] = 'V';
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
header[8]='v';
|
header[8] = 'v';
|
||||||
}
|
}
|
||||||
|
|
||||||
header[9] = '2';
|
header[9] = '2';
|
||||||
header[10] = '7';
|
header[10] = '7';
|
||||||
header[11] = '5';
|
header[11] = '5';
|
||||||
|
|
||||||
fwrite(header,SIZEOFBLENDERHEADER,1,fp);
|
fwrite(header, SIZEOFBLENDERHEADER, 1, fp);
|
||||||
|
|
||||||
writeChunks(fp, fixupPointers);
|
writeChunks(fp, fixupPointers);
|
||||||
|
|
||||||
writeDNA(fp);
|
writeDNA(fp);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
}
|
||||||
} else
|
else
|
||||||
{
|
{
|
||||||
printf("Error: cannot open file %s for writing\n",fileName);
|
printf("Error: cannot open file %s for writing\n", fileName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btBulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code)
|
||||||
|
|
||||||
void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
bParse::bChunkInd dataChunk;
|
bParse::bChunkInd dataChunk;
|
||||||
dataChunk.code = code;
|
dataChunk.code = code;
|
||||||
dataChunk.nr = 1;
|
dataChunk.nr = 1;
|
||||||
@@ -436,13 +413,12 @@ void btBulletFile::addStruct(const char* structType,void* data, int len, void* o
|
|||||||
dataChunk.oldPtr = oldPtr;
|
dataChunk.oldPtr = oldPtr;
|
||||||
|
|
||||||
///Perform structure size validation
|
///Perform structure size validation
|
||||||
short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr);
|
short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr);
|
||||||
int elemBytes;
|
int elemBytes;
|
||||||
elemBytes= mMemoryDNA->getLength(structInfo[0]);
|
elemBytes = mMemoryDNA->getLength(structInfo[0]);
|
||||||
// int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
|
// int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]);
|
||||||
assert(len==elemBytes);
|
assert(len == elemBytes);
|
||||||
|
|
||||||
mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
|
mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data);
|
||||||
m_chunks.push_back(dataChunk);
|
m_chunks.push_back(dataChunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,29 +16,21 @@ subject to the following restrictions:
|
|||||||
#ifndef BT_BULLET_FILE_H
|
#ifndef BT_BULLET_FILE_H
|
||||||
#define BT_BULLET_FILE_H
|
#define BT_BULLET_FILE_H
|
||||||
|
|
||||||
|
|
||||||
#include "bFile.h"
|
#include "bFile.h"
|
||||||
#include "LinearMath/btAlignedObjectArray.h"
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
#include "bDefines.h"
|
#include "bDefines.h"
|
||||||
|
|
||||||
|
|
||||||
#include "LinearMath/btSerializer.h"
|
#include "LinearMath/btSerializer.h"
|
||||||
|
|
||||||
|
namespace bParse
|
||||||
|
{
|
||||||
namespace bParse {
|
// ----------------------------------------------------- //
|
||||||
|
class btBulletFile : public bFile
|
||||||
// ----------------------------------------------------- //
|
{
|
||||||
class btBulletFile : public bFile
|
protected:
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
char* m_DnaCopy;
|
char* m_DnaCopy;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btAlignedObjectArray<bStructHandle*> m_multiBodies;
|
btAlignedObjectArray<bStructHandle*> m_multiBodies;
|
||||||
|
|
||||||
btAlignedObjectArray<bStructHandle*> m_multiBodyLinkColliders;
|
btAlignedObjectArray<bStructHandle*> m_multiBodyLinkColliders;
|
||||||
@@ -66,15 +58,14 @@ namespace bParse {
|
|||||||
|
|
||||||
btBulletFile(const char* fileName);
|
btBulletFile(const char* fileName);
|
||||||
|
|
||||||
btBulletFile(char *memoryBuffer, int len);
|
btBulletFile(char* memoryBuffer, int len);
|
||||||
|
|
||||||
virtual ~btBulletFile();
|
virtual ~btBulletFile();
|
||||||
|
|
||||||
virtual void addDataBlock(char* dataBlock);
|
virtual void addDataBlock(char* dataBlock);
|
||||||
|
|
||||||
|
|
||||||
// experimental
|
// experimental
|
||||||
virtual int write(const char* fileName, bool fixupPointers=false);
|
virtual int write(const char* fileName, bool fixupPointers = false);
|
||||||
|
|
||||||
virtual void parse(int verboseMode);
|
virtual void parse(int verboseMode);
|
||||||
|
|
||||||
@@ -82,9 +73,8 @@ namespace bParse {
|
|||||||
|
|
||||||
virtual void writeDNA(FILE* fp);
|
virtual void writeDNA(FILE* fp);
|
||||||
|
|
||||||
void addStruct(const char* structType,void* data, int len, void* oldPtr, int code);
|
void addStruct(const char* structType, void* data, int len, void* oldPtr, int code);
|
||||||
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
}; // namespace bParse
|
||||||
|
|
||||||
#endif //BT_BULLET_FILE_H
|
#endif //BT_BULLET_FILE_H
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
|||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "btBulletWorldImporter.h"
|
#include "btBulletWorldImporter.h"
|
||||||
#include "../BulletFileLoader/btBulletFile.h"
|
#include "../BulletFileLoader/btBulletFile.h"
|
||||||
|
|
||||||
@@ -22,14 +21,13 @@ subject to the following restrictions:
|
|||||||
#include "BulletCollision/Gimpact/btGImpactShape.h"
|
#include "BulletCollision/Gimpact/btGImpactShape.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//#define USE_INTERNAL_EDGE_UTILITY
|
//#define USE_INTERNAL_EDGE_UTILITY
|
||||||
#ifdef USE_INTERNAL_EDGE_UTILITY
|
#ifdef USE_INTERNAL_EDGE_UTILITY
|
||||||
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
|
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
|
||||||
#endif //USE_INTERNAL_EDGE_UTILITY
|
#endif //USE_INTERNAL_EDGE_UTILITY
|
||||||
|
|
||||||
btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world)
|
btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world)
|
||||||
:btWorldImporter(world)
|
: btWorldImporter(world)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,12 +35,10 @@ btBulletWorldImporter::~btBulletWorldImporter()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool btBulletWorldImporter::loadFile(const char* fileName, const char* preSwapFilenameOut)
|
||||||
bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapFilenameOut)
|
|
||||||
{
|
{
|
||||||
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
||||||
|
|
||||||
|
|
||||||
bool result = loadFileFromMemory(bulletFile2);
|
bool result = loadFileFromMemory(bulletFile2);
|
||||||
//now you could save the file in 'native' format using
|
//now you could save the file in 'native' format using
|
||||||
//bulletFile2->writeFile("native.bullet");
|
//bulletFile2->writeFile("native.bullet");
|
||||||
@@ -53,19 +49,15 @@ bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapF
|
|||||||
bulletFile2->preSwap();
|
bulletFile2->preSwap();
|
||||||
bulletFile2->writeFile(preSwapFilenameOut);
|
bulletFile2->writeFile(preSwapFilenameOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
delete bulletFile2;
|
delete bulletFile2;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool btBulletWorldImporter::loadFileFromMemory(char* memoryBuffer, int len)
|
||||||
|
|
||||||
bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len)
|
|
||||||
{
|
{
|
||||||
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len);
|
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer, len);
|
||||||
|
|
||||||
bool result = loadFileFromMemory(bulletFile2);
|
bool result = loadFileFromMemory(bulletFile2);
|
||||||
|
|
||||||
@@ -74,12 +66,9 @@ bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool btBulletWorldImporter::loadFileFromMemory(bParse::btBulletFile* bulletFile2)
|
||||||
|
|
||||||
|
|
||||||
bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFile2)
|
|
||||||
{
|
{
|
||||||
bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
|
bool ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0;
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
bulletFile2->parse(m_verboseMode);
|
bulletFile2->parse(m_verboseMode);
|
||||||
@@ -92,18 +81,16 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
|||||||
}
|
}
|
||||||
|
|
||||||
return convertAllObjects(bulletFile2);
|
return convertAllObjects(bulletFile2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2)
|
bool btBulletWorldImporter::convertAllObjects(bParse::btBulletFile* bulletFile2)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_shapeMap.clear();
|
m_shapeMap.clear();
|
||||||
m_bodyMap.clear();
|
m_bodyMap.clear();
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0;i<bulletFile2->m_bvhs.size();i++)
|
for (i = 0; i < bulletFile2->m_bvhs.size(); i++)
|
||||||
{
|
{
|
||||||
btOptimizedBvh* bvh = createOptimizedBvh();
|
btOptimizedBvh* bvh = createOptimizedBvh();
|
||||||
|
|
||||||
@@ -111,41 +98,34 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
{
|
{
|
||||||
btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
|
btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
|
||||||
bvh->deSerializeDouble(*bvhData);
|
bvh->deSerializeDouble(*bvhData);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
|
btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
|
||||||
bvh->deSerializeFloat(*bvhData);
|
bvh->deSerializeFloat(*bvhData);
|
||||||
}
|
}
|
||||||
m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh);
|
m_bvhMap.insert(bulletFile2->m_bvhs[i], bvh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bulletFile2->m_collisionShapes.size(); i++)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
|
|
||||||
{
|
{
|
||||||
btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
|
btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
|
||||||
btCollisionShape* shape = convertCollisionShape(shapeData);
|
btCollisionShape* shape = convertCollisionShape(shapeData);
|
||||||
if (shape)
|
if (shape)
|
||||||
{
|
{
|
||||||
// printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
|
// printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
|
||||||
m_shapeMap.insert(shapeData,shape);
|
m_shapeMap.insert(shapeData, shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shape&& shapeData->m_name)
|
if (shape && shapeData->m_name)
|
||||||
{
|
{
|
||||||
char* newname = duplicateName(shapeData->m_name);
|
char* newname = duplicateName(shapeData->m_name);
|
||||||
m_objectNameMap.insert(shape,newname);
|
m_objectNameMap.insert(shape, newname);
|
||||||
m_nameShapeMap.insert(newname,shape);
|
m_nameShapeMap.insert(newname, shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < bulletFile2->m_dynamicsWorldInfo.size(); i++)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i<bulletFile2->m_dynamicsWorldInfo.size();i++)
|
|
||||||
{
|
{
|
||||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||||
{
|
{
|
||||||
@@ -182,8 +162,9 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
|
|
||||||
solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
|
solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
|
||||||
|
|
||||||
setDynamicsWorldInfo(gravity,solverInfo);
|
setDynamicsWorldInfo(gravity, solverInfo);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i];
|
btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i];
|
||||||
btContactSolverInfo solverInfo;
|
btContactSolverInfo solverInfo;
|
||||||
@@ -218,27 +199,25 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
|
|
||||||
solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
|
solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
|
||||||
|
|
||||||
setDynamicsWorldInfo(gravity,solverInfo);
|
setDynamicsWorldInfo(gravity, solverInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bulletFile2->m_rigidBodies.size(); i++)
|
||||||
for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
|
|
||||||
{
|
{
|
||||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||||
{
|
{
|
||||||
btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i];
|
btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i];
|
||||||
convertRigidBodyDouble(colObjData);
|
convertRigidBodyDouble(colObjData);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
|
btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
|
||||||
convertRigidBodyFloat(colObjData);
|
convertRigidBodyFloat(colObjData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<bulletFile2->m_collisionObjects.size();i++)
|
for (i = 0; i < bulletFile2->m_collisionObjects.size(); i++)
|
||||||
{
|
{
|
||||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||||
{
|
{
|
||||||
@@ -251,7 +230,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
startTransform.deSerializeDouble(colObjData->m_worldTransform);
|
startTransform.deSerializeDouble(colObjData->m_worldTransform);
|
||||||
|
|
||||||
btCollisionShape* shape = (btCollisionShape*)*shapePtr;
|
btCollisionShape* shape = (btCollisionShape*)*shapePtr;
|
||||||
btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
|
btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name);
|
||||||
body->setFriction(btScalar(colObjData->m_friction));
|
body->setFriction(btScalar(colObjData->m_friction));
|
||||||
body->setRestitution(btScalar(colObjData->m_restitution));
|
body->setRestitution(btScalar(colObjData->m_restitution));
|
||||||
|
|
||||||
@@ -265,13 +244,14 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //USE_INTERNAL_EDGE_UTILITY
|
#endif //USE_INTERNAL_EDGE_UTILITY
|
||||||
m_bodyMap.insert(colObjData,body);
|
m_bodyMap.insert(colObjData, body);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
printf("error: no shape found\n");
|
printf("error: no shape found\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
else
|
||||||
{
|
{
|
||||||
btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i];
|
btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i];
|
||||||
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
|
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
|
||||||
@@ -282,7 +262,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
startTransform.deSerializeFloat(colObjData->m_worldTransform);
|
startTransform.deSerializeFloat(colObjData->m_worldTransform);
|
||||||
|
|
||||||
btCollisionShape* shape = (btCollisionShape*)*shapePtr;
|
btCollisionShape* shape = (btCollisionShape*)*shapePtr;
|
||||||
btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
|
btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name);
|
||||||
|
|
||||||
#ifdef USE_INTERNAL_EDGE_UTILITY
|
#ifdef USE_INTERNAL_EDGE_UTILITY
|
||||||
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||||
@@ -294,17 +274,16 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //USE_INTERNAL_EDGE_UTILITY
|
#endif //USE_INTERNAL_EDGE_UTILITY
|
||||||
m_bodyMap.insert(colObjData,body);
|
m_bodyMap.insert(colObjData, body);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
printf("error: no shape found\n");
|
printf("error: no shape found\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bulletFile2->m_constraints.size(); i++)
|
||||||
for (i=0;i<bulletFile2->m_constraints.size();i++)
|
|
||||||
{
|
{
|
||||||
btTypedConstraintData2* constraintData = (btTypedConstraintData2*)bulletFile2->m_constraints[i];
|
btTypedConstraintData2* constraintData = (btTypedConstraintData2*)bulletFile2->m_constraints[i];
|
||||||
|
|
||||||
@@ -329,33 +308,30 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
if (!rbA && !rbB)
|
if (!rbA && !rbB)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0;
|
bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) != 0;
|
||||||
|
|
||||||
if (isDoublePrecisionData)
|
if (isDoublePrecisionData)
|
||||||
{
|
{
|
||||||
if (bulletFile2->getVersion()>=282)
|
if (bulletFile2->getVersion() >= 282)
|
||||||
{
|
{
|
||||||
btTypedConstraintDoubleData* dc = (btTypedConstraintDoubleData*)constraintData;
|
btTypedConstraintDoubleData* dc = (btTypedConstraintDoubleData*)constraintData;
|
||||||
convertConstraintDouble(dc, rbA,rbB, bulletFile2->getVersion());
|
convertConstraintDouble(dc, rbA, rbB, bulletFile2->getVersion());
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//double-precision constraints were messed up until 2.82, try to recover data...
|
//double-precision constraints were messed up until 2.82, try to recover data...
|
||||||
|
|
||||||
btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData;
|
btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData;
|
||||||
|
|
||||||
convertConstraintBackwardsCompatible281(oldData, rbA,rbB, bulletFile2->getVersion());
|
convertConstraintBackwardsCompatible281(oldData, rbA, rbB, bulletFile2->getVersion());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
btTypedConstraintFloatData* dc = (btTypedConstraintFloatData*)constraintData;
|
btTypedConstraintFloatData* dc = (btTypedConstraintFloatData*)constraintData;
|
||||||
convertConstraintFloat(dc, rbA,rbB, bulletFile2->getVersion());
|
convertConstraintFloat(dc, rbA, rbB, bulletFile2->getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,56 +13,40 @@ subject to the following restrictions:
|
|||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BULLET_WORLD_IMPORTER_H
|
#ifndef BULLET_WORLD_IMPORTER_H
|
||||||
#define BULLET_WORLD_IMPORTER_H
|
#define BULLET_WORLD_IMPORTER_H
|
||||||
|
|
||||||
|
|
||||||
#include "btWorldImporter.h"
|
#include "btWorldImporter.h"
|
||||||
|
|
||||||
|
|
||||||
class btBulletFile;
|
class btBulletFile;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace bParse
|
namespace bParse
|
||||||
{
|
{
|
||||||
class btBulletFile;
|
class btBulletFile;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///The btBulletWorldImporter is a starting point to import .bullet files.
|
///The btBulletWorldImporter is a starting point to import .bullet files.
|
||||||
///note that not all data is converted yet. You are expected to override or modify this class.
|
///note that not all data is converted yet. You are expected to override or modify this class.
|
||||||
///See Bullet/Demos/SerializeDemo for a derived class that extract btSoftBody objects too.
|
///See Bullet/Demos/SerializeDemo for a derived class that extract btSoftBody objects too.
|
||||||
class btBulletWorldImporter : public btWorldImporter
|
class btBulletWorldImporter : public btWorldImporter
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
btBulletWorldImporter(btDynamicsWorld* world = 0);
|
||||||
btBulletWorldImporter(btDynamicsWorld* world=0);
|
|
||||||
|
|
||||||
virtual ~btBulletWorldImporter();
|
virtual ~btBulletWorldImporter();
|
||||||
|
|
||||||
///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness
|
///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness
|
||||||
///this pre-swapped file can be loaded without swapping on a target platform of different endianness
|
///this pre-swapped file can be loaded without swapping on a target platform of different endianness
|
||||||
bool loadFile(const char* fileName, const char* preSwapFilenameOut=0);
|
bool loadFile(const char* fileName, const char* preSwapFilenameOut = 0);
|
||||||
|
|
||||||
///the memoryBuffer might be modified (for example if endian swaps are necessary)
|
///the memoryBuffer might be modified (for example if endian swaps are necessary)
|
||||||
bool loadFileFromMemory(char *memoryBuffer, int len);
|
bool loadFileFromMemory(char* memoryBuffer, int len);
|
||||||
|
|
||||||
bool loadFileFromMemory(bParse::btBulletFile* file);
|
bool loadFileFromMemory(bParse::btBulletFile* file);
|
||||||
|
|
||||||
//call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory
|
//call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory
|
||||||
virtual bool convertAllObjects(bParse::btBulletFile* file);
|
virtual bool convertAllObjects(bParse::btBulletFile* file);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BULLET_WORLD_IMPORTER_H
|
#endif //BULLET_WORLD_IMPORTER_H
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,12 @@ struct btMultiBodyWorldImporterInternalData
|
|||||||
};
|
};
|
||||||
|
|
||||||
btMultiBodyWorldImporter::btMultiBodyWorldImporter(btMultiBodyDynamicsWorld* world)
|
btMultiBodyWorldImporter::btMultiBodyWorldImporter(btMultiBodyDynamicsWorld* world)
|
||||||
:btBulletWorldImporter(world)
|
: btBulletWorldImporter(world)
|
||||||
{
|
{
|
||||||
m_data = new btMultiBodyWorldImporterInternalData;
|
m_data = new btMultiBodyWorldImporterInternalData;
|
||||||
m_data->m_mbDynamicsWorld = world;
|
m_data->m_mbDynamicsWorld = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btMultiBodyWorldImporter::~btMultiBodyWorldImporter()
|
btMultiBodyWorldImporter::~btMultiBodyWorldImporter()
|
||||||
{
|
{
|
||||||
delete m_data;
|
delete m_data;
|
||||||
@@ -32,7 +31,6 @@ void btMultiBodyWorldImporter::deleteAllData()
|
|||||||
btBulletWorldImporter::deleteAllData();
|
btBulletWorldImporter::deleteAllData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static btCollisionObjectDoubleData* getBody0FromContactManifold(btPersistentManifoldDoubleData* manifold)
|
static btCollisionObjectDoubleData* getBody0FromContactManifold(btPersistentManifoldDoubleData* manifold)
|
||||||
{
|
{
|
||||||
return (btCollisionObjectDoubleData*)manifold->m_body0;
|
return (btCollisionObjectDoubleData*)manifold->m_body0;
|
||||||
@@ -50,8 +48,8 @@ static btCollisionObjectFloatData* getBody1FromContactManifold(btPersistentManif
|
|||||||
return (btCollisionObjectFloatData*)manifold->m_body1;
|
return (btCollisionObjectFloatData*)manifold->m_body1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
template<class T> void syncContactManifolds(T** contactManifolds, int numContactManifolds, btMultiBodyWorldImporterInternalData* m_data)
|
void syncContactManifolds(T** contactManifolds, int numContactManifolds, btMultiBodyWorldImporterInternalData* m_data)
|
||||||
{
|
{
|
||||||
m_data->m_mbDynamicsWorld->updateAabbs();
|
m_data->m_mbDynamicsWorld->updateAabbs();
|
||||||
m_data->m_mbDynamicsWorld->computeOverlappingPairs();
|
m_data->m_mbDynamicsWorld->computeOverlappingPairs();
|
||||||
@@ -59,7 +57,6 @@ template<class T> void syncContactManifolds(T** contactManifolds, int numContact
|
|||||||
|
|
||||||
btDispatcherInfo& dispatchInfo = m_data->m_mbDynamicsWorld->getDispatchInfo();
|
btDispatcherInfo& dispatchInfo = m_data->m_mbDynamicsWorld->getDispatchInfo();
|
||||||
|
|
||||||
|
|
||||||
if (dispatcher)
|
if (dispatcher)
|
||||||
{
|
{
|
||||||
btOverlappingPairCache* pairCache = m_data->m_mbDynamicsWorld->getBroadphase()->getOverlappingPairCache();
|
btOverlappingPairCache* pairCache = m_data->m_mbDynamicsWorld->getBroadphase()->getOverlappingPairCache();
|
||||||
@@ -104,10 +101,10 @@ template<class T> void syncContactManifolds(T** contactManifolds, int numContact
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldImporterInternalData* m_data, btAlignedObjectArray<btQuaternion>& scratchQ, btAlignedObjectArray<btVector3>& scratchM)
|
template <class T>
|
||||||
|
void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldImporterInternalData* m_data, btAlignedObjectArray<btQuaternion>& scratchQ, btAlignedObjectArray<btVector3>& scratchM)
|
||||||
{
|
{
|
||||||
bool isFixedBase = mbd->m_baseMass == 0;
|
bool isFixedBase = mbd->m_baseMass == 0;
|
||||||
bool canSleep = false;
|
bool canSleep = false;
|
||||||
@@ -129,7 +126,6 @@ template<class T> void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldI
|
|||||||
|
|
||||||
for (int i = 0; i < mbd->m_numLinks; i++)
|
for (int i = 0; i < mbd->m_numLinks; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
mb->getLink(i).m_absFrameTotVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityTop);
|
mb->getLink(i).m_absFrameTotVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityTop);
|
||||||
mb->getLink(i).m_absFrameTotVelocity.m_bottomVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityBottom);
|
mb->getLink(i).m_absFrameTotVelocity.m_bottomVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityBottom);
|
||||||
mb->getLink(i).m_absFrameLocVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameLocVelocityTop);
|
mb->getLink(i).m_absFrameLocVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameLocVelocityTop);
|
||||||
@@ -155,8 +151,8 @@ template<class T> void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldI
|
|||||||
}
|
}
|
||||||
case btMultibodyLink::eSpherical:
|
case btMultibodyLink::eSpherical:
|
||||||
{
|
{
|
||||||
btScalar jointPos[4] = { (btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3] };
|
btScalar jointPos[4] = {(btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3]};
|
||||||
btScalar jointVel[3] = { (btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2] };
|
btScalar jointVel[3] = {(btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2]};
|
||||||
mb->setJointPosMultiDof(i, jointPos);
|
mb->setJointPosMultiDof(i, jointPos);
|
||||||
mb->setJointVelMultiDof(i, jointVel);
|
mb->setJointVelMultiDof(i, jointVel);
|
||||||
|
|
||||||
@@ -175,7 +171,8 @@ template<class T> void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldI
|
|||||||
mb->updateCollisionObjectWorldTransforms(scratchQ, scratchM);
|
mb->updateCollisionObjectWorldTransforms(scratchQ, scratchM);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> void convertMultiBody(T* mbd, btMultiBodyWorldImporterInternalData* m_data)
|
template <class T>
|
||||||
|
void convertMultiBody(T* mbd, btMultiBodyWorldImporterInternalData* m_data)
|
||||||
{
|
{
|
||||||
bool isFixedBase = mbd->m_baseMass == 0;
|
bool isFixedBase = mbd->m_baseMass == 0;
|
||||||
bool canSleep = false;
|
bool canSleep = false;
|
||||||
@@ -208,8 +205,6 @@ template<class T> void convertMultiBody(T* mbd, btMultiBodyWorldImporterInterna
|
|||||||
{
|
{
|
||||||
case btMultibodyLink::eFixed:
|
case btMultibodyLink::eFixed:
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
mb->setupFixed(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
mb->setupFixed(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
||||||
parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset);
|
parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset);
|
||||||
//search for the collider
|
//search for the collider
|
||||||
@@ -220,7 +215,7 @@ template<class T> void convertMultiBody(T* mbd, btMultiBodyWorldImporterInterna
|
|||||||
{
|
{
|
||||||
btVector3 jointAxis;
|
btVector3 jointAxis;
|
||||||
jointAxis.deSerialize(mbd->m_links[i].m_jointAxisBottom[0]);
|
jointAxis.deSerialize(mbd->m_links[i].m_jointAxisBottom[0]);
|
||||||
bool disableParentCollision = true;//todo
|
bool disableParentCollision = true; //todo
|
||||||
mb->setupPrismatic(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
mb->setupPrismatic(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
||||||
parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision);
|
parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision);
|
||||||
mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]);
|
mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]);
|
||||||
@@ -231,7 +226,7 @@ template<class T> void convertMultiBody(T* mbd, btMultiBodyWorldImporterInterna
|
|||||||
{
|
{
|
||||||
btVector3 jointAxis;
|
btVector3 jointAxis;
|
||||||
jointAxis.deSerialize(mbd->m_links[i].m_jointAxisTop[0]);
|
jointAxis.deSerialize(mbd->m_links[i].m_jointAxisTop[0]);
|
||||||
bool disableParentCollision = true;//todo
|
bool disableParentCollision = true; //todo
|
||||||
mb->setupRevolute(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
mb->setupRevolute(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
||||||
parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision);
|
parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision);
|
||||||
mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]);
|
mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]);
|
||||||
@@ -241,11 +236,11 @@ template<class T> void convertMultiBody(T* mbd, btMultiBodyWorldImporterInterna
|
|||||||
case btMultibodyLink::eSpherical:
|
case btMultibodyLink::eSpherical:
|
||||||
{
|
{
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
bool disableParentCollision = true;//todo
|
bool disableParentCollision = true; //todo
|
||||||
mb->setupSpherical(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
mb->setupSpherical(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex,
|
||||||
parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision);
|
parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision);
|
||||||
btScalar jointPos[4] = { (btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3] };
|
btScalar jointPos[4] = {(btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3]};
|
||||||
btScalar jointVel[3] = { (btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2] };
|
btScalar jointVel[3] = {(btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2]};
|
||||||
mb->setJointPosMultiDof(i, jointPos);
|
mb->setJointPosMultiDof(i, jointPos);
|
||||||
mb->setJointVelMultiDof(i, jointVel);
|
mb->setJointVelMultiDof(i, jointVel);
|
||||||
|
|
||||||
@@ -264,13 +259,13 @@ template<class T> void convertMultiBody(T* mbd, btMultiBodyWorldImporterInterna
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2)
|
bool btMultiBodyWorldImporter::convertAllObjects(bParse::btBulletFile* bulletFile2)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
btAlignedObjectArray<btQuaternion> scratchQ;
|
btAlignedObjectArray<btQuaternion> scratchQ;
|
||||||
btAlignedObjectArray<btVector3> scratchM;
|
btAlignedObjectArray<btVector3> scratchM;
|
||||||
|
|
||||||
if (m_importerFlags&eRESTORE_EXISTING_OBJECTS)
|
if (m_importerFlags & eRESTORE_EXISTING_OBJECTS)
|
||||||
{
|
{
|
||||||
//check if the snapshot is valid for the existing world
|
//check if the snapshot is valid for the existing world
|
||||||
//equal number of objects, # links etc
|
//equal number of objects, # links etc
|
||||||
@@ -284,7 +279,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
//convert all multibodies
|
//convert all multibodies
|
||||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||||
{
|
{
|
||||||
|
|
||||||
//for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++)
|
//for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++)
|
||||||
for (int i = bulletFile2->m_multiBodies.size() - 1; i >= 0; i--)
|
for (int i = bulletFile2->m_multiBodies.size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -352,7 +346,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (bulletFile2->m_contactManifolds.size())
|
if (bulletFile2->m_contactManifolds.size())
|
||||||
{
|
{
|
||||||
syncContactManifolds((btPersistentManifoldDoubleData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data);
|
syncContactManifolds((btPersistentManifoldDoubleData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data);
|
||||||
@@ -389,23 +382,19 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (bulletFile2->m_contactManifolds.size())
|
if (bulletFile2->m_contactManifolds.size())
|
||||||
{
|
{
|
||||||
syncContactManifolds((btPersistentManifoldFloatData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data);
|
syncContactManifolds((btPersistentManifoldFloatData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = btBulletWorldImporter::convertAllObjects(bulletFile2);
|
result = btBulletWorldImporter::convertAllObjects(bulletFile2);
|
||||||
|
|
||||||
|
|
||||||
//convert all multibodies
|
//convert all multibodies
|
||||||
for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++)
|
for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||||
{
|
{
|
||||||
btMultiBodyDoubleData* mbd = (btMultiBodyDoubleData*)bulletFile2->m_multiBodies[i];
|
btMultiBodyDoubleData* mbd = (btMultiBodyDoubleData*)bulletFile2->m_multiBodies[i];
|
||||||
@@ -421,7 +410,7 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
//forward kinematics, so that the link world transforms are valid, for collision detection
|
//forward kinematics, so that the link world transforms are valid, for collision detection
|
||||||
for (int i = 0; i < m_data->m_mbMap.size(); i++)
|
for (int i = 0; i < m_data->m_mbMap.size(); i++)
|
||||||
{
|
{
|
||||||
btMultiBody**ptr = m_data->m_mbMap.getAtIndex(i);
|
btMultiBody** ptr = m_data->m_mbMap.getAtIndex(i);
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
btMultiBody* mb = *ptr;
|
btMultiBody* mb = *ptr;
|
||||||
@@ -444,7 +433,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
{
|
{
|
||||||
btMultiBody* multiBody = *ptr;
|
btMultiBody* multiBody = *ptr;
|
||||||
|
|
||||||
|
|
||||||
btCollisionShape** shapePtr = m_shapeMap.find(mblcd->m_colObjData.m_collisionShape);
|
btCollisionShape** shapePtr = m_shapeMap.find(mblcd->m_colObjData.m_collisionShape);
|
||||||
if (shapePtr && *shapePtr)
|
if (shapePtr && *shapePtr)
|
||||||
{
|
{
|
||||||
@@ -491,7 +479,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
#endif
|
#endif
|
||||||
m_data->m_mbDynamicsWorld->addCollisionObject(col, collisionFilterGroup, collisionFilterMask);
|
m_data->m_mbDynamicsWorld->addCollisionObject(col, collisionFilterGroup, collisionFilterMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -503,13 +490,12 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF
|
|||||||
world1->addCollisionObject(col, collisionFilterGroup, collisionFilterMask);
|
world1->addCollisionObject(col, collisionFilterGroup, collisionFilterMask);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_data->m_mbMap.size(); i++)
|
for (int i = 0; i < m_data->m_mbMap.size(); i++)
|
||||||
{
|
{
|
||||||
btMultiBody**ptr = m_data->m_mbMap.getAtIndex(i);
|
btMultiBody** ptr = m_data->m_mbMap.getAtIndex(i);
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
btMultiBody* mb = *ptr;
|
btMultiBody* mb = *ptr;
|
||||||
|
|||||||
@@ -8,11 +8,10 @@ class btMultiBodyWorldImporter : public btBulletWorldImporter
|
|||||||
struct btMultiBodyWorldImporterInternalData* m_data;
|
struct btMultiBodyWorldImporterInternalData* m_data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btMultiBodyWorldImporter(class btMultiBodyDynamicsWorld* world);
|
btMultiBodyWorldImporter(class btMultiBodyDynamicsWorld* world);
|
||||||
virtual ~btMultiBodyWorldImporter();
|
virtual ~btMultiBodyWorldImporter();
|
||||||
|
|
||||||
virtual bool convertAllObjects( bParse::btBulletFile* bulletFile2);
|
virtual bool convertAllObjects(bParse::btBulletFile* bulletFile2);
|
||||||
|
|
||||||
virtual void deleteAllData();
|
virtual void deleteAllData();
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
|||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BT_WORLD_IMPORTER_H
|
#ifndef BT_WORLD_IMPORTER_H
|
||||||
#define BT_WORLD_IMPORTER_H
|
#define BT_WORLD_IMPORTER_H
|
||||||
|
|
||||||
@@ -57,11 +56,11 @@ struct btRigidBodyFloatData;
|
|||||||
#define btRigidBodyData btRigidBodyDoubleData
|
#define btRigidBodyData btRigidBodyDoubleData
|
||||||
#else
|
#else
|
||||||
#define btRigidBodyData btRigidBodyFloatData
|
#define btRigidBodyData btRigidBodyFloatData
|
||||||
#endif//BT_USE_DOUBLE_PRECISION
|
#endif //BT_USE_DOUBLE_PRECISION
|
||||||
|
|
||||||
enum btWorldImporterFlags
|
enum btWorldImporterFlags
|
||||||
{
|
{
|
||||||
eRESTORE_EXISTING_OBJECTS=1,//don't create new objects
|
eRESTORE_EXISTING_OBJECTS = 1, //don't create new objects
|
||||||
};
|
};
|
||||||
|
|
||||||
class btWorldImporter
|
class btWorldImporter
|
||||||
@@ -89,18 +88,16 @@ protected:
|
|||||||
btAlignedObjectArray<btVector3FloatData*> m_floatVertexArrays;
|
btAlignedObjectArray<btVector3FloatData*> m_floatVertexArrays;
|
||||||
btAlignedObjectArray<btVector3DoubleData*> m_doubleVertexArrays;
|
btAlignedObjectArray<btVector3DoubleData*> m_doubleVertexArrays;
|
||||||
|
|
||||||
|
btHashMap<btHashPtr, btOptimizedBvh*> m_bvhMap;
|
||||||
|
btHashMap<btHashPtr, btTriangleInfoMap*> m_timMap;
|
||||||
|
|
||||||
btHashMap<btHashPtr,btOptimizedBvh*> m_bvhMap;
|
btHashMap<btHashString, btCollisionShape*> m_nameShapeMap;
|
||||||
btHashMap<btHashPtr,btTriangleInfoMap*> m_timMap;
|
btHashMap<btHashString, btRigidBody*> m_nameBodyMap;
|
||||||
|
btHashMap<btHashString, btTypedConstraint*> m_nameConstraintMap;
|
||||||
btHashMap<btHashString,btCollisionShape*> m_nameShapeMap;
|
btHashMap<btHashPtr, const char*> m_objectNameMap;
|
||||||
btHashMap<btHashString,btRigidBody*> m_nameBodyMap;
|
|
||||||
btHashMap<btHashString,btTypedConstraint*> m_nameConstraintMap;
|
|
||||||
btHashMap<btHashPtr,const char*> m_objectNameMap;
|
|
||||||
|
|
||||||
btHashMap<btHashPtr,btCollisionShape*> m_shapeMap;
|
|
||||||
btHashMap<btHashPtr,btCollisionObject*> m_bodyMap;
|
|
||||||
|
|
||||||
|
btHashMap<btHashPtr, btCollisionShape*> m_shapeMap;
|
||||||
|
btHashMap<btHashPtr, btCollisionObject*> m_bodyMap;
|
||||||
|
|
||||||
//methods
|
//methods
|
||||||
|
|
||||||
@@ -108,16 +105,15 @@ protected:
|
|||||||
|
|
||||||
char* duplicateName(const char* name);
|
char* duplicateName(const char* name);
|
||||||
|
|
||||||
btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData );
|
btCollisionShape* convertCollisionShape(btCollisionShapeData* shapeData);
|
||||||
|
|
||||||
void convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion);
|
void convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion);
|
||||||
void convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion);
|
void convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion);
|
||||||
void convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion);
|
void convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion);
|
||||||
void convertRigidBodyFloat(btRigidBodyFloatData* colObjData);
|
void convertRigidBodyFloat(btRigidBodyFloatData* colObjData);
|
||||||
void convertRigidBodyDouble( btRigidBodyDoubleData* colObjData);
|
void convertRigidBodyDouble(btRigidBodyDoubleData* colObjData);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btWorldImporter(btDynamicsWorld* world);
|
btWorldImporter(btDynamicsWorld* world);
|
||||||
|
|
||||||
virtual ~btWorldImporter();
|
virtual ~btWorldImporter();
|
||||||
@@ -146,8 +142,6 @@ public:
|
|||||||
return m_importerFlags;
|
return m_importerFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// query for data
|
// query for data
|
||||||
int getNumCollisionShapes() const;
|
int getNumCollisionShapes() const;
|
||||||
btCollisionShape* getCollisionShapeByIndex(int index);
|
btCollisionShape* getCollisionShapeByIndex(int index);
|
||||||
@@ -171,24 +165,24 @@ public:
|
|||||||
virtual void setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo);
|
virtual void setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo);
|
||||||
|
|
||||||
//bodies
|
//bodies
|
||||||
virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape, const char* bodyName);
|
||||||
virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
virtual btCollisionObject* createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName);
|
||||||
|
|
||||||
///shapes
|
///shapes
|
||||||
|
|
||||||
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
|
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal, btScalar planeConstant);
|
||||||
virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
|
virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
|
||||||
virtual btCollisionShape* createSphereShape(btScalar radius);
|
virtual btCollisionShape* createSphereShape(btScalar radius);
|
||||||
virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
|
virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
|
virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
|
virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
|
||||||
|
|
||||||
virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height);
|
virtual btCollisionShape* createCylinderShapeX(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height);
|
virtual btCollisionShape* createCylinderShapeY(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
|
virtual btCollisionShape* createCylinderShapeZ(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height);
|
virtual btCollisionShape* createConeShapeX(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height);
|
virtual btCollisionShape* createConeShapeY(btScalar radius, btScalar height);
|
||||||
virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height);
|
virtual btCollisionShape* createConeShapeZ(btScalar radius, btScalar height);
|
||||||
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
|
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
|
||||||
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
|
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
|
||||||
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
|
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
|
||||||
@@ -197,9 +191,9 @@ public:
|
|||||||
|
|
||||||
virtual class btConvexHullShape* createConvexHullShape();
|
virtual class btConvexHullShape* createConvexHullShape();
|
||||||
virtual class btCompoundShape* createCompoundShape();
|
virtual class btCompoundShape* createCompoundShape();
|
||||||
virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape);
|
virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScalingbtBvhTriangleMeshShape);
|
||||||
|
|
||||||
virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres);
|
virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres);
|
||||||
|
|
||||||
virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
|
virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
|
||||||
|
|
||||||
@@ -208,25 +202,20 @@ public:
|
|||||||
virtual btTriangleInfoMap* createTriangleInfoMap();
|
virtual btTriangleInfoMap* createTriangleInfoMap();
|
||||||
|
|
||||||
///constraints
|
///constraints
|
||||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
|
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB);
|
||||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
|
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA, const btVector3& pivotInA);
|
||||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false);
|
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
|
||||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false);
|
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false);
|
||||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
|
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame);
|
||||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
|
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA, const btTransform& rbAFrame);
|
||||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
|
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
|
||||||
virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||||
virtual btGeneric6DofSpring2Constraint* createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder );
|
virtual btGeneric6DofSpring2Constraint* createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder);
|
||||||
|
|
||||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||||
virtual btGearConstraint* createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio);
|
virtual btGearConstraint* createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif //BT_WORLD_IMPORTER_H
|
#endif //BT_WORLD_IMPORTER_H
|
||||||
@@ -24,23 +24,20 @@ struct MyLocalCaster
|
|||||||
void* m_ptr;
|
void* m_ptr;
|
||||||
int m_int;
|
int m_int;
|
||||||
MyLocalCaster()
|
MyLocalCaster()
|
||||||
:m_ptr(0)
|
: m_ptr(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
btBulletXmlWorldImporter::btBulletXmlWorldImporter(btDynamicsWorld* world)
|
btBulletXmlWorldImporter::btBulletXmlWorldImporter(btDynamicsWorld* world)
|
||||||
:btWorldImporter(world),
|
: btWorldImporter(world),
|
||||||
m_fileVersion(-1),
|
m_fileVersion(-1),
|
||||||
m_fileOk(false)
|
m_fileOk(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btBulletXmlWorldImporter::~btBulletXmlWorldImporter()
|
btBulletXmlWorldImporter::~btBulletXmlWorldImporter()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -61,19 +58,19 @@ static int get_double_attribute_by_name(const XMLElement* pElement, const char*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int get_int_attribute_by_name(const XMLElement* pElement, const char* attribName,int* value)
|
static int get_int_attribute_by_name(const XMLElement* pElement, const char* attribName, int* value)
|
||||||
{
|
{
|
||||||
if ( !pElement )
|
if (!pElement)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const XMLAttribute* pAttrib=pElement->FirstAttribute();
|
const XMLAttribute* pAttrib = pElement->FirstAttribute();
|
||||||
while (pAttrib)
|
while (pAttrib)
|
||||||
{
|
{
|
||||||
if (!strcmp(pAttrib->Name(),attribName))
|
if (!strcmp(pAttrib->Name(), attribName))
|
||||||
if (pAttrib->QueryIntValue(value)==XML_SUCCESS)
|
if (pAttrib->QueryIntValue(value) == XML_SUCCESS)
|
||||||
return 1;
|
return 1;
|
||||||
// if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
|
// if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
|
||||||
pAttrib=pAttrib->Next();
|
pAttrib = pAttrib->Next();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -82,13 +79,12 @@ void stringToFloatArray(const std::string& string, btAlignedObjectArray<float>&
|
|||||||
{
|
{
|
||||||
btAlignedObjectArray<std::string> pieces;
|
btAlignedObjectArray<std::string> pieces;
|
||||||
|
|
||||||
bullet_utils::split( pieces, string, " ");
|
bullet_utils::split(pieces, string, " ");
|
||||||
for ( int i = 0; i < pieces.size(); ++i)
|
for (int i = 0; i < pieces.size(); ++i)
|
||||||
{
|
{
|
||||||
btAssert(pieces[i]!="");
|
btAssert(pieces[i] != "");
|
||||||
floats.push_back((float)atof(pieces[i].c_str()));
|
floats.push_back((float)atof(pieces[i].c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static btVector3FloatData TextToVector3Data(const char* txt)
|
static btVector3FloatData TextToVector3Data(const char* txt)
|
||||||
@@ -96,7 +92,7 @@ static btVector3FloatData TextToVector3Data(const char* txt)
|
|||||||
btAssert(txt);
|
btAssert(txt);
|
||||||
btAlignedObjectArray<float> floats;
|
btAlignedObjectArray<float> floats;
|
||||||
stringToFloatArray(txt, floats);
|
stringToFloatArray(txt, floats);
|
||||||
btAssert(floats.size()==4);
|
btAssert(floats.size() == 4);
|
||||||
|
|
||||||
btVector3FloatData vec4;
|
btVector3FloatData vec4;
|
||||||
vec4.m_floats[0] = floats[0];
|
vec4.m_floats[0] = floats[0];
|
||||||
@@ -106,145 +102,137 @@ static btVector3FloatData TextToVector3Data(const char* txt)
|
|||||||
return vec4;
|
return vec4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeVector3FloatData(XMLNode* pParent,btAlignedObjectArray<btVector3FloatData>& vectors)
|
void btBulletXmlWorldImporter::deSerializeVector3FloatData(XMLNode* pParent, btAlignedObjectArray<btVector3FloatData>& vectors)
|
||||||
{
|
{
|
||||||
XMLNode* flNode = pParent->FirstChildElement("m_floats");
|
XMLNode* flNode = pParent->FirstChildElement("m_floats");
|
||||||
btAssert(flNode);
|
btAssert(flNode);
|
||||||
while (flNode && flNode->FirstChildElement())
|
while (flNode && flNode->FirstChildElement())
|
||||||
{
|
{
|
||||||
XMLText* pText = flNode->FirstChildElement()->ToText();
|
XMLText* pText = flNode->FirstChildElement()->ToText();
|
||||||
// printf("value = %s\n",pText->Value());
|
// printf("value = %s\n",pText->Value());
|
||||||
btVector3FloatData vec4 = TextToVector3Data(pText->Value());
|
btVector3FloatData vec4 = TextToVector3Data(pText->Value());
|
||||||
vectors.push_back(vec4);
|
vectors.push_back(vec4);
|
||||||
flNode = flNode->NextSibling();
|
flNode = flNode->NextSibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SET_INT_VALUE(xmlnode, targetdata, argname) \
|
#define SET_INT_VALUE(xmlnode, targetdata, argname) \
|
||||||
btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement());\
|
btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()); \
|
||||||
if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement())\
|
if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()) \
|
||||||
(targetdata)->argname= (int)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText());
|
(targetdata)->argname = (int)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText());
|
||||||
|
|
||||||
|
|
||||||
#define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \
|
#define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \
|
||||||
btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement());\
|
btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()); \
|
||||||
if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement())\
|
if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()) \
|
||||||
(targetdata)->argname= (float)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText());
|
(targetdata)->argname = (float)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText());
|
||||||
|
|
||||||
|
|
||||||
#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) \
|
#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) \
|
||||||
{\
|
{ \
|
||||||
XMLNode* node = xmlnode->FirstChildElement(#argname);\
|
XMLNode* node = xmlnode->FirstChildElement(#argname); \
|
||||||
btAssert(node);\
|
btAssert(node); \
|
||||||
if (node)\
|
if (node) \
|
||||||
{\
|
{ \
|
||||||
const char* txt = (node)->ToElement()->GetText();\
|
const char* txt = (node)->ToElement()->GetText(); \
|
||||||
MyLocalCaster cast;\
|
MyLocalCaster cast; \
|
||||||
cast.m_int = (int) atof(txt);\
|
cast.m_int = (int)atof(txt); \
|
||||||
(targetdata).argname= (pointertype)cast.m_ptr;\
|
(targetdata).argname = (pointertype)cast.m_ptr; \
|
||||||
}\
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \
|
#define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \
|
||||||
{\
|
{ \
|
||||||
XMLNode* flNode = xmlnode->FirstChildElement(#argname);\
|
XMLNode* flNode = xmlnode->FirstChildElement(#argname); \
|
||||||
btAssert(flNode);\
|
btAssert(flNode); \
|
||||||
if (flNode && flNode->FirstChildElement())\
|
if (flNode && flNode->FirstChildElement()) \
|
||||||
{\
|
{ \
|
||||||
const char* txt= flNode->FirstChildElement()->ToElement()->GetText();\
|
const char* txt = flNode->FirstChildElement()->ToElement()->GetText(); \
|
||||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
btVector3FloatData vec4 = TextToVector3Data(txt); \
|
||||||
(targetdata)->argname.m_floats[0] = vec4.m_floats[0];\
|
(targetdata)->argname.m_floats[0] = vec4.m_floats[0]; \
|
||||||
(targetdata)->argname.m_floats[1] = vec4.m_floats[1];\
|
(targetdata)->argname.m_floats[1] = vec4.m_floats[1]; \
|
||||||
(targetdata)->argname.m_floats[2] = vec4.m_floats[2];\
|
(targetdata)->argname.m_floats[2] = vec4.m_floats[2]; \
|
||||||
(targetdata)->argname.m_floats[3] = vec4.m_floats[3];\
|
(targetdata)->argname.m_floats[3] = vec4.m_floats[3]; \
|
||||||
}\
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SET_MATRIX33_VALUE(n, targetdata, argname) \
|
#define SET_MATRIX33_VALUE(n, targetdata, argname) \
|
||||||
{\
|
{ \
|
||||||
XMLNode* xmlnode = n->FirstChildElement(#argname);\
|
XMLNode* xmlnode = n->FirstChildElement(#argname); \
|
||||||
btAssert(xmlnode);\
|
btAssert(xmlnode); \
|
||||||
if (xmlnode)\
|
if (xmlnode) \
|
||||||
{\
|
{ \
|
||||||
XMLNode* eleNode = xmlnode->FirstChildElement("m_el");\
|
XMLNode* eleNode = xmlnode->FirstChildElement("m_el"); \
|
||||||
btAssert(eleNode);\
|
btAssert(eleNode); \
|
||||||
if (eleNode&& eleNode->FirstChildElement())\
|
if (eleNode && eleNode->FirstChildElement()) \
|
||||||
{\
|
{ \
|
||||||
const char* txt= eleNode->FirstChildElement()->ToElement()->GetText();\
|
const char* txt = eleNode->FirstChildElement()->ToElement()->GetText(); \
|
||||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
btVector3FloatData vec4 = TextToVector3Data(txt); \
|
||||||
(targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0];\
|
(targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0]; \
|
||||||
(targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1];\
|
(targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1]; \
|
||||||
(targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2];\
|
(targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2]; \
|
||||||
(targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3];\
|
(targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3]; \
|
||||||
\
|
\
|
||||||
XMLNode* n1 = eleNode->FirstChildElement()->NextSibling();\
|
XMLNode* n1 = eleNode->FirstChildElement()->NextSibling(); \
|
||||||
btAssert(n1);\
|
btAssert(n1); \
|
||||||
if (n1)\
|
if (n1) \
|
||||||
{\
|
{ \
|
||||||
const char* txt= n1->ToElement()->GetText();\
|
const char* txt = n1->ToElement()->GetText(); \
|
||||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
btVector3FloatData vec4 = TextToVector3Data(txt); \
|
||||||
(targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0];\
|
(targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0]; \
|
||||||
(targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1];\
|
(targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1]; \
|
||||||
(targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2];\
|
(targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2]; \
|
||||||
(targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3];\
|
(targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3]; \
|
||||||
\
|
\
|
||||||
XMLNode* n2 = n1->NextSibling();\
|
XMLNode* n2 = n1->NextSibling(); \
|
||||||
btAssert(n2);\
|
btAssert(n2); \
|
||||||
if (n2)\
|
if (n2) \
|
||||||
{\
|
{ \
|
||||||
const char* txt= n2->ToElement()->GetText();\
|
const char* txt = n2->ToElement()->GetText(); \
|
||||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
btVector3FloatData vec4 = TextToVector3Data(txt); \
|
||||||
(targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0];\
|
(targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0]; \
|
||||||
(targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1];\
|
(targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1]; \
|
||||||
(targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2];\
|
(targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2]; \
|
||||||
(targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3];\
|
(targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3]; \
|
||||||
}\
|
} \
|
||||||
}\
|
} \
|
||||||
}\
|
} \
|
||||||
}\
|
} \
|
||||||
}\
|
}
|
||||||
|
|
||||||
#define SET_TRANSFORM_VALUE(n, targetdata, argname) \
|
#define SET_TRANSFORM_VALUE(n, targetdata, argname) \
|
||||||
{\
|
{ \
|
||||||
XMLNode* trNode = n->FirstChildElement(#argname);\
|
XMLNode* trNode = n->FirstChildElement(#argname); \
|
||||||
btAssert(trNode);\
|
btAssert(trNode); \
|
||||||
if (trNode)\
|
if (trNode) \
|
||||||
{\
|
{ \
|
||||||
SET_VECTOR4_VALUE(trNode,&(targetdata)->argname,m_origin)\
|
SET_VECTOR4_VALUE(trNode, &(targetdata)->argname, m_origin) \
|
||||||
SET_MATRIX33_VALUE(trNode, &(targetdata)->argname,m_basis)\
|
SET_MATRIX33_VALUE(trNode, &(targetdata)->argname, m_basis) \
|
||||||
}\
|
} \
|
||||||
}\
|
}
|
||||||
|
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeCollisionShapeData(XMLNode* pParent, btCollisionShapeData* colShapeData)
|
void btBulletXmlWorldImporter::deSerializeCollisionShapeData(XMLNode* pParent, btCollisionShapeData* colShapeData)
|
||||||
{
|
{
|
||||||
SET_INT_VALUE(pParent,colShapeData,m_shapeType)
|
SET_INT_VALUE(pParent, colShapeData, m_shapeType)
|
||||||
colShapeData->m_name = 0;
|
colShapeData->m_name = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
btConvexHullShapeData* convexHullData = (btConvexHullShapeData*)btAlignedAlloc(sizeof(btConvexHullShapeData), 16);
|
btConvexHullShapeData* convexHullData = (btConvexHullShapeData*)btAlignedAlloc(sizeof(btConvexHullShapeData), 16);
|
||||||
|
|
||||||
XMLNode* xmlConvexInt = pParent->FirstChildElement("m_convexInternalShapeData");
|
XMLNode* xmlConvexInt = pParent->FirstChildElement("m_convexInternalShapeData");
|
||||||
btAssert(xmlConvexInt);
|
btAssert(xmlConvexInt);
|
||||||
|
|
||||||
XMLNode* xmlColShape = xmlConvexInt ->FirstChildElement("m_collisionShapeData");
|
XMLNode* xmlColShape = xmlConvexInt->FirstChildElement("m_collisionShapeData");
|
||||||
btAssert(xmlColShape);
|
btAssert(xmlColShape);
|
||||||
|
|
||||||
deSerializeCollisionShapeData(xmlColShape,&convexHullData->m_convexInternalShapeData.m_collisionShapeData);
|
deSerializeCollisionShapeData(xmlColShape, &convexHullData->m_convexInternalShapeData.m_collisionShapeData);
|
||||||
|
|
||||||
SET_FLOAT_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_collisionMargin)
|
SET_FLOAT_VALUE(xmlConvexInt, &convexHullData->m_convexInternalShapeData, m_collisionMargin)
|
||||||
SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_localScaling)
|
SET_VECTOR4_VALUE(xmlConvexInt, &convexHullData->m_convexInternalShapeData, m_localScaling)
|
||||||
SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_implicitShapeDimensions)
|
SET_VECTOR4_VALUE(xmlConvexInt, &convexHullData->m_convexInternalShapeData, m_implicitShapeDimensions)
|
||||||
|
|
||||||
//convexHullData->m_unscaledPointsFloatPtr
|
//convexHullData->m_unscaledPointsFloatPtr
|
||||||
//#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype)
|
//#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype)
|
||||||
@@ -256,23 +244,23 @@ void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(XMLNode* pParent)
|
|||||||
{
|
{
|
||||||
const char* txt = (node)->ToElement()->GetText();
|
const char* txt = (node)->ToElement()->GetText();
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
cast.m_int = (int) atof(txt);
|
cast.m_int = (int)atof(txt);
|
||||||
(*convexHullData).m_unscaledPointsFloatPtr= (btVector3FloatData*) cast.m_ptr;
|
(*convexHullData).m_unscaledPointsFloatPtr = (btVector3FloatData*)cast.m_ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsFloatPtr,btVector3FloatData*);
|
SET_POINTER_VALUE(pParent, *convexHullData, m_unscaledPointsFloatPtr, btVector3FloatData*);
|
||||||
SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsDoublePtr,btVector3DoubleData*);
|
SET_POINTER_VALUE(pParent, *convexHullData, m_unscaledPointsDoublePtr, btVector3DoubleData*);
|
||||||
SET_INT_VALUE(pParent,convexHullData,m_numUnscaledPoints);
|
SET_INT_VALUE(pParent, convexHullData, m_numUnscaledPoints);
|
||||||
|
|
||||||
m_collisionShapeData.push_back((btCollisionShapeData*)convexHullData);
|
m_collisionShapeData.push_back((btCollisionShapeData*)convexHullData);
|
||||||
m_pointerLookup.insert(cast.m_ptr,convexHullData);
|
m_pointerLookup.insert(cast.m_ptr, convexHullData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
int numChildren = 0;
|
int numChildren = 0;
|
||||||
btAlignedObjectArray<btCompoundShapeChildData>* compoundChildArrayPtr = new btAlignedObjectArray<btCompoundShapeChildData>;
|
btAlignedObjectArray<btCompoundShapeChildData>* compoundChildArrayPtr = new btAlignedObjectArray<btCompoundShapeChildData>;
|
||||||
@@ -282,17 +270,17 @@ void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParen
|
|||||||
XMLNode* marginNode = pParent->FirstChildElement("m_childMargin");
|
XMLNode* marginNode = pParent->FirstChildElement("m_childMargin");
|
||||||
XMLNode* childTypeNode = pParent->FirstChildElement("m_childShapeType");
|
XMLNode* childTypeNode = pParent->FirstChildElement("m_childShapeType");
|
||||||
|
|
||||||
int i=0;
|
int i = 0;
|
||||||
while (transNode && colShapeNode && marginNode && childTypeNode)
|
while (transNode && colShapeNode && marginNode && childTypeNode)
|
||||||
{
|
{
|
||||||
compoundChildArrayPtr->expandNonInitializing();
|
compoundChildArrayPtr->expandNonInitializing();
|
||||||
SET_VECTOR4_VALUE (transNode,&compoundChildArrayPtr->at(i).m_transform,m_origin)
|
SET_VECTOR4_VALUE(transNode, &compoundChildArrayPtr->at(i).m_transform, m_origin)
|
||||||
SET_MATRIX33_VALUE(transNode,&compoundChildArrayPtr->at(i).m_transform,m_basis)
|
SET_MATRIX33_VALUE(transNode, &compoundChildArrayPtr->at(i).m_transform, m_basis)
|
||||||
|
|
||||||
const char* txt = (colShapeNode)->ToElement()->GetText();
|
const char* txt = (colShapeNode)->ToElement()->GetText();
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
cast.m_int = (int) atof(txt);
|
cast.m_int = (int)atof(txt);
|
||||||
compoundChildArrayPtr->at(i).m_childShape = (btCollisionShapeData*) cast.m_ptr;
|
compoundChildArrayPtr->at(i).m_childShape = (btCollisionShapeData*)cast.m_ptr;
|
||||||
|
|
||||||
btAssert(childTypeNode->ToElement());
|
btAssert(childTypeNode->ToElement());
|
||||||
if (childTypeNode->ToElement())
|
if (childTypeNode->ToElement())
|
||||||
@@ -314,7 +302,6 @@ void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParen
|
|||||||
}
|
}
|
||||||
|
|
||||||
numChildren = i;
|
numChildren = i;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btAssert(numChildren);
|
btAssert(numChildren);
|
||||||
@@ -322,66 +309,62 @@ void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParen
|
|||||||
{
|
{
|
||||||
m_compoundShapeChildDataArrays.push_back(compoundChildArrayPtr);
|
m_compoundShapeChildDataArrays.push_back(compoundChildArrayPtr);
|
||||||
btCompoundShapeChildData* cd = &compoundChildArrayPtr->at(0);
|
btCompoundShapeChildData* cd = &compoundChildArrayPtr->at(0);
|
||||||
m_pointerLookup.insert(cast.m_ptr,cd);
|
m_pointerLookup.insert(cast.m_ptr, cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeCompoundShapeData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeCompoundShapeData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
btCompoundShapeData* compoundData = (btCompoundShapeData*) btAlignedAlloc(sizeof(btCompoundShapeData),16);
|
btCompoundShapeData* compoundData = (btCompoundShapeData*)btAlignedAlloc(sizeof(btCompoundShapeData), 16);
|
||||||
|
|
||||||
XMLNode* xmlColShape = pParent ->FirstChildElement("m_collisionShapeData");
|
XMLNode* xmlColShape = pParent->FirstChildElement("m_collisionShapeData");
|
||||||
btAssert(xmlColShape);
|
btAssert(xmlColShape);
|
||||||
deSerializeCollisionShapeData(xmlColShape,&compoundData->m_collisionShapeData);
|
deSerializeCollisionShapeData(xmlColShape, &compoundData->m_collisionShapeData);
|
||||||
|
|
||||||
SET_INT_VALUE(pParent, compoundData,m_numChildShapes);
|
SET_INT_VALUE(pParent, compoundData, m_numChildShapes);
|
||||||
|
|
||||||
XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData");
|
XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData");
|
||||||
btAssert(xmlShapeData );
|
btAssert(xmlShapeData);
|
||||||
|
|
||||||
{
|
{
|
||||||
XMLNode* node = pParent->FirstChildElement("m_childShapePtr");\
|
XMLNode* node = pParent->FirstChildElement("m_childShapePtr");
|
||||||
btAssert(node);
|
btAssert(node);
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
const char* txt = (node)->ToElement()->GetText();
|
const char* txt = (node)->ToElement()->GetText();
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
cast.m_int = (int) atof(txt);
|
cast.m_int = (int)atof(txt);
|
||||||
compoundData->m_childShapePtr = (btCompoundShapeChildData*) cast.m_ptr;
|
compoundData->m_childShapePtr = (btCompoundShapeChildData*)cast.m_ptr;
|
||||||
node = node->NextSiblingElement("m_childShapePtr");
|
node = node->NextSiblingElement("m_childShapePtr");
|
||||||
}
|
}
|
||||||
//SET_POINTER_VALUE(xmlColShape, *compoundData,m_childShapePtr,btCompoundShapeChildData*);
|
//SET_POINTER_VALUE(xmlColShape, *compoundData,m_childShapePtr,btCompoundShapeChildData*);
|
||||||
|
|
||||||
}
|
}
|
||||||
SET_FLOAT_VALUE(pParent, compoundData,m_collisionMargin);
|
SET_FLOAT_VALUE(pParent, compoundData, m_collisionMargin);
|
||||||
|
|
||||||
m_collisionShapeData.push_back((btCollisionShapeData*)compoundData);
|
m_collisionShapeData.push_back((btCollisionShapeData*)compoundData);
|
||||||
m_pointerLookup.insert(cast.m_ptr,compoundData);
|
m_pointerLookup.insert(cast.m_ptr, compoundData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeStaticPlaneShapeData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeStaticPlaneShapeData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) btAlignedAlloc(sizeof(btStaticPlaneShapeData),16);
|
btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)btAlignedAlloc(sizeof(btStaticPlaneShapeData), 16);
|
||||||
|
|
||||||
XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData");
|
XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData");
|
||||||
btAssert(xmlShapeData );
|
btAssert(xmlShapeData);
|
||||||
deSerializeCollisionShapeData(xmlShapeData,&planeData->m_collisionShapeData);
|
deSerializeCollisionShapeData(xmlShapeData, &planeData->m_collisionShapeData);
|
||||||
|
|
||||||
SET_VECTOR4_VALUE(pParent, planeData,m_localScaling);
|
SET_VECTOR4_VALUE(pParent, planeData, m_localScaling);
|
||||||
SET_VECTOR4_VALUE(pParent, planeData,m_planeNormal);
|
SET_VECTOR4_VALUE(pParent, planeData, m_planeNormal);
|
||||||
SET_FLOAT_VALUE(pParent, planeData,m_planeConstant);
|
SET_FLOAT_VALUE(pParent, planeData, m_planeConstant);
|
||||||
|
|
||||||
m_collisionShapeData.push_back((btCollisionShapeData*)planeData);
|
m_collisionShapeData.push_back((btCollisionShapeData*)planeData);
|
||||||
m_pointerLookup.insert(cast.m_ptr,planeData);
|
m_pointerLookup.insert(cast.m_ptr, planeData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(XMLNode* pParent)
|
||||||
@@ -397,25 +380,22 @@ void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(XMLNode* pParent)
|
|||||||
void btBulletXmlWorldImporter::deSerializeConvexInternalShapeData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeConvexInternalShapeData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
|
btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*)btAlignedAlloc(sizeof(btConvexInternalShapeData), 16);
|
||||||
btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*) btAlignedAlloc(sizeof(btConvexInternalShapeData),16);
|
memset(convexShape, 0, sizeof(btConvexInternalShapeData));
|
||||||
memset(convexShape,0,sizeof(btConvexInternalShapeData));
|
|
||||||
|
|
||||||
XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData");
|
XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData");
|
||||||
btAssert(xmlShapeData );
|
btAssert(xmlShapeData);
|
||||||
|
|
||||||
deSerializeCollisionShapeData(xmlShapeData,&convexShape->m_collisionShapeData);
|
deSerializeCollisionShapeData(xmlShapeData, &convexShape->m_collisionShapeData);
|
||||||
|
|
||||||
|
SET_FLOAT_VALUE(pParent, convexShape, m_collisionMargin)
|
||||||
SET_FLOAT_VALUE(pParent,convexShape,m_collisionMargin)
|
SET_VECTOR4_VALUE(pParent, convexShape, m_localScaling)
|
||||||
SET_VECTOR4_VALUE(pParent,convexShape,m_localScaling)
|
SET_VECTOR4_VALUE(pParent, convexShape, m_implicitShapeDimensions)
|
||||||
SET_VECTOR4_VALUE(pParent,convexShape,m_implicitShapeDimensions)
|
|
||||||
|
|
||||||
m_collisionShapeData.push_back((btCollisionShapeData*)convexShape);
|
m_collisionShapeData.push_back((btCollisionShapeData*)convexShape);
|
||||||
m_pointerLookup.insert(cast.m_ptr,convexShape);
|
m_pointerLookup.insert(cast.m_ptr, convexShape);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -433,115 +413,110 @@ enum btTypedConstraintType
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeGeneric6DofConstraintData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeGeneric6DofConstraintData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
btGeneric6DofConstraintData2* dof6Data = (btGeneric6DofConstraintData2*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData2),16);
|
|
||||||
|
|
||||||
|
btGeneric6DofConstraintData2* dof6Data = (btGeneric6DofConstraintData2*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData2), 16);
|
||||||
|
|
||||||
XMLNode* n = pParent->FirstChildElement("m_typeConstraintData");
|
XMLNode* n = pParent->FirstChildElement("m_typeConstraintData");
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbA,btRigidBodyData*);
|
SET_POINTER_VALUE(n, dof6Data->m_typeConstraintData, m_rbA, btRigidBodyData*);
|
||||||
SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbB,btRigidBodyData*);
|
SET_POINTER_VALUE(n, dof6Data->m_typeConstraintData, m_rbB, btRigidBodyData*);
|
||||||
dof6Data->m_typeConstraintData.m_name = 0;//tbd
|
dof6Data->m_typeConstraintData.m_name = 0; //tbd
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_objectType);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_objectType);
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintType);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_userConstraintType);
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintId);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_userConstraintId);
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_needsFeedback);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_needsFeedback);
|
||||||
SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_appliedImpulse);
|
SET_FLOAT_VALUE(n, &dof6Data->m_typeConstraintData, m_appliedImpulse);
|
||||||
SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_dbgDrawSize);
|
SET_FLOAT_VALUE(n, &dof6Data->m_typeConstraintData, m_dbgDrawSize);
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_disableCollisionsBetweenLinkedBodies);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_disableCollisionsBetweenLinkedBodies);
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_overrideNumSolverIterations);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_overrideNumSolverIterations);
|
||||||
SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_breakingImpulseThreshold);
|
SET_FLOAT_VALUE(n, &dof6Data->m_typeConstraintData, m_breakingImpulseThreshold);
|
||||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_isEnabled);
|
SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_isEnabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbAFrame);
|
SET_TRANSFORM_VALUE(pParent, dof6Data, m_rbAFrame);
|
||||||
SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbBFrame);
|
SET_TRANSFORM_VALUE(pParent, dof6Data, m_rbBFrame);
|
||||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_linearUpperLimit);
|
SET_VECTOR4_VALUE(pParent, dof6Data, m_linearUpperLimit);
|
||||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_linearLowerLimit);
|
SET_VECTOR4_VALUE(pParent, dof6Data, m_linearLowerLimit);
|
||||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_angularUpperLimit);
|
SET_VECTOR4_VALUE(pParent, dof6Data, m_angularUpperLimit);
|
||||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_angularLowerLimit);
|
SET_VECTOR4_VALUE(pParent, dof6Data, m_angularLowerLimit);
|
||||||
SET_INT_VALUE(pParent, dof6Data,m_useLinearReferenceFrameA);
|
SET_INT_VALUE(pParent, dof6Data, m_useLinearReferenceFrameA);
|
||||||
SET_INT_VALUE(pParent, dof6Data,m_useOffsetForConstraintFrame);
|
SET_INT_VALUE(pParent, dof6Data, m_useOffsetForConstraintFrame);
|
||||||
|
|
||||||
m_constraintData.push_back((btTypedConstraintData2*)dof6Data);
|
m_constraintData.push_back((btTypedConstraintData2*)dof6Data);
|
||||||
m_pointerLookup.insert(cast.m_ptr,dof6Data);
|
m_pointerLookup.insert(cast.m_ptr, dof6Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::deSerializeRigidBodyFloatData(XMLNode* pParent)
|
void btBulletXmlWorldImporter::deSerializeRigidBodyFloatData(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
|
|
||||||
if (!get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int))
|
if (!get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int))
|
||||||
{
|
{
|
||||||
m_fileOk = false;
|
m_fileOk = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
btRigidBodyData* rbData = (btRigidBodyData*)btAlignedAlloc(sizeof(btRigidBodyData),16);
|
btRigidBodyData* rbData = (btRigidBodyData*)btAlignedAlloc(sizeof(btRigidBodyData), 16);
|
||||||
|
|
||||||
XMLNode* n = pParent->FirstChildElement("m_collisionObjectData");
|
XMLNode* n = pParent->FirstChildElement("m_collisionObjectData");
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
SET_POINTER_VALUE(n,rbData->m_collisionObjectData,m_collisionShape, void*);
|
SET_POINTER_VALUE(n, rbData->m_collisionObjectData, m_collisionShape, void*);
|
||||||
SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_worldTransform);
|
SET_TRANSFORM_VALUE(n, &rbData->m_collisionObjectData, m_worldTransform);
|
||||||
SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_interpolationWorldTransform);
|
SET_TRANSFORM_VALUE(n, &rbData->m_collisionObjectData, m_interpolationWorldTransform);
|
||||||
SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationLinearVelocity)
|
SET_VECTOR4_VALUE(n, &rbData->m_collisionObjectData, m_interpolationLinearVelocity)
|
||||||
SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationAngularVelocity)
|
SET_VECTOR4_VALUE(n, &rbData->m_collisionObjectData, m_interpolationAngularVelocity)
|
||||||
SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_anisotropicFriction)
|
SET_VECTOR4_VALUE(n, &rbData->m_collisionObjectData, m_anisotropicFriction)
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_contactProcessingThreshold);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_contactProcessingThreshold);
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_deactivationTime);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_deactivationTime);
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_friction);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_friction);
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_restitution);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_restitution);
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_hitFraction);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_hitFraction);
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdSweptSphereRadius);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_ccdSweptSphereRadius);
|
||||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdMotionThreshold);
|
SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_ccdMotionThreshold);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_hasAnisotropicFriction);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_hasAnisotropicFriction);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_collisionFlags);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_collisionFlags);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_islandTag1);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_islandTag1);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_companionId);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_companionId);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_activationState1);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_activationState1);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_internalType);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_internalType);
|
||||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_checkCollideWith);
|
SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_checkCollideWith);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity);
|
// SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity);
|
||||||
|
|
||||||
SET_MATRIX33_VALUE(pParent,rbData,m_invInertiaTensorWorld);
|
SET_MATRIX33_VALUE(pParent, rbData, m_invInertiaTensorWorld);
|
||||||
|
|
||||||
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_angularVelocity)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_angularFactor)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_linearFactor)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_gravity)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_gravity_acceleration )
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_invInertiaLocal)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_totalTorque)
|
|
||||||
SET_VECTOR4_VALUE(pParent,rbData,m_totalForce)
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_inverseMass);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_linearDamping);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_angularDamping);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalDampingFactor);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalLinearDampingThresholdSqr);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingThresholdSqr);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingFactor);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_angularSleepingThreshold);
|
|
||||||
SET_FLOAT_VALUE(pParent,rbData,m_linearSleepingThreshold);
|
|
||||||
SET_INT_VALUE(pParent,rbData,m_additionalDamping);
|
|
||||||
|
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_linearVelocity)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_angularVelocity)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_angularFactor)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_linearFactor)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_gravity)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_gravity_acceleration)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_invInertiaLocal)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_totalTorque)
|
||||||
|
SET_VECTOR4_VALUE(pParent, rbData, m_totalForce)
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_inverseMass);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_linearDamping);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_angularDamping);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_additionalDampingFactor);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_additionalLinearDampingThresholdSqr);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_additionalAngularDampingThresholdSqr);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_additionalAngularDampingFactor);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_angularSleepingThreshold);
|
||||||
|
SET_FLOAT_VALUE(pParent, rbData, m_linearSleepingThreshold);
|
||||||
|
SET_INT_VALUE(pParent, rbData, m_additionalDamping);
|
||||||
|
|
||||||
m_rigidBodyData.push_back(rbData);
|
m_rigidBodyData.push_back(rbData);
|
||||||
m_pointerLookup.insert(cast.m_ptr,rbData);
|
m_pointerLookup.insert(cast.m_ptr, rbData);
|
||||||
|
|
||||||
// rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt);
|
// rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -599,26 +574,23 @@ void btBulletXmlWorldImporter::fixupConstraintData(btTypedConstraintData2* tcd)
|
|||||||
{
|
{
|
||||||
btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbA);
|
btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbA);
|
||||||
btAssert(ptrptr);
|
btAssert(ptrptr);
|
||||||
tcd->m_rbA = ptrptr? *ptrptr : 0;
|
tcd->m_rbA = ptrptr ? *ptrptr : 0;
|
||||||
}
|
}
|
||||||
if (tcd->m_rbB)
|
if (tcd->m_rbB)
|
||||||
{
|
{
|
||||||
btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbB);
|
btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbB);
|
||||||
btAssert(ptrptr);
|
btAssert(ptrptr);
|
||||||
tcd->m_rbB = ptrptr? *ptrptr : 0;
|
tcd->m_rbB = ptrptr ? *ptrptr : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData)
|
void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (shapeData->m_shapeType)
|
switch (shapeData->m_shapeType)
|
||||||
{
|
{
|
||||||
|
|
||||||
case COMPOUND_SHAPE_PROXYTYPE:
|
case COMPOUND_SHAPE_PROXYTYPE:
|
||||||
{
|
{
|
||||||
btCompoundShapeData* compound = (btCompoundShapeData*) shapeData;
|
btCompoundShapeData* compound = (btCompoundShapeData*)shapeData;
|
||||||
|
|
||||||
void** cdptr = m_pointerLookup.find((void*)compound->m_childShapePtr);
|
void** cdptr = m_pointerLookup.find((void*)compound->m_childShapePtr);
|
||||||
btCompoundShapeChildData** c = (btCompoundShapeChildData**)cdptr;
|
btCompoundShapeChildData** c = (btCompoundShapeChildData**)cdptr;
|
||||||
@@ -626,7 +598,8 @@ void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData*
|
|||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
compound->m_childShapePtr = *c;
|
compound->m_childShapePtr = *c;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
compound->m_childShapePtr = 0;
|
compound->m_childShapePtr = 0;
|
||||||
}
|
}
|
||||||
@@ -641,7 +614,8 @@ void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData*
|
|||||||
if (ptrptr)
|
if (ptrptr)
|
||||||
{
|
{
|
||||||
convexData->m_unscaledPointsFloatPtr = *ptrptr;
|
convexData->m_unscaledPointsFloatPtr = *ptrptr;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
convexData->m_unscaledPointsFloatPtr = 0;
|
convexData->m_unscaledPointsFloatPtr = 0;
|
||||||
}
|
}
|
||||||
@@ -661,76 +635,74 @@ void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pParent)
|
void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
int numChildren = 0;
|
int numChildren = 0;
|
||||||
btAssert(pParent);
|
btAssert(pParent);
|
||||||
if (pParent)
|
if (pParent)
|
||||||
{
|
{
|
||||||
XMLNode*pChild;
|
XMLNode* pChild;
|
||||||
for ( pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling(), numChildren++)
|
for (pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling(), numChildren++)
|
||||||
{
|
{
|
||||||
// printf("child Name=%s\n", pChild->Value());
|
// printf("child Name=%s\n", pChild->Value());
|
||||||
if (!strcmp(pChild->Value(),"btVector3FloatData"))
|
if (!strcmp(pChild->Value(), "btVector3FloatData"))
|
||||||
{
|
{
|
||||||
MyLocalCaster cast;
|
MyLocalCaster cast;
|
||||||
get_int_attribute_by_name(pChild->ToElement(),"pointer",&cast.m_int);
|
get_int_attribute_by_name(pChild->ToElement(), "pointer", &cast.m_int);
|
||||||
|
|
||||||
btAlignedObjectArray<btVector3FloatData> v;
|
btAlignedObjectArray<btVector3FloatData> v;
|
||||||
deSerializeVector3FloatData(pChild,v);
|
deSerializeVector3FloatData(pChild, v);
|
||||||
int numVectors = v.size();
|
int numVectors = v.size();
|
||||||
btVector3FloatData* vectors= (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*numVectors,16);
|
btVector3FloatData* vectors = (btVector3FloatData*)btAlignedAlloc(sizeof(btVector3FloatData) * numVectors, 16);
|
||||||
for (int i=0;i<numVectors;i++)
|
for (int i = 0; i < numVectors; i++)
|
||||||
vectors[i] = v[i];
|
vectors[i] = v[i];
|
||||||
m_floatVertexArrays.push_back(vectors);
|
m_floatVertexArrays.push_back(vectors);
|
||||||
m_pointerLookup.insert(cast.m_ptr,vectors);
|
m_pointerLookup.insert(cast.m_ptr, vectors);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(pChild->Value(),"btGeneric6DofConstraintData"))
|
if (!strcmp(pChild->Value(), "btGeneric6DofConstraintData"))
|
||||||
{
|
{
|
||||||
deSerializeGeneric6DofConstraintData(pChild);
|
deSerializeGeneric6DofConstraintData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(pChild->Value(),"btStaticPlaneShapeData"))
|
if (!strcmp(pChild->Value(), "btStaticPlaneShapeData"))
|
||||||
{
|
{
|
||||||
deSerializeStaticPlaneShapeData(pChild);
|
deSerializeStaticPlaneShapeData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(pChild->Value(),"btCompoundShapeData"))
|
if (!strcmp(pChild->Value(), "btCompoundShapeData"))
|
||||||
{
|
{
|
||||||
deSerializeCompoundShapeData(pChild);
|
deSerializeCompoundShapeData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(pChild->Value(),"btCompoundShapeChildData"))
|
if (!strcmp(pChild->Value(), "btCompoundShapeChildData"))
|
||||||
{
|
{
|
||||||
deSerializeCompoundShapeChildData(pChild);
|
deSerializeCompoundShapeChildData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(pChild->Value(),"btConvexHullShapeData"))
|
if (!strcmp(pChild->Value(), "btConvexHullShapeData"))
|
||||||
{
|
{
|
||||||
deSerializeConvexHullShapeData(pChild);
|
deSerializeConvexHullShapeData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(pChild->Value(),"btDynamicsWorldFloatData"))
|
if (!strcmp(pChild->Value(), "btDynamicsWorldFloatData"))
|
||||||
{
|
{
|
||||||
deSerializeDynamicsWorldData(pChild);
|
deSerializeDynamicsWorldData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(pChild->Value(), "btConvexInternalShapeData"))
|
||||||
if (!strcmp(pChild->Value(),"btConvexInternalShapeData"))
|
|
||||||
{
|
{
|
||||||
deSerializeConvexInternalShapeData(pChild);
|
deSerializeConvexInternalShapeData(pChild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(pChild->Value(),"btRigidBodyFloatData"))
|
if (!strcmp(pChild->Value(), "btRigidBodyFloatData"))
|
||||||
{
|
{
|
||||||
deSerializeRigidBodyFloatData(pChild);
|
deSerializeRigidBodyFloatData(pChild);
|
||||||
continue;
|
continue;
|
||||||
@@ -745,10 +717,10 @@ void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pPare
|
|||||||
///fixup pointers in various places, in the right order
|
///fixup pointers in various places, in the right order
|
||||||
|
|
||||||
//fixup compoundshape child data
|
//fixup compoundshape child data
|
||||||
for (int i=0;i<m_compoundShapeChildDataArrays.size();i++)
|
for (int i = 0; i < m_compoundShapeChildDataArrays.size(); i++)
|
||||||
{
|
{
|
||||||
btAlignedObjectArray<btCompoundShapeChildData>* childDataArray = m_compoundShapeChildDataArrays[i];
|
btAlignedObjectArray<btCompoundShapeChildData>* childDataArray = m_compoundShapeChildDataArrays[i];
|
||||||
for (int c=0;c<childDataArray->size();c++)
|
for (int c = 0; c < childDataArray->size(); c++)
|
||||||
{
|
{
|
||||||
btCompoundShapeChildData* childData = &childDataArray->at(c);
|
btCompoundShapeChildData* childData = &childDataArray->at(c);
|
||||||
btCollisionShapeData** ptrptr = (btCollisionShapeData**)m_pointerLookup[childData->m_childShape];
|
btCollisionShapeData** ptrptr = (btCollisionShapeData**)m_pointerLookup[childData->m_childShape];
|
||||||
@@ -760,15 +732,14 @@ void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pPare
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<this->m_collisionShapeData.size();i++)
|
for (int i = 0; i < this->m_collisionShapeData.size(); i++)
|
||||||
{
|
{
|
||||||
btCollisionShapeData* shapeData = m_collisionShapeData[i];
|
btCollisionShapeData* shapeData = m_collisionShapeData[i];
|
||||||
fixupCollisionDataPointers(shapeData);
|
fixupCollisionDataPointers(shapeData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///now fixup pointers
|
///now fixup pointers
|
||||||
for (int i=0;i<m_rigidBodyData.size();i++)
|
for (int i = 0; i < m_rigidBodyData.size(); i++)
|
||||||
{
|
{
|
||||||
btRigidBodyData* rbData = m_rigidBodyData[i];
|
btRigidBodyData* rbData = m_rigidBodyData[i];
|
||||||
|
|
||||||
@@ -776,42 +747,39 @@ void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pPare
|
|||||||
//btAssert(ptrptr);
|
//btAssert(ptrptr);
|
||||||
rbData->m_collisionObjectData.m_broadphaseHandle = 0;
|
rbData->m_collisionObjectData.m_broadphaseHandle = 0;
|
||||||
rbData->m_collisionObjectData.m_rootCollisionShape = 0;
|
rbData->m_collisionObjectData.m_rootCollisionShape = 0;
|
||||||
rbData->m_collisionObjectData.m_name = 0;//tbd
|
rbData->m_collisionObjectData.m_name = 0; //tbd
|
||||||
if (ptrptr)
|
if (ptrptr)
|
||||||
{
|
{
|
||||||
rbData->m_collisionObjectData.m_collisionShape = *ptrptr;
|
rbData->m_collisionObjectData.m_collisionShape = *ptrptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m_constraintData.size(); i++)
|
||||||
|
|
||||||
for (int i=0;i<m_constraintData.size();i++)
|
|
||||||
{
|
{
|
||||||
btTypedConstraintData2* tcd = m_constraintData[i];
|
btTypedConstraintData2* tcd = m_constraintData[i];
|
||||||
fixupConstraintData(tcd);
|
fixupConstraintData(tcd);
|
||||||
|
|
||||||
}
|
}
|
||||||
///=================================================================
|
///=================================================================
|
||||||
///convert data into Bullet data in the right order
|
///convert data into Bullet data in the right order
|
||||||
|
|
||||||
///convert collision shapes
|
///convert collision shapes
|
||||||
for (int i=0;i<this->m_collisionShapeData.size();i++)
|
for (int i = 0; i < this->m_collisionShapeData.size(); i++)
|
||||||
{
|
{
|
||||||
btCollisionShapeData* shapeData = m_collisionShapeData[i];
|
btCollisionShapeData* shapeData = m_collisionShapeData[i];
|
||||||
btCollisionShape* shape = convertCollisionShape(shapeData);
|
btCollisionShape* shape = convertCollisionShape(shapeData);
|
||||||
if (shape)
|
if (shape)
|
||||||
{
|
{
|
||||||
m_shapeMap.insert(shapeData,shape);
|
m_shapeMap.insert(shapeData, shape);
|
||||||
}
|
}
|
||||||
if (shape&& shapeData->m_name)
|
if (shape && shapeData->m_name)
|
||||||
{
|
{
|
||||||
char* newname = duplicateName(shapeData->m_name);
|
char* newname = duplicateName(shapeData->m_name);
|
||||||
m_objectNameMap.insert(shape,newname);
|
m_objectNameMap.insert(shape, newname);
|
||||||
m_nameShapeMap.insert(newname,shape);
|
m_nameShapeMap.insert(newname, shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<m_rigidBodyData.size();i++)
|
for (int i = 0; i < m_rigidBodyData.size(); i++)
|
||||||
{
|
{
|
||||||
#ifdef BT_USE_DOUBLE_PRECISION
|
#ifdef BT_USE_DOUBLE_PRECISION
|
||||||
convertRigidBodyDouble(m_rigidBodyData[i]);
|
convertRigidBodyDouble(m_rigidBodyData[i]);
|
||||||
@@ -820,10 +788,10 @@ void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pPare
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<m_constraintData.size();i++)
|
for (int i = 0; i < m_constraintData.size(); i++)
|
||||||
{
|
{
|
||||||
btTypedConstraintData2* tcd = m_constraintData[i];
|
btTypedConstraintData2* tcd = m_constraintData[i];
|
||||||
// bool isDoublePrecision = false;
|
// bool isDoublePrecision = false;
|
||||||
btRigidBody* rbA = 0;
|
btRigidBody* rbA = 0;
|
||||||
btRigidBody* rbB = 0;
|
btRigidBody* rbB = 0;
|
||||||
{
|
{
|
||||||
@@ -842,62 +810,53 @@ void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pPare
|
|||||||
}
|
}
|
||||||
if (rbA || rbB)
|
if (rbA || rbB)
|
||||||
{
|
{
|
||||||
btAssert(0);//todo
|
btAssert(0); //todo
|
||||||
//convertConstraint(tcd,rbA,rbB,isDoublePrecision, m_fileVersion);
|
//convertConstraint(tcd,rbA,rbB,isDoublePrecision, m_fileVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void btBulletXmlWorldImporter::auto_serialize(XMLNode* pParent)
|
void btBulletXmlWorldImporter::auto_serialize(XMLNode* pParent)
|
||||||
{
|
{
|
||||||
// XMLElement* root = pParent->FirstChildElement("bullet_physics");
|
// XMLElement* root = pParent->FirstChildElement("bullet_physics");
|
||||||
if (pParent)
|
if (pParent)
|
||||||
{
|
{
|
||||||
XMLNode*pChild;
|
XMLNode* pChild;
|
||||||
for ( pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling())
|
for (pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling())
|
||||||
{
|
{
|
||||||
//if (pChild->Type()==XMLNode::TINYXML_ELEMENT)
|
//if (pChild->Type()==XMLNode::TINYXML_ELEMENT)
|
||||||
{
|
{
|
||||||
// printf("root Name=%s\n", pChild->Value());
|
// printf("root Name=%s\n", pChild->Value());
|
||||||
auto_serialize_root_level_children(pChild);
|
auto_serialize_root_level_children(pChild);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
printf("ERROR: no bullet_physics element\n");
|
printf("ERROR: no bullet_physics element\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool btBulletXmlWorldImporter::loadFile(const char* fileName)
|
bool btBulletXmlWorldImporter::loadFile(const char* fileName)
|
||||||
{
|
{
|
||||||
XMLDocument doc;
|
XMLDocument doc;
|
||||||
|
|
||||||
|
|
||||||
XMLError loadOkay = doc.LoadFile(fileName);
|
XMLError loadOkay = doc.LoadFile(fileName);
|
||||||
|
|
||||||
if (loadOkay==XML_SUCCESS)
|
if (loadOkay == XML_SUCCESS)
|
||||||
{
|
{
|
||||||
if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"version", &m_fileVersion))
|
if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(), "version", &m_fileVersion))
|
||||||
{
|
{
|
||||||
if (m_fileVersion==281)
|
if (m_fileVersion == 281)
|
||||||
{
|
{
|
||||||
m_fileOk = true;
|
m_fileOk = true;
|
||||||
int itemcount;
|
int itemcount;
|
||||||
get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"itemcount", &itemcount);
|
get_int_attribute_by_name(doc.FirstChildElement()->ToElement(), "itemcount", &itemcount);
|
||||||
|
|
||||||
auto_serialize(&doc);
|
auto_serialize(&doc);
|
||||||
return m_fileOk;
|
return m_fileOk;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class btDynamicsWorld;
|
|||||||
|
|
||||||
namespace tinyxml2
|
namespace tinyxml2
|
||||||
{
|
{
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct btConvexInternalShapeData;
|
struct btConvexInternalShapeData;
|
||||||
@@ -37,38 +37,34 @@ struct btRigidBodyFloatData;
|
|||||||
struct btTypedConstraintFloatData;
|
struct btTypedConstraintFloatData;
|
||||||
#define btTypedConstraintData2 btTypedConstraintFloatData
|
#define btTypedConstraintData2 btTypedConstraintFloatData
|
||||||
#define btRigidBodyData btRigidBodyFloatData
|
#define btRigidBodyData btRigidBodyFloatData
|
||||||
#endif//BT_USE_DOUBLE_PRECISION
|
#endif //BT_USE_DOUBLE_PRECISION
|
||||||
|
|
||||||
|
|
||||||
struct btCompoundShapeChildData;
|
struct btCompoundShapeChildData;
|
||||||
|
|
||||||
#include "LinearMath/btAlignedObjectArray.h"
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
#include "btWorldImporter.h"
|
#include "btWorldImporter.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class btBulletXmlWorldImporter : public btWorldImporter
|
class btBulletXmlWorldImporter : public btWorldImporter
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
btAlignedObjectArray<btCollisionShapeData*> m_collisionShapeData;
|
btAlignedObjectArray<btCollisionShapeData*> m_collisionShapeData;
|
||||||
btAlignedObjectArray<btAlignedObjectArray<btCompoundShapeChildData>* > m_compoundShapeChildDataArrays;
|
btAlignedObjectArray<btAlignedObjectArray<btCompoundShapeChildData>*> m_compoundShapeChildDataArrays;
|
||||||
btAlignedObjectArray<btRigidBodyData*> m_rigidBodyData;
|
btAlignedObjectArray<btRigidBodyData*> m_rigidBodyData;
|
||||||
btAlignedObjectArray<btTypedConstraintData2*> m_constraintData;
|
btAlignedObjectArray<btTypedConstraintData2*> m_constraintData;
|
||||||
btHashMap<btHashPtr,void*> m_pointerLookup;
|
btHashMap<btHashPtr, void*> m_pointerLookup;
|
||||||
int m_fileVersion;
|
int m_fileVersion;
|
||||||
bool m_fileOk;
|
bool m_fileOk;
|
||||||
|
|
||||||
void auto_serialize_root_level_children(tinyxml2::XMLNode* pParent);
|
void auto_serialize_root_level_children(tinyxml2::XMLNode* pParent);
|
||||||
void auto_serialize(tinyxml2::XMLNode* pParent);
|
void auto_serialize(tinyxml2::XMLNode* pParent);
|
||||||
|
|
||||||
void deSerializeVector3FloatData(tinyxml2::XMLNode* pParent,btAlignedObjectArray<btVector3FloatData>& vectors);
|
void deSerializeVector3FloatData(tinyxml2::XMLNode* pParent, btAlignedObjectArray<btVector3FloatData>& vectors);
|
||||||
|
|
||||||
void fixupCollisionDataPointers(btCollisionShapeData* shapeData);
|
void fixupCollisionDataPointers(btCollisionShapeData* shapeData);
|
||||||
void fixupConstraintData(btTypedConstraintData2* tcd);
|
void fixupConstraintData(btTypedConstraintData2* tcd);
|
||||||
|
|
||||||
//collision shapes data
|
//collision shapes data
|
||||||
void deSerializeCollisionShapeData(tinyxml2::XMLNode* pParent,btCollisionShapeData* colShapeData);
|
void deSerializeCollisionShapeData(tinyxml2::XMLNode* pParent, btCollisionShapeData* colShapeData);
|
||||||
void deSerializeConvexInternalShapeData(tinyxml2::XMLNode* pParent);
|
void deSerializeConvexInternalShapeData(tinyxml2::XMLNode* pParent);
|
||||||
void deSerializeStaticPlaneShapeData(tinyxml2::XMLNode* pParent);
|
void deSerializeStaticPlaneShapeData(tinyxml2::XMLNode* pParent);
|
||||||
void deSerializeCompoundShapeData(tinyxml2::XMLNode* pParent);
|
void deSerializeCompoundShapeData(tinyxml2::XMLNode* pParent);
|
||||||
@@ -82,13 +78,12 @@ protected:
|
|||||||
///constraints
|
///constraints
|
||||||
void deSerializeGeneric6DofConstraintData(tinyxml2::XMLNode* pParent);
|
void deSerializeGeneric6DofConstraintData(tinyxml2::XMLNode* pParent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
btBulletXmlWorldImporter(btDynamicsWorld* world);
|
btBulletXmlWorldImporter(btDynamicsWorld* world);
|
||||||
|
|
||||||
virtual ~btBulletXmlWorldImporter();
|
virtual ~btBulletXmlWorldImporter();
|
||||||
|
|
||||||
bool loadFile(const char* fileName);
|
bool loadFile(const char* fileName);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BT_BULLET_XML_WORLD_IMPORTER_H
|
#endif //BT_BULLET_XML_WORLD_IMPORTER_H
|
||||||
|
|||||||
@@ -25,18 +25,16 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
namespace bullet_utils
|
namespace bullet_utils
|
||||||
{
|
{
|
||||||
void split( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, const std::string& separator)
|
void split(btAlignedObjectArray<std::string> &pieces, const std::string &vector_str, const std::string &separator)
|
||||||
{
|
{
|
||||||
char** strArray = str_split(vector_str.c_str(),separator.c_str());
|
char **strArray = str_split(vector_str.c_str(), separator.c_str());
|
||||||
int numSubStr = str_array_len(strArray);
|
int numSubStr = str_array_len(strArray);
|
||||||
for (int i=0;i<numSubStr;i++)
|
for (int i = 0; i < numSubStr; i++)
|
||||||
pieces.push_back(std::string(strArray[i]));
|
pieces.push_back(std::string(strArray[i]));
|
||||||
str_array_free(strArray);
|
str_array_free(strArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
}; // namespace bullet_utils
|
||||||
|
|
||||||
/* Append an item to a dynamically allocated array of strings. On failure,
|
/* Append an item to a dynamically allocated array of strings. On failure,
|
||||||
return NULL, in which case the original array is intact. The item
|
return NULL, in which case the original array is intact. The item
|
||||||
@@ -50,8 +48,9 @@ char **str_array_append(char **array, size_t nitems, const char *item,
|
|||||||
char *copy;
|
char *copy;
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
copy = NULL;
|
copy = NULL;
|
||||||
else {
|
else
|
||||||
copy = (char*)malloc(itemlen + 1);
|
{
|
||||||
|
copy = (char *)malloc(itemlen + 1);
|
||||||
if (copy == NULL)
|
if (copy == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
memcpy(copy, item, itemlen);
|
memcpy(copy, item, itemlen);
|
||||||
@@ -61,19 +60,19 @@ char **str_array_append(char **array, size_t nitems, const char *item,
|
|||||||
/* Extend array with one element. Except extend it by two elements,
|
/* Extend array with one element. Except extend it by two elements,
|
||||||
in case it did not yet exist. This might mean it is a teeny bit
|
in case it did not yet exist. This might mean it is a teeny bit
|
||||||
too big, but we don't care. */
|
too big, but we don't care. */
|
||||||
array = (char**)realloc(array, (nitems + 2) * sizeof(array[0]));
|
array = (char **)realloc(array, (nitems + 2) * sizeof(array[0]));
|
||||||
if (array == NULL) {
|
if (array == NULL)
|
||||||
|
{
|
||||||
free(copy);
|
free(copy);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add copy of item to array, and return it. */
|
/* Add copy of item to array, and return it. */
|
||||||
array[nitems] = copy;
|
array[nitems] = copy;
|
||||||
array[nitems+1] = NULL;
|
array[nitems + 1] = NULL;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Free a dynamic array of dynamic strings. */
|
/* Free a dynamic array of dynamic strings. */
|
||||||
void str_array_free(char **array)
|
void str_array_free(char **array)
|
||||||
{
|
{
|
||||||
@@ -84,7 +83,6 @@ void str_array_free(char **array)
|
|||||||
free(array);
|
free(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Split a string into substrings. Return dynamic array of dynamically
|
/* Split a string into substrings. Return dynamic array of dynamically
|
||||||
allocated substrings, or NULL if there was an error. Caller is
|
allocated substrings, or NULL if there was an error. Caller is
|
||||||
expected to free the memory, for example with str_array_free. */
|
expected to free the memory, for example with str_array_free. */
|
||||||
@@ -98,29 +96,37 @@ char **str_split(const char *input, const char *sep)
|
|||||||
const char *item;
|
const char *item;
|
||||||
size_t itemlen;
|
size_t itemlen;
|
||||||
|
|
||||||
for (;;) {
|
for (;;)
|
||||||
|
{
|
||||||
next = strstr(start, sep);
|
next = strstr(start, sep);
|
||||||
if (next == NULL) {
|
if (next == NULL)
|
||||||
|
{
|
||||||
/* Add the remaining string (or empty string, if input ends with
|
/* Add the remaining string (or empty string, if input ends with
|
||||||
separator. */
|
separator. */
|
||||||
char **newstr = str_array_append(array, nitems, start, strlen(start));
|
char **newstr = str_array_append(array, nitems, start, strlen(start));
|
||||||
if (newstr == NULL) {
|
if (newstr == NULL)
|
||||||
|
{
|
||||||
str_array_free(array);
|
str_array_free(array);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
array = newstr;
|
array = newstr;
|
||||||
++nitems;
|
++nitems;
|
||||||
break;
|
break;
|
||||||
} else if (next == input) {
|
}
|
||||||
|
else if (next == input)
|
||||||
|
{
|
||||||
/* Input starts with separator. */
|
/* Input starts with separator. */
|
||||||
item = "";
|
item = "";
|
||||||
itemlen = 0;
|
itemlen = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
item = start;
|
item = start;
|
||||||
itemlen = next - item;
|
itemlen = next - item;
|
||||||
}
|
}
|
||||||
char **newstr = str_array_append(array, nitems, item, itemlen);
|
char **newstr = str_array_append(array, nitems, item, itemlen);
|
||||||
if (newstr == NULL) {
|
if (newstr == NULL)
|
||||||
|
{
|
||||||
str_array_free(array);
|
str_array_free(array);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -129,7 +135,8 @@ char **str_split(const char *input, const char *sep)
|
|||||||
start = next + seplen;
|
start = next + seplen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nitems == 0) {
|
if (nitems == 0)
|
||||||
|
{
|
||||||
/* Input does not contain separator at all. */
|
/* Input does not contain separator at all. */
|
||||||
assert(array == NULL);
|
assert(array == NULL);
|
||||||
array = str_array_append(array, nitems, input, strlen(input));
|
array = str_array_append(array, nitems, input, strlen(input));
|
||||||
@@ -138,7 +145,6 @@ char **str_split(const char *input, const char *sep)
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return length of a NULL-delimited array of strings. */
|
/* Return length of a NULL-delimited array of strings. */
|
||||||
size_t str_array_len(char **array)
|
size_t str_array_len(char **array)
|
||||||
{
|
{
|
||||||
@@ -153,10 +159,10 @@ size_t str_array_len(char **array)
|
|||||||
|
|
||||||
#define MAX_OUTPUT 20
|
#define MAX_OUTPUT 20
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
const char *input;
|
const char *input;
|
||||||
const char *sep;
|
const char *sep;
|
||||||
char *output[MAX_OUTPUT];
|
char *output[MAX_OUTPUT];
|
||||||
@@ -208,28 +214,35 @@ int main(void)
|
|||||||
|
|
||||||
errors = false;
|
errors = false;
|
||||||
|
|
||||||
for (int i = 0; i < tab_len; ++i) {
|
for (int i = 0; i < tab_len; ++i)
|
||||||
|
{
|
||||||
printf("test %d\n", i);
|
printf("test %d\n", i);
|
||||||
|
|
||||||
char **output = str_split(tab[i].input, tab[i].sep);
|
char **output = str_split(tab[i].input, tab[i].sep);
|
||||||
if (output == NULL) {
|
if (output == NULL)
|
||||||
|
{
|
||||||
fprintf(stderr, "output is NULL\n");
|
fprintf(stderr, "output is NULL\n");
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size_t num_output = str_array_len(output);
|
size_t num_output = str_array_len(output);
|
||||||
printf("num_output %lu\n", (unsigned long) num_output);
|
printf("num_output %lu\n", (unsigned long)num_output);
|
||||||
|
|
||||||
size_t num_correct = str_array_len(tab[i].output);
|
size_t num_correct = str_array_len(tab[i].output);
|
||||||
if (num_output != num_correct) {
|
if (num_output != num_correct)
|
||||||
|
{
|
||||||
fprintf(stderr, "wrong number of outputs (%lu, not %lu)\n",
|
fprintf(stderr, "wrong number of outputs (%lu, not %lu)\n",
|
||||||
(unsigned long) num_output, (unsigned long) num_correct);
|
(unsigned long)num_output, (unsigned long)num_correct);
|
||||||
errors = true;
|
errors = true;
|
||||||
} else {
|
}
|
||||||
for (size_t j = 0; j < num_output; ++j) {
|
else
|
||||||
if (strcmp(tab[i].output[j], output[j]) != 0) {
|
{
|
||||||
|
for (size_t j = 0; j < num_output; ++j)
|
||||||
|
{
|
||||||
|
if (strcmp(tab[i].output[j], output[j]) != 0)
|
||||||
|
{
|
||||||
fprintf(stderr, "output[%lu] is '%s' not '%s'\n",
|
fprintf(stderr, "output[%lu] is '%s' not '%s'\n",
|
||||||
(unsigned long) j, output[j], tab[i].output[j]);
|
(unsigned long)j, output[j], tab[i].output[j]);
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -245,6 +258,4 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif//
|
#endif //
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ subject to the following restrictions:
|
|||||||
///The string split C code is by Lars Wirzenius
|
///The string split C code is by Lars Wirzenius
|
||||||
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
||||||
|
|
||||||
|
|
||||||
#ifndef STRING_SPLIT_H
|
#ifndef STRING_SPLIT_H
|
||||||
#define STRING_SPLIT_H
|
#define STRING_SPLIT_H
|
||||||
|
|
||||||
@@ -27,13 +26,12 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
namespace bullet_utils
|
namespace bullet_utils
|
||||||
{
|
{
|
||||||
void split( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, const std::string& separator);
|
void split(btAlignedObjectArray<std::string>& pieces, const std::string& vector_str, const std::string& separator);
|
||||||
};
|
};
|
||||||
|
|
||||||
///The string split C code is by Lars Wirzenius
|
///The string split C code is by Lars Wirzenius
|
||||||
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
||||||
|
|
||||||
|
|
||||||
/* Split a string into substrings. Return dynamic array of dynamically
|
/* Split a string into substrings. Return dynamic array of dynamically
|
||||||
allocated substrings, or NULL if there was an error. Caller is
|
allocated substrings, or NULL if there was an error. Caller is
|
||||||
expected to free the memory, for example with str_array_free. */
|
expected to free the memory, for example with str_array_free. */
|
||||||
@@ -46,4 +44,3 @@ void str_array_free(char** array);
|
|||||||
size_t str_array_len(char** array);
|
size_t str_array_len(char** array);
|
||||||
|
|
||||||
#endif //STRING_SPLIT_H
|
#endif //STRING_SPLIT_H
|
||||||
|
|
||||||
|
|||||||
@@ -36,13 +36,11 @@ typedef std::map<bString, bString> bStringMap;
|
|||||||
typedef std::vector<class bVariable> bVariableList;
|
typedef std::vector<class bVariable> bVariableList;
|
||||||
typedef std::vector<bString> bStringList;
|
typedef std::vector<bString> bStringList;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
static FILE *dump = 0;
|
static FILE *dump = 0;
|
||||||
static bDNA *mDNA =0;
|
static bDNA *mDNA = 0;
|
||||||
static bStringMap mStructs;
|
static bStringMap mStructs;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
class bVariable
|
class bVariable
|
||||||
{
|
{
|
||||||
@@ -50,11 +48,9 @@ public:
|
|||||||
bVariable();
|
bVariable();
|
||||||
~bVariable();
|
~bVariable();
|
||||||
|
|
||||||
|
|
||||||
bString dataType;
|
bString dataType;
|
||||||
bString variableName;
|
bString variableName;
|
||||||
|
|
||||||
|
|
||||||
bString functionName;
|
bString functionName;
|
||||||
bString classCtor;
|
bString classCtor;
|
||||||
|
|
||||||
@@ -62,7 +58,6 @@ public:
|
|||||||
bString memberDataType;
|
bString memberDataType;
|
||||||
bString functionArgs;
|
bString functionArgs;
|
||||||
|
|
||||||
|
|
||||||
void initialize(bString dataType, bString variable, bStringMap refDataTable);
|
void initialize(bString dataType, bString variable, bStringMap refDataTable);
|
||||||
|
|
||||||
bool isPtr;
|
bool isPtr;
|
||||||
@@ -103,19 +98,18 @@ bool dataTypeStandard(bString dataType)
|
|||||||
void writeTemplate(short *structData)
|
void writeTemplate(short *structData)
|
||||||
{
|
{
|
||||||
bString type = mDNA->getType(structData[0]);
|
bString type = mDNA->getType(structData[0]);
|
||||||
bString className=type;
|
bString className = type;
|
||||||
bString prefix = isBulletFile? "bullet_" : "blender_";
|
bString prefix = isBulletFile ? "bullet_" : "blender_";
|
||||||
|
|
||||||
int thisLen = structData[1];
|
int thisLen = structData[1];
|
||||||
structData+=2;
|
structData += 2;
|
||||||
|
|
||||||
bString fileName = prefix+type;
|
bString fileName = prefix + type;
|
||||||
|
|
||||||
bVariableList dataTypes;
|
bVariableList dataTypes;
|
||||||
bStringMap includeFiles;
|
bStringMap includeFiles;
|
||||||
|
|
||||||
|
for (int dataVal = 0; dataVal < thisLen; dataVal++, structData += 2)
|
||||||
for (int dataVal =0; dataVal<thisLen; dataVal++, structData+=2)
|
|
||||||
{
|
{
|
||||||
bString dataType = mDNA->getType(structData[0]);
|
bString dataType = mDNA->getType(structData[0]);
|
||||||
bString dataName = mDNA->getName(structData[1]);
|
bString dataName = mDNA->getName(structData[1]);
|
||||||
@@ -148,7 +142,6 @@ void writeTemplate(short *structData)
|
|||||||
if (dataName[0] != '*')
|
if (dataName[0] != '*')
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,28 +153,26 @@ void writeTemplate(short *structData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bStringMap::iterator include = mStructs.find(dataType);
|
bStringMap::iterator include = mStructs.find(dataType);
|
||||||
if (include != mStructs.end())
|
if (include != mStructs.end())
|
||||||
{
|
{
|
||||||
if (dataName[0] != '*')
|
if (dataName[0] != '*')
|
||||||
{
|
{
|
||||||
if (includeFiles.find(dataType)== includeFiles.end())
|
if (includeFiles.find(dataType) == includeFiles.end())
|
||||||
{
|
{
|
||||||
includeFiles[dataType]=prefix+dataType;
|
includeFiles[dataType] = prefix + dataType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fprintf(dump, "###############################################################\n");
|
fprintf(dump, "###############################################################\n");
|
||||||
fprintf(dump, "%s = bStructClass()\n", fileName.c_str());
|
fprintf(dump, "%s = bStructClass()\n", fileName.c_str());
|
||||||
fprintf(dump, "%s.name = '%s'\n", fileName.c_str(), className.c_str());
|
fprintf(dump, "%s.name = '%s'\n", fileName.c_str(), className.c_str());
|
||||||
fprintf(dump, "%s.filename = '%s'\n", fileName.c_str(), fileName.c_str());
|
fprintf(dump, "%s.filename = '%s'\n", fileName.c_str(), fileName.c_str());
|
||||||
|
|
||||||
bVariableList::iterator vars = dataTypes.begin();
|
bVariableList::iterator vars = dataTypes.begin();
|
||||||
while (vars!= dataTypes.end())
|
while (vars != dataTypes.end())
|
||||||
{
|
{
|
||||||
fprintf(dump, "%s.dataTypes.append('%s %s')\n", fileName.c_str(), vars->dataType.c_str(), vars->variableName.c_str());
|
fprintf(dump, "%s.dataTypes.append('%s %s')\n", fileName.c_str(), vars->dataType.c_str(), vars->variableName.c_str());
|
||||||
vars++;
|
vars++;
|
||||||
@@ -196,32 +187,27 @@ void writeTemplate(short *structData)
|
|||||||
fprintf(dump, "DataTypeList.append(%s)\n", fileName.c_str());
|
fprintf(dump, "DataTypeList.append(%s)\n", fileName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
char data[] = {
|
||||||
|
"\n"
|
||||||
|
"class bStructClass:\n"
|
||||||
|
" def __init__(self):\n"
|
||||||
|
" self.name = \"\";\n"
|
||||||
|
" self.filename = \"\";\n"
|
||||||
|
" self.includes = []\n"
|
||||||
|
" self.dataTypes = []\n"
|
||||||
|
"\n\n"
|
||||||
|
"DataTypeList = []\n"};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
char data[]={
|
int main(int argc, char **argv)
|
||||||
"\n"
|
|
||||||
"class bStructClass:\n"
|
|
||||||
" def __init__(self):\n"
|
|
||||||
" self.name = \"\";\n"
|
|
||||||
" self.filename = \"\";\n"
|
|
||||||
" self.includes = []\n"
|
|
||||||
" self.dataTypes = []\n"
|
|
||||||
"\n\n"
|
|
||||||
"DataTypeList = []\n"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
int main(int argc,char** argv)
|
|
||||||
{
|
{
|
||||||
using namespace bParse;
|
using namespace bParse;
|
||||||
dump = fopen("dump.py", "w");
|
dump = fopen("dump.py", "w");
|
||||||
|
|
||||||
|
|
||||||
if (!dump) return 0;
|
if (!dump) return 0;
|
||||||
fprintf(dump, "%s\n", data);
|
fprintf(dump, "%s\n", data);
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
char* filename = "../../../../data/r2d2_multibody.bullet";
|
char* filename = "../../../../data/r2d2_multibody.bullet";
|
||||||
|
|
||||||
@@ -275,73 +261,65 @@ int main(int argc,char** argv)
|
|||||||
#else
|
#else
|
||||||
isBulletFile = true;
|
isBulletFile = true;
|
||||||
bool swap = false;
|
bool swap = false;
|
||||||
char* memBuf = sBulletDNAstr;
|
char *memBuf = sBulletDNAstr;
|
||||||
int len = sBulletDNAlen;
|
int len = sBulletDNAlen;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
char *blenderData = memBuf;
|
char *blenderData = memBuf;
|
||||||
int sdnaPos=0;
|
int sdnaPos = 0;
|
||||||
int mDataStart = 12;
|
int mDataStart = 12;
|
||||||
|
|
||||||
char *tempBuffer = blenderData;
|
char *tempBuffer = blenderData;
|
||||||
for (int i=0; i<len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
// looking for the data's starting position
|
// looking for the data's starting position
|
||||||
// and the start of SDNA decls
|
// and the start of SDNA decls
|
||||||
|
|
||||||
if (!mDataStart && strncmp(tempBuffer, "REND", 4)==0)
|
if (!mDataStart && strncmp(tempBuffer, "REND", 4) == 0)
|
||||||
mDataStart = i;
|
mDataStart = i;
|
||||||
if (!sdnaPos && strncmp(tempBuffer, "SDNA", 4)==0)
|
if (!sdnaPos && strncmp(tempBuffer, "SDNA", 4) == 0)
|
||||||
sdnaPos = i;
|
sdnaPos = i;
|
||||||
|
|
||||||
if (mDataStart && sdnaPos) break;
|
if (mDataStart && sdnaPos) break;
|
||||||
tempBuffer++;
|
tempBuffer++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE *fpdna = fopen("dnaString.txt", "w");
|
||||||
|
|
||||||
FILE* fpdna = fopen("dnaString.txt","w");
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
for (int i=0;i<len-sdnaPos;i++)
|
for (int i = 0; i < len - sdnaPos; i++)
|
||||||
{
|
{
|
||||||
int dnaval = (memBuf+sdnaPos)[i];
|
int dnaval = (memBuf + sdnaPos)[i];
|
||||||
|
|
||||||
if ((i%32)==0)
|
if ((i % 32) == 0)
|
||||||
{
|
{
|
||||||
sprintf(buf,"%d,\n",dnaval);
|
sprintf(buf, "%d,\n", dnaval);
|
||||||
|
}
|
||||||
} else
|
else
|
||||||
{
|
{
|
||||||
sprintf(buf,"%d,",dnaval);
|
sprintf(buf, "%d,", dnaval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fwrite(buf, strlen(buf), 1, fpdna);
|
||||||
fwrite(buf,strlen(buf),1,fpdna);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fpdna);
|
fclose(fpdna);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mDNA = new bDNA();
|
mDNA = new bDNA();
|
||||||
//mDNA->initMemory();
|
//mDNA->initMemory();
|
||||||
|
|
||||||
mDNA->init(memBuf+sdnaPos, len-sdnaPos, swap);
|
mDNA->init(memBuf + sdnaPos, len - sdnaPos, swap);
|
||||||
|
|
||||||
|
for (int i = 0; i < mDNA->getNumStructs(); i++)
|
||||||
for (int i=0; i<mDNA->getNumStructs(); i++)
|
|
||||||
{
|
{
|
||||||
short *structData = mDNA->getStruct(i);
|
short *structData = mDNA->getStruct(i);
|
||||||
bString type = mDNA->getType(structData[0]);
|
bString type = mDNA->getType(structData[0]);
|
||||||
|
|
||||||
bString className = type;
|
bString className = type;
|
||||||
mStructs[type]=className;
|
mStructs[type] = className;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mDNA->getNumStructs(); i++)
|
||||||
for (int i=0; i<mDNA->getNumStructs(); i++)
|
|
||||||
{
|
{
|
||||||
short *structData = mDNA->getStruct(i);
|
short *structData = mDNA->getStruct(i);
|
||||||
writeTemplate(structData);
|
writeTemplate(structData);
|
||||||
@@ -353,23 +331,22 @@ int main(int argc,char** argv)
|
|||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int _getArraySize(char* str)
|
int _getArraySize(char *str)
|
||||||
{
|
{
|
||||||
int a, mul=1;
|
int a, mul = 1;
|
||||||
char stri[100], *cp=0;
|
char stri[100], *cp = 0;
|
||||||
int len = (int)strlen(str);
|
int len = (int)strlen(str);
|
||||||
|
|
||||||
memcpy(stri, str, len+1);
|
memcpy(stri, str, len + 1);
|
||||||
for (a=0; a<len; a++)
|
for (a = 0; a < len; a++)
|
||||||
{
|
{
|
||||||
if (str[a]== '[')
|
if (str[a] == '[')
|
||||||
cp= &(stri[a+1]);
|
cp = &(stri[a + 1]);
|
||||||
else if ( str[a]==']' && cp)
|
else if (str[a] == ']' && cp)
|
||||||
{
|
{
|
||||||
stri[a]= 0;
|
stri[a] = 0;
|
||||||
mul*= atoi(cp);
|
mul *= atoi(cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mul;
|
return mul;
|
||||||
@@ -397,7 +374,6 @@ bVariable::bVariable()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bVariable::~bVariable()
|
bVariable::~bVariable()
|
||||||
{
|
{
|
||||||
@@ -405,7 +381,6 @@ bVariable::~bVariable()
|
|||||||
variableName.clear();
|
variableName.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void bVariable::initialize(bString type, bString variable, bStringMap refDataTable)
|
void bVariable::initialize(bString type, bString variable, bStringMap refDataTable)
|
||||||
{
|
{
|
||||||
@@ -422,7 +397,7 @@ void bVariable::initialize(bString type, bString variable, bStringMap refDataTab
|
|||||||
if (variableName[1] == '*')
|
if (variableName[1] == '*')
|
||||||
isFunctionPtr = true;
|
isFunctionPtr = true;
|
||||||
|
|
||||||
if (variableName[variableName.size()-1] == ']')
|
if (variableName[variableName.size() - 1] == ']')
|
||||||
{
|
{
|
||||||
isArray = true;
|
isArray = true;
|
||||||
if (type == "char")
|
if (type == "char")
|
||||||
@@ -434,14 +409,13 @@ void bVariable::initialize(bString type, bString variable, bStringMap refDataTab
|
|||||||
|
|
||||||
if (variableName[0] == 'p')
|
if (variableName[0] == 'p')
|
||||||
{
|
{
|
||||||
bString sub = variableName.substr(0,3);
|
bString sub = variableName.substr(0, 3);
|
||||||
if (sub == "pad")
|
if (sub == "pad")
|
||||||
isPadding = true;
|
isPadding = true;
|
||||||
}
|
}
|
||||||
if (dataType[0] == '/' && dataType[1] == '/')
|
if (dataType[0] == '/' && dataType[1] == '/')
|
||||||
isCommentedOut = true;
|
isCommentedOut = true;
|
||||||
|
|
||||||
|
|
||||||
if (refDataTable.find(dataType) != refDataTable.end())
|
if (refDataTable.find(dataType) != refDataTable.end())
|
||||||
isGeneratedType = true;
|
isGeneratedType = true;
|
||||||
|
|
||||||
@@ -450,13 +424,13 @@ void bVariable::initialize(bString type, bString variable, bStringMap refDataTab
|
|||||||
// replace valid float arrays
|
// replace valid float arrays
|
||||||
if (dataType == "float" && isArray)
|
if (dataType == "float" && isArray)
|
||||||
{
|
{
|
||||||
int size = _getArraySize((char*)variableName.c_str());
|
int size = _getArraySize((char *)variableName.c_str());
|
||||||
if (size==3)
|
if (size == 3)
|
||||||
{
|
{
|
||||||
dataType = "vec3f";
|
dataType = "vec3f";
|
||||||
variableName = variableName.substr(0, variableName.find_first_of("["));
|
variableName = variableName.substr(0, variableName.find_first_of("["));
|
||||||
}
|
}
|
||||||
if (size==4)
|
if (size == 4)
|
||||||
{
|
{
|
||||||
dataType = "vec4f";
|
dataType = "vec4f";
|
||||||
variableName = variableName.substr(0, variableName.find_first_of("["));
|
variableName = variableName.substr(0, variableName.find_first_of("["));
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ enum LocalBroadphaseNativeTypes
|
|||||||
CONVEX_HULL_SHAPE_PROXYTYPE,
|
CONVEX_HULL_SHAPE_PROXYTYPE,
|
||||||
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
|
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
|
||||||
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
|
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
|
||||||
//implicit convex shapes
|
//implicit convex shapes
|
||||||
IMPLICIT_CONVEX_SHAPES_START_HERE,
|
IMPLICIT_CONVEX_SHAPES_START_HERE,
|
||||||
SPHERE_SHAPE_PROXYTYPE,
|
SPHERE_SHAPE_PROXYTYPE,
|
||||||
MULTI_SPHERE_SHAPE_PROXYTYPE,
|
MULTI_SPHERE_SHAPE_PROXYTYPE,
|
||||||
CAPSULE_SHAPE_PROXYTYPE,
|
CAPSULE_SHAPE_PROXYTYPE,
|
||||||
@@ -36,8 +36,8 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
|
|||||||
BOX_2D_SHAPE_PROXYTYPE,
|
BOX_2D_SHAPE_PROXYTYPE,
|
||||||
CONVEX_2D_SHAPE_PROXYTYPE,
|
CONVEX_2D_SHAPE_PROXYTYPE,
|
||||||
CUSTOM_CONVEX_SHAPE_TYPE,
|
CUSTOM_CONVEX_SHAPE_TYPE,
|
||||||
//concave shapes
|
//concave shapes
|
||||||
CONCAVE_SHAPES_START_HERE,
|
CONCAVE_SHAPES_START_HERE,
|
||||||
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
|
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
|
||||||
TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
||||||
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
||||||
@@ -45,15 +45,15 @@ CONCAVE_SHAPES_START_HERE,
|
|||||||
FAST_CONCAVE_MESH_PROXYTYPE,
|
FAST_CONCAVE_MESH_PROXYTYPE,
|
||||||
//terrain
|
//terrain
|
||||||
TERRAIN_SHAPE_PROXYTYPE,
|
TERRAIN_SHAPE_PROXYTYPE,
|
||||||
///Used for GIMPACT Trimesh integration
|
///Used for GIMPACT Trimesh integration
|
||||||
GIMPACT_SHAPE_PROXYTYPE,
|
GIMPACT_SHAPE_PROXYTYPE,
|
||||||
///Multimaterial mesh
|
///Multimaterial mesh
|
||||||
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
|
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
|
||||||
|
|
||||||
EMPTY_SHAPE_PROXYTYPE,
|
EMPTY_SHAPE_PROXYTYPE,
|
||||||
STATIC_PLANE_PROXYTYPE,
|
STATIC_PLANE_PROXYTYPE,
|
||||||
CUSTOM_CONCAVE_SHAPE_TYPE,
|
CUSTOM_CONCAVE_SHAPE_TYPE,
|
||||||
CONCAVE_SHAPES_END_HERE,
|
CONCAVE_SHAPES_END_HERE,
|
||||||
|
|
||||||
COMPOUND_SHAPE_PROXYTYPE,
|
COMPOUND_SHAPE_PROXYTYPE,
|
||||||
|
|
||||||
@@ -78,19 +78,16 @@ void btBulletDataExtractor::convertAllObjects(bParse::btBulletFile* bulletFile2)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
|
for (i = 0; i < bulletFile2->m_collisionShapes.size(); i++)
|
||||||
{
|
{
|
||||||
btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
|
btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
|
||||||
if (shapeData->m_name)
|
if (shapeData->m_name)
|
||||||
printf("converting shape %s\n", shapeData->m_name);
|
printf("converting shape %s\n", shapeData->m_name);
|
||||||
void* shape = convertCollisionShape(shapeData);
|
void* shape = convertCollisionShape(shapeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* btBulletDataExtractor::convertCollisionShape(btCollisionShapeData* shapeData)
|
||||||
|
|
||||||
void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shapeData )
|
|
||||||
{
|
{
|
||||||
void* shape = 0;
|
void* shape = 0;
|
||||||
|
|
||||||
@@ -99,7 +96,7 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape
|
|||||||
case STATIC_PLANE_PROXYTYPE:
|
case STATIC_PLANE_PROXYTYPE:
|
||||||
{
|
{
|
||||||
btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;
|
btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;
|
||||||
void* shape = createPlaneShape(planeData->m_planeNormal,planeData->m_planeConstant, planeData->m_localScaling);
|
void* shape = createPlaneShape(planeData->m_planeNormal, planeData->m_planeConstant, planeData->m_localScaling);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,12 +113,12 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape
|
|||||||
{
|
{
|
||||||
case BOX_SHAPE_PROXYTYPE:
|
case BOX_SHAPE_PROXYTYPE:
|
||||||
{
|
{
|
||||||
shape = createBoxShape(bsd->m_implicitShapeDimensions, bsd->m_localScaling,bsd->m_collisionMargin);
|
shape = createBoxShape(bsd->m_implicitShapeDimensions, bsd->m_localScaling, bsd->m_collisionMargin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPHERE_SHAPE_PROXYTYPE:
|
case SPHERE_SHAPE_PROXYTYPE:
|
||||||
{
|
{
|
||||||
shape = createSphereShape(bsd->m_implicitShapeDimensions.m_floats[0],bsd->m_localScaling, bsd->m_collisionMargin);
|
shape = createSphereShape(bsd->m_implicitShapeDimensions.m_floats[0], bsd->m_localScaling, bsd->m_collisionMargin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
@@ -223,7 +220,7 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType);
|
printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,30 +313,27 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape
|
|||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
printf("unsupported shape type (%d)\n",shapeData->m_shapeType);
|
printf("unsupported shape type (%d)\n", shapeData->m_shapeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return shape;
|
return shape;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* btBulletDataExtractor::createBoxShape( const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin)
|
void* btBulletDataExtractor::createBoxShape(const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin)
|
||||||
{
|
{
|
||||||
printf("createBoxShape with halfDimensions %f,%f,%f\n",halfDimensions.m_floats[0], halfDimensions.m_floats[1],halfDimensions.m_floats[2]);
|
printf("createBoxShape with halfDimensions %f,%f,%f\n", halfDimensions.m_floats[0], halfDimensions.m_floats[1], halfDimensions.m_floats[2]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* btBulletDataExtractor::createSphereShape( float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin)
|
void* btBulletDataExtractor::createSphereShape(float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin)
|
||||||
{
|
{
|
||||||
printf("createSphereShape with radius %f\n",radius);
|
printf("createSphereShape with radius %f\n", radius);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* btBulletDataExtractor::createPlaneShape(const btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling)
|
||||||
void* btBulletDataExtractor::createPlaneShape( const btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling)
|
|
||||||
{
|
{
|
||||||
printf("createPlaneShape with normal %f,%f,%f and planeConstant\n",planeNormal.m_floats[0], planeNormal.m_floats[1],planeNormal.m_floats[2],planeConstant);
|
printf("createPlaneShape with normal %f,%f,%f and planeConstant\n", planeNormal.m_floats[0], planeNormal.m_floats[1], planeNormal.m_floats[2], planeConstant);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
#ifndef BULLET_DATA_EXTRACTOR_H
|
#ifndef BULLET_DATA_EXTRACTOR_H
|
||||||
#define BULLET_DATA_EXTRACTOR_H
|
#define BULLET_DATA_EXTRACTOR_H
|
||||||
|
|
||||||
|
|
||||||
#include "../BulletFileLoader/autogenerated/bullet.h"
|
#include "../BulletFileLoader/autogenerated/bullet.h"
|
||||||
|
|
||||||
namespace bParse
|
namespace bParse
|
||||||
{
|
{
|
||||||
class btBulletFile;
|
class btBulletFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
class btBulletDataExtractor
|
class btBulletDataExtractor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
btBulletDataExtractor();
|
btBulletDataExtractor();
|
||||||
|
|
||||||
virtual ~btBulletDataExtractor();
|
virtual ~btBulletDataExtractor();
|
||||||
|
|
||||||
virtual void convertAllObjects(bParse::btBulletFile* bulletFile);
|
virtual void convertAllObjects(bParse::btBulletFile* bulletFile);
|
||||||
|
|
||||||
virtual void* convertCollisionShape( Bullet::btCollisionShapeData* shapeData );
|
virtual void* convertCollisionShape(Bullet::btCollisionShapeData* shapeData);
|
||||||
|
|
||||||
virtual void* createPlaneShape( const Bullet::btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling);
|
virtual void* createPlaneShape(const Bullet::btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling);
|
||||||
|
|
||||||
virtual void* createBoxShape( const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin);
|
virtual void* createBoxShape(const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin);
|
||||||
|
|
||||||
virtual void* createSphereShape( float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin);
|
|
||||||
|
|
||||||
|
virtual void* createSphereShape(float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BULLET_DATA_EXTRACTOR_H
|
#endif //BULLET_DATA_EXTRACTOR_H
|
||||||
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
|||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../BulletFileLoader/btBulletFile.h"
|
#include "../BulletFileLoader/btBulletFile.h"
|
||||||
#include "BulletDataExtractor.h"
|
#include "BulletDataExtractor.h"
|
||||||
@@ -25,24 +24,24 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
const char* fileName="testFile.bullet";
|
const char* fileName = "testFile.bullet";
|
||||||
bool verboseDumpAllTypes = false;
|
bool verboseDumpAllTypes = false;
|
||||||
|
|
||||||
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
||||||
|
|
||||||
bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
|
bool ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0;
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
bulletFile2->parse(verboseDumpAllTypes);
|
bulletFile2->parse(verboseDumpAllTypes);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Error loading file %s.\n",fileName);
|
printf("Error loading file %s.\n", fileName);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
|
ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0;
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
printf("Error parsing file %s.\n",fileName);
|
printf("Error parsing file %s.\n", fileName);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +50,6 @@ int main(int argc, char** argv)
|
|||||||
bulletFile2->dumpChunks(bulletFile2->getFileDNA());
|
bulletFile2->dumpChunks(bulletFile2->getFileDNA());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btBulletDataExtractor extractor;
|
btBulletDataExtractor extractor;
|
||||||
|
|
||||||
extractor.convertAllObjects(bulletFile2);
|
extractor.convertAllObjects(bulletFile2);
|
||||||
@@ -60,4 +58,3 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#ifndef DNA_RIGIDBODY_H
|
#ifndef DNA_RIGIDBODY_H
|
||||||
#define DNA_RIGIDBODY_H
|
#define DNA_RIGIDBODY_H
|
||||||
|
|
||||||
|
|
||||||
struct PointerArray
|
struct PointerArray
|
||||||
{
|
{
|
||||||
int m_size;
|
int m_size;
|
||||||
@@ -10,7 +9,6 @@ struct PointerArray
|
|||||||
void *m_data;
|
void *m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct btPhysicsSystem
|
struct btPhysicsSystem
|
||||||
{
|
{
|
||||||
PointerArray m_collisionShapes;
|
PointerArray m_collisionShapes;
|
||||||
@@ -25,5 +23,4 @@ struct ListBase
|
|||||||
void *last;
|
void *last;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user