mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +00:00
* Adjustment: Update Bullet version to 3.24.
This commit is contained in:
parent
35de012ee7
commit
4a3f31df2a
6148 changed files with 2112532 additions and 56873 deletions
67
Engine/lib/bullet/Extras/ConvexDecomposition/CMakeLists.txt
Normal file
67
Engine/lib/bullet/Extras/ConvexDecomposition/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/ConvexDecomposition ${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
SET(ConvexDecomposition_SRCS
|
||||
bestfitobb.cpp
|
||||
ConvexBuilder.cpp
|
||||
cd_wavefront.cpp
|
||||
fitsphere.cpp
|
||||
meshvolume.cpp
|
||||
raytri.cpp
|
||||
vlookup.cpp
|
||||
bestfit.cpp
|
||||
cd_hull.cpp
|
||||
ConvexDecomposition.cpp
|
||||
concavity.cpp
|
||||
float_math.cpp
|
||||
planetri.cpp
|
||||
splitplane.cpp
|
||||
)
|
||||
|
||||
SET(ConvexDecomposition_HDRS
|
||||
ConvexDecomposition.h
|
||||
cd_vector.h
|
||||
concavity.h
|
||||
bestfitobb.h
|
||||
ConvexBuilder.h
|
||||
cd_wavefront.h
|
||||
fitsphere.h
|
||||
meshvolume.h
|
||||
raytri.h
|
||||
vlookup.h
|
||||
bestfit.h
|
||||
cd_hull.h
|
||||
)
|
||||
|
||||
ADD_LIBRARY(ConvexDecomposition ${ConvexDecomposition_SRCS} ${ConvexDecomposition_HDRS})
|
||||
SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(ConvexDecomposition BulletCollision LinearMath)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
IF (INSTALL_EXTRA_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
#FILES_MATCHING requires CMake 2.6
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS ConvexDecomposition DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS ConvexDecomposition
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN
|
||||
".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE)
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(ConvexDecomposition PROPERTIES PUBLIC_HEADER "${ConvexDecomposition_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_EXTRA_LIBS)
|
||||
350
Engine/lib/bullet/Extras/ConvexDecomposition/ConvexBuilder.cpp
Normal file
350
Engine/lib/bullet/Extras/ConvexDecomposition/ConvexBuilder.cpp
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
#include "float_math.h"
|
||||
#include "ConvexBuilder.h"
|
||||
#include "meshvolume.h"
|
||||
#include "bestfit.h"
|
||||
#include <assert.h>
|
||||
#include "cd_hull.h"
|
||||
|
||||
#include "fitsphere.h"
|
||||
#include "bestfitobb.h"
|
||||
|
||||
unsigned int MAXDEPTH = 8;
|
||||
float CONCAVE_PERCENT = 1.0f;
|
||||
float MERGE_PERCENT = 2.0f;
|
||||
|
||||
CHull::CHull(const ConvexDecomposition::ConvexResult &result)
|
||||
{
|
||||
mResult = new ConvexDecomposition::ConvexResult(result);
|
||||
mVolume = computeMeshVolume(result.mHullVertices, result.mHullTcount, result.mHullIndices);
|
||||
|
||||
mDiagonal = getBoundingRegion(result.mHullVcount, result.mHullVertices, sizeof(float) * 3, mMin, mMax);
|
||||
|
||||
float dx = mMax[0] - mMin[0];
|
||||
float dy = mMax[1] - mMin[1];
|
||||
float dz = mMax[2] - mMin[2];
|
||||
|
||||
dx *= 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
|
||||
|
||||
mMin[0] -= dx;
|
||||
mMin[1] -= dy;
|
||||
mMin[2] -= dz;
|
||||
|
||||
mMax[0] += dx;
|
||||
mMax[1] += dy;
|
||||
mMax[2] += dz;
|
||||
}
|
||||
|
||||
CHull::~CHull(void)
|
||||
{
|
||||
delete mResult;
|
||||
}
|
||||
|
||||
bool CHull::overlap(const CHull &h) const
|
||||
{
|
||||
return overlapAABB(mMin, mMax, h.mMin, h.mMax);
|
||||
}
|
||||
|
||||
ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback)
|
||||
{
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
ConvexBuilder::~ConvexBuilder(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < mChulls.size(); i++)
|
||||
{
|
||||
CHull *cr = mChulls[i];
|
||||
delete cr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConvexBuilder::isDuplicate(unsigned int i1, unsigned int i2, unsigned int i3,
|
||||
unsigned int ci1, unsigned int ci2, unsigned int ci3)
|
||||
{
|
||||
unsigned int dcount = 0;
|
||||
|
||||
assert(i1 != i2 && i1 != i3 && i2 != i3);
|
||||
assert(ci1 != ci2 && ci1 != ci3 && ci2 != ci3);
|
||||
|
||||
if (i1 == ci1 || i1 == ci2 || i1 == ci3) dcount++;
|
||||
if (i2 == ci1 || i2 == ci2 || i2 == ci3) dcount++;
|
||||
if (i3 == ci1 || i3 == ci2 || i3 == ci3) dcount++;
|
||||
|
||||
return dcount == 3;
|
||||
}
|
||||
|
||||
void ConvexBuilder::getMesh(const ConvexDecomposition::ConvexResult &cr, VertexLookup vc, UintVector &indices)
|
||||
{
|
||||
unsigned int *src = cr.mHullIndices;
|
||||
|
||||
for (unsigned int i = 0; i < cr.mHullTcount; i++)
|
||||
{
|
||||
unsigned int i1 = *src++;
|
||||
unsigned int i2 = *src++;
|
||||
unsigned int i3 = *src++;
|
||||
|
||||
const float *p1 = &cr.mHullVertices[i1 * 3];
|
||||
const float *p2 = &cr.mHullVertices[i2 * 3];
|
||||
const float *p3 = &cr.mHullVertices[i3 * 3];
|
||||
|
||||
i1 = Vl_getIndex(vc, p1);
|
||||
i2 = Vl_getIndex(vc, p2);
|
||||
i3 = Vl_getIndex(vc, p3);
|
||||
|
||||
#if 0
|
||||
bool duplicate = false;
|
||||
|
||||
unsigned int tcount = indices.size()/3;
|
||||
for (unsigned int j=0; j<tcount; j++)
|
||||
{
|
||||
unsigned int ci1 = indices[j*3+0];
|
||||
unsigned int ci2 = indices[j*3+1];
|
||||
unsigned int ci3 = indices[j*3+2];
|
||||
if ( isDuplicate(i1,i2,i3, ci1, ci2, ci3 ) )
|
||||
{
|
||||
duplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !duplicate )
|
||||
{
|
||||
indices.push_back(i1);
|
||||
indices.push_back(i2);
|
||||
indices.push_back(i3);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
CHull *ret = 0;
|
||||
|
||||
// ok..we are going to combine both meshes into a single mesh
|
||||
// and then we are going to compute the concavity...
|
||||
|
||||
VertexLookup vc = Vl_createVertexLookup();
|
||||
|
||||
UintVector indices;
|
||||
|
||||
getMesh(*a->mResult, vc, indices);
|
||||
getMesh(*b->mResult, vc, indices);
|
||||
|
||||
unsigned int vcount = Vl_getVcount(vc);
|
||||
const float *vertices = Vl_getVertices(vc);
|
||||
unsigned int tcount = indices.size() / 3;
|
||||
|
||||
//don't do anything if hull is empty
|
||||
if (!tcount)
|
||||
{
|
||||
Vl_releaseVertexLookup(vc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConvexDecomposition::HullResult hresult;
|
||||
ConvexDecomposition::HullLibrary hl;
|
||||
ConvexDecomposition::HullDesc desc;
|
||||
|
||||
desc.SetHullFlag(ConvexDecomposition::QF_TRIANGLES);
|
||||
|
||||
desc.mVcount = vcount;
|
||||
desc.mVertices = vertices;
|
||||
desc.mVertexStride = sizeof(float) * 3;
|
||||
|
||||
ConvexDecomposition::HullError hret = hl.CreateConvexHull(desc, hresult);
|
||||
|
||||
if (hret == ConvexDecomposition::QE_OK)
|
||||
{
|
||||
float combineVolume = computeMeshVolume(hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices);
|
||||
float sumVolume = a->mVolume + b->mVolume;
|
||||
|
||||
float percent = (sumVolume * 100) / combineVolume;
|
||||
if (percent >= (100.0f - MERGE_PERCENT))
|
||||
{
|
||||
ConvexDecomposition::ConvexResult cr(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices);
|
||||
ret = new CHull(cr);
|
||||
}
|
||||
}
|
||||
|
||||
Vl_releaseVertexLookup(vc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ConvexBuilder::combineHulls(void)
|
||||
{
|
||||
bool combine = false;
|
||||
|
||||
sortChulls(mChulls); // sort the convex hulls, largest volume to least...
|
||||
|
||||
CHullVector output; // the output hulls...
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mChulls.size() && !combine; ++i)
|
||||
{
|
||||
CHull *cr = mChulls[i];
|
||||
|
||||
int j;
|
||||
for (j = 0; j < mChulls.size(); j++)
|
||||
{
|
||||
CHull *match = mChulls[j];
|
||||
|
||||
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....
|
||||
|
||||
if (merge)
|
||||
{
|
||||
output.push_back(merge);
|
||||
|
||||
++i;
|
||||
while (i != mChulls.size())
|
||||
{
|
||||
CHull *cr = mChulls[i];
|
||||
if (cr != match)
|
||||
{
|
||||
output.push_back(cr);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
delete cr;
|
||||
delete match;
|
||||
combine = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (combine)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.push_back(cr);
|
||||
}
|
||||
}
|
||||
|
||||
if (combine)
|
||||
{
|
||||
mChulls.clear();
|
||||
mChulls.copyFromArray(output);
|
||||
output.clear();
|
||||
}
|
||||
|
||||
return combine;
|
||||
}
|
||||
|
||||
unsigned int ConvexBuilder::process(const ConvexDecomposition::DecompDesc &desc)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
MAXDEPTH = desc.mDepth;
|
||||
CONCAVE_PERCENT = desc.mCpercent;
|
||||
MERGE_PERCENT = desc.mPpercent;
|
||||
|
||||
calcConvexDecomposition(desc.mVcount, desc.mVertices, desc.mTcount, desc.mIndices, this, 0, 0);
|
||||
|
||||
while (combineHulls())
|
||||
; // keep combinging hulls until I can't combine any more...
|
||||
|
||||
int i;
|
||||
for (i = 0; i < mChulls.size(); i++)
|
||||
{
|
||||
CHull *cr = mChulls[i];
|
||||
|
||||
// before we hand it back to the application, we need to regenerate the hull based on the
|
||||
// limits given by the user.
|
||||
|
||||
const ConvexDecomposition::ConvexResult &c = *cr->mResult; // the high resolution hull...
|
||||
|
||||
ConvexDecomposition::HullResult result;
|
||||
ConvexDecomposition::HullLibrary hl;
|
||||
ConvexDecomposition::HullDesc hdesc;
|
||||
|
||||
hdesc.SetHullFlag(ConvexDecomposition::QF_TRIANGLES);
|
||||
|
||||
hdesc.mVcount = c.mHullVcount;
|
||||
hdesc.mVertices = c.mHullVertices;
|
||||
hdesc.mVertexStride = sizeof(float) * 3;
|
||||
hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output
|
||||
|
||||
if (desc.mSkinWidth)
|
||||
{
|
||||
hdesc.mSkinWidth = desc.mSkinWidth;
|
||||
hdesc.SetHullFlag(ConvexDecomposition::QF_SKIN_WIDTH); // do skin width computation.
|
||||
}
|
||||
|
||||
ConvexDecomposition::HullError ret = hl.CreateConvexHull(hdesc, result);
|
||||
|
||||
if (ret == ConvexDecomposition::QE_OK)
|
||||
{
|
||||
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.
|
||||
|
||||
// compute the best fit OBB
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
r.mSphereRadius = computeBoundingSphere(result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter);
|
||||
r.mSphereVolume = fm_sphereVolume(r.mSphereRadius);
|
||||
|
||||
mCallback->ConvexDecompResult(r);
|
||||
}
|
||||
|
||||
hl.ReleaseResult(result);
|
||||
|
||||
delete cr;
|
||||
}
|
||||
|
||||
ret = mChulls.size();
|
||||
|
||||
mChulls.clear();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ConvexBuilder::ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color)
|
||||
{
|
||||
mCallback->ConvexDebugTri(p1, p2, p3, color);
|
||||
}
|
||||
|
||||
void ConvexBuilder::ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color)
|
||||
{
|
||||
mCallback->ConvexDebugOBB(sides, matrix, color);
|
||||
}
|
||||
void ConvexBuilder::ConvexDebugPoint(const float *p, float dist, unsigned int color)
|
||||
{
|
||||
mCallback->ConvexDebugPoint(p, dist, color);
|
||||
}
|
||||
|
||||
void ConvexBuilder::ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color)
|
||||
{
|
||||
mCallback->ConvexDebugBound(bmin, bmax, color);
|
||||
}
|
||||
|
||||
void ConvexBuilder::ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
|
||||
{
|
||||
CHull *ch = new CHull(result);
|
||||
mChulls.push_back(ch);
|
||||
}
|
||||
|
||||
void ConvexBuilder::sortChulls(CHullVector &hulls)
|
||||
{
|
||||
hulls.quickSort(CHullSort());
|
||||
//hulls.heapSort(CHullSort());
|
||||
}
|
||||
103
Engine/lib/bullet/Extras/ConvexDecomposition/ConvexBuilder.h
Normal file
103
Engine/lib/bullet/Extras/ConvexDecomposition/ConvexBuilder.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#ifndef CONVEX_BUILDER_H
|
||||
#define CONVEX_BUILDER_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
#include "ConvexDecomposition.h"
|
||||
#include "vlookup.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
class CHull
|
||||
{
|
||||
public:
|
||||
CHull(const ConvexDecomposition::ConvexResult &result);
|
||||
|
||||
~CHull(void);
|
||||
|
||||
bool overlap(const CHull &h) const;
|
||||
|
||||
float mMin[3];
|
||||
float mMax[3];
|
||||
float mVolume;
|
||||
float mDiagonal; // long edge..
|
||||
ConvexDecomposition::ConvexResult *mResult;
|
||||
};
|
||||
|
||||
// Usage: std::sort( list.begin(), list.end(), StringSortRef() );
|
||||
class CHullSort
|
||||
{
|
||||
public:
|
||||
inline bool operator()(const CHull *a, const CHull *b) const
|
||||
{
|
||||
return a->mVolume < b->mVolume;
|
||||
}
|
||||
};
|
||||
|
||||
typedef btAlignedObjectArray<CHull *> CHullVector;
|
||||
|
||||
class ConvexBuilder : public ConvexDecomposition::ConvexDecompInterface
|
||||
{
|
||||
public:
|
||||
ConvexBuilder(ConvexDecomposition::ConvexDecompInterface *callback);
|
||||
|
||||
virtual ~ConvexBuilder(void);
|
||||
|
||||
bool isDuplicate(unsigned int i1, unsigned int i2, unsigned int i3,
|
||||
unsigned int ci1, unsigned int ci2, unsigned int ci3);
|
||||
|
||||
void getMesh(const ConvexDecomposition::ConvexResult &cr, VertexLookup vc, UintVector &indices);
|
||||
|
||||
CHull *canMerge(CHull *a, CHull *b);
|
||||
|
||||
bool combineHulls(void);
|
||||
|
||||
unsigned int process(const ConvexDecomposition::DecompDesc &desc);
|
||||
|
||||
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 ConvexDebugPoint(const float *p, float dist, unsigned int color);
|
||||
|
||||
virtual void ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color);
|
||||
|
||||
virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result);
|
||||
|
||||
void sortChulls(CHullVector &hulls);
|
||||
|
||||
CHullVector mChulls;
|
||||
ConvexDecompInterface *mCallback;
|
||||
};
|
||||
|
||||
#endif //CONVEX_BUILDER_H
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
#include "float_math.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
#include "ConvexDecomposition.h"
|
||||
#include "cd_vector.h"
|
||||
#include "cd_hull.h"
|
||||
#include "bestfit.h"
|
||||
#include "planetri.h"
|
||||
#include "vlookup.h"
|
||||
#include "splitplane.h"
|
||||
#include "meshvolume.h"
|
||||
#include "concavity.h"
|
||||
#include "bestfitobb.h"
|
||||
#include "float_math.h"
|
||||
#include "fitsphere.h"
|
||||
|
||||
#define SHOW_MESH 0
|
||||
#define MAKE_MESH 1
|
||||
|
||||
using namespace ConvexDecomposition;
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
class FaceTri
|
||||
{
|
||||
public:
|
||||
FaceTri(void){};
|
||||
FaceTri(const float *vertices, unsigned int i1, unsigned int i2, unsigned int i3)
|
||||
{
|
||||
mP1.Set(&vertices[i1 * 3]);
|
||||
mP2.Set(&vertices[i2 * 3]);
|
||||
mP3.Set(&vertices[i3 * 3]);
|
||||
}
|
||||
|
||||
Vector3d mP1;
|
||||
Vector3d mP2;
|
||||
Vector3d mP3;
|
||||
Vector3d mNormal;
|
||||
};
|
||||
|
||||
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 i2 = Vl_getIndex(vl, p2.Ptr());
|
||||
unsigned int i3 = Vl_getIndex(vl, p3.Ptr());
|
||||
|
||||
// do *not* process degenerate triangles!
|
||||
|
||||
if (i1 != i2 && i1 != i3 && i2 != i3)
|
||||
{
|
||||
list.push_back(i1);
|
||||
list.push_back(i2);
|
||||
list.push_back(i3);
|
||||
}
|
||||
}
|
||||
|
||||
void calcConvexDecomposition(unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int tcount,
|
||||
const unsigned int *indices,
|
||||
ConvexDecompInterface *callback,
|
||||
float masterVolume,
|
||||
unsigned int depth)
|
||||
|
||||
{
|
||||
float plane[4];
|
||||
|
||||
bool split = false;
|
||||
|
||||
if (depth < MAXDEPTH)
|
||||
{
|
||||
float volume;
|
||||
float c = computeConcavity(vcount, vertices, tcount, indices, callback, plane, volume);
|
||||
|
||||
if (depth == 0)
|
||||
{
|
||||
masterVolume = volume;
|
||||
}
|
||||
|
||||
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.
|
||||
{
|
||||
split = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth >= MAXDEPTH || !split)
|
||||
{
|
||||
#if 1
|
||||
|
||||
HullResult result;
|
||||
HullLibrary hl;
|
||||
HullDesc desc;
|
||||
|
||||
desc.SetHullFlag(QF_TRIANGLES);
|
||||
|
||||
desc.mVcount = vcount;
|
||||
desc.mVertices = vertices;
|
||||
desc.mVertexStride = sizeof(float) * 3;
|
||||
|
||||
HullError ret = hl.CreateConvexHull(desc, result);
|
||||
|
||||
if (ret == QE_OK)
|
||||
{
|
||||
ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);
|
||||
|
||||
callback->ConvexDecompResult(r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static unsigned int colors[8] =
|
||||
{
|
||||
0xFF0000,
|
||||
0x00FF00,
|
||||
0x0000FF,
|
||||
0xFFFF00,
|
||||
0x00FFFF,
|
||||
0xFF00FF,
|
||||
0xFFFFFF,
|
||||
0xFF8040};
|
||||
|
||||
static int count = 0;
|
||||
|
||||
count++;
|
||||
|
||||
if (count == 8) count = 0;
|
||||
|
||||
assert(count >= 0 && count < 8);
|
||||
|
||||
unsigned int color = colors[count];
|
||||
|
||||
const unsigned int *source = indices;
|
||||
|
||||
for (unsigned int i = 0; i < tcount; i++)
|
||||
{
|
||||
unsigned int i1 = *source++;
|
||||
unsigned int i2 = *source++;
|
||||
unsigned int i3 = *source++;
|
||||
|
||||
FaceTri t(vertices, i1, i2, i3);
|
||||
|
||||
callback->ConvexDebugTri(t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color);
|
||||
}
|
||||
#endif
|
||||
|
||||
hl.ReleaseResult(result);
|
||||
return;
|
||||
}
|
||||
|
||||
UintVector ifront;
|
||||
UintVector iback;
|
||||
|
||||
VertexLookup vfront = Vl_createVertexLookup();
|
||||
VertexLookup vback = Vl_createVertexLookup();
|
||||
|
||||
bool showmesh = false;
|
||||
#if SHOW_MESH
|
||||
showmesh = true;
|
||||
#endif
|
||||
|
||||
if (0)
|
||||
{
|
||||
showmesh = true;
|
||||
for (float x = -1; x < 1; x += 0.10f)
|
||||
{
|
||||
for (float y = 0; y < 1; y += 0.10f)
|
||||
{
|
||||
for (float z = -1; z < 1; z += 0.04f)
|
||||
{
|
||||
float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3];
|
||||
Vector3d p(x, y, z);
|
||||
if (d >= 0)
|
||||
callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00);
|
||||
else
|
||||
callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
// ok..now we are going to 'split' all of the input triangles against this plane!
|
||||
const unsigned int *source = indices;
|
||||
for (unsigned int i = 0; i < tcount; i++)
|
||||
{
|
||||
unsigned int i1 = *source++;
|
||||
unsigned int i2 = *source++;
|
||||
unsigned int i3 = *source++;
|
||||
|
||||
FaceTri t(vertices, i1, i2, i3);
|
||||
|
||||
Vector3d front[4];
|
||||
Vector3d back[4];
|
||||
|
||||
unsigned int fcount = 0;
|
||||
unsigned int bcount = 0;
|
||||
|
||||
PlaneTriResult result;
|
||||
|
||||
result = planeTriIntersection(plane, t.mP1.Ptr(), sizeof(Vector3d), 0.00001f, front[0].Ptr(), fcount, back[0].Ptr(), bcount);
|
||||
|
||||
if (fcount > 4 || bcount > 4)
|
||||
{
|
||||
result = planeTriIntersection(plane, t.mP1.Ptr(), sizeof(Vector3d), 0.00001f, front[0].Ptr(), fcount, back[0].Ptr(), bcount);
|
||||
}
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case PTR_FRONT:
|
||||
|
||||
assert(fcount == 3);
|
||||
|
||||
if (showmesh)
|
||||
callback->ConvexDebugTri(front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00);
|
||||
|
||||
#if MAKE_MESH
|
||||
|
||||
addTri(vfront, ifront, front[0], front[1], front[2]);
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
case PTR_BACK:
|
||||
assert(bcount == 3);
|
||||
|
||||
if (showmesh)
|
||||
callback->ConvexDebugTri(back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00);
|
||||
|
||||
#if MAKE_MESH
|
||||
|
||||
addTri(vback, iback, back[0], back[1], back[2]);
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
case PTR_SPLIT:
|
||||
|
||||
assert(fcount >= 3 && fcount <= 4);
|
||||
assert(bcount >= 3 && bcount <= 4);
|
||||
|
||||
#if MAKE_MESH
|
||||
|
||||
addTri(vfront, ifront, front[0], front[1], front[2]);
|
||||
addTri(vback, iback, back[0], back[1], back[2]);
|
||||
|
||||
if (fcount == 4)
|
||||
{
|
||||
addTri(vfront, ifront, front[0], front[2], front[3]);
|
||||
}
|
||||
|
||||
if (bcount == 4)
|
||||
{
|
||||
addTri(vback, iback, back[0], back[2], back[3]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (showmesh)
|
||||
{
|
||||
callback->ConvexDebugTri(front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000);
|
||||
callback->ConvexDebugTri(back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000);
|
||||
|
||||
if (fcount == 4)
|
||||
{
|
||||
callback->ConvexDebugTri(front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000);
|
||||
}
|
||||
if (bcount == 4)
|
||||
{
|
||||
callback->ConvexDebugTri(back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ok... here we recursively call
|
||||
if (ifront.size())
|
||||
{
|
||||
unsigned int vcount = Vl_getVcount(vfront);
|
||||
const float *vertices = Vl_getVertices(vfront);
|
||||
unsigned int tcount = ifront.size() / 3;
|
||||
|
||||
calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth + 1);
|
||||
}
|
||||
|
||||
ifront.clear();
|
||||
|
||||
Vl_releaseVertexLookup(vfront);
|
||||
|
||||
if (iback.size())
|
||||
{
|
||||
unsigned int vcount = Vl_getVcount(vback);
|
||||
const float *vertices = Vl_getVertices(vback);
|
||||
unsigned int tcount = iback.size() / 3;
|
||||
|
||||
calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth + 1);
|
||||
}
|
||||
|
||||
iback.clear();
|
||||
Vl_releaseVertexLookup(vback);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
#ifndef CONVEX_DECOMPOSITION_H
|
||||
|
||||
#define CONVEX_DECOMPOSITION_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <memory.h> //memcpy
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
extern unsigned int MAXDEPTH;
|
||||
extern float CONCAVE_PERCENT;
|
||||
extern float MERGE_PERCENT;
|
||||
|
||||
typedef btAlignedObjectArray<unsigned int> UintVector;
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
class ConvexResult
|
||||
{
|
||||
public:
|
||||
ConvexResult(void)
|
||||
{
|
||||
mHullVcount = 0;
|
||||
mHullVertices = 0;
|
||||
mHullTcount = 0;
|
||||
mHullIndices = 0;
|
||||
}
|
||||
|
||||
ConvexResult(unsigned int hvcount, const float *hvertices, unsigned int htcount, const unsigned int *hindices)
|
||||
{
|
||||
mHullVcount = hvcount;
|
||||
if (mHullVcount)
|
||||
{
|
||||
mHullVertices = new float[mHullVcount * sizeof(float) * 3];
|
||||
memcpy(mHullVertices, hvertices, sizeof(float) * 3 * mHullVcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHullVertices = 0;
|
||||
}
|
||||
|
||||
mHullTcount = htcount;
|
||||
|
||||
if (mHullTcount)
|
||||
{
|
||||
mHullIndices = new unsigned int[sizeof(unsigned int) * mHullTcount * 3];
|
||||
memcpy(mHullIndices, hindices, sizeof(unsigned int) * mHullTcount * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHullIndices = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ConvexResult(const ConvexResult &r)
|
||||
{
|
||||
mHullVcount = r.mHullVcount;
|
||||
if (mHullVcount)
|
||||
{
|
||||
mHullVertices = new float[mHullVcount * sizeof(float) * 3];
|
||||
memcpy(mHullVertices, r.mHullVertices, sizeof(float) * 3 * mHullVcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHullVertices = 0;
|
||||
}
|
||||
mHullTcount = r.mHullTcount;
|
||||
if (mHullTcount)
|
||||
{
|
||||
mHullIndices = new unsigned int[sizeof(unsigned int) * mHullTcount * 3];
|
||||
memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int) * mHullTcount * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHullIndices = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~ConvexResult(void)
|
||||
{
|
||||
delete[] mHullVertices;
|
||||
delete[] mHullIndices;
|
||||
}
|
||||
|
||||
// the convex hull.
|
||||
unsigned int mHullVcount;
|
||||
float *mHullVertices;
|
||||
unsigned int mHullTcount;
|
||||
unsigned int *mHullIndices;
|
||||
|
||||
float mHullVolume; // the volume of the convex hull.
|
||||
|
||||
float mOBBSides[3]; // the width, height and breadth of the best fit OBB
|
||||
float mOBBCenter[3]; // the center of the OBB
|
||||
float mOBBOrientation[4]; // the quaternion rotation of the OBB.
|
||||
float mOBBTransform[16]; // the 4x4 transform of the OBB.
|
||||
float mOBBVolume; // the volume of the OBB
|
||||
|
||||
float mSphereRadius; // radius and center of best fit sphere
|
||||
float mSphereCenter[3];
|
||||
float mSphereVolume; // volume of the best fit sphere
|
||||
};
|
||||
|
||||
class ConvexDecompInterface
|
||||
{
|
||||
public:
|
||||
virtual ~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){};
|
||||
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;
|
||||
};
|
||||
|
||||
// just to avoid passing a zillion parameters to the method the
|
||||
// options are packed into this descriptor.
|
||||
class DecompDesc
|
||||
{
|
||||
public:
|
||||
DecompDesc(void)
|
||||
{
|
||||
mVcount = 0;
|
||||
mVertices = 0;
|
||||
mTcount = 0;
|
||||
mIndices = 0;
|
||||
mDepth = 5;
|
||||
mCpercent = 5;
|
||||
mPpercent = 5;
|
||||
mMaxVertices = 32;
|
||||
mSkinWidth = 0;
|
||||
mCallback = 0;
|
||||
}
|
||||
|
||||
// describes the input triangle.
|
||||
unsigned int mVcount; // the number of vertices in the source mesh.
|
||||
const float *mVertices; // start of the vertex position array. Assumes a stride of 3 floats.
|
||||
unsigned int mTcount; // the number of triangles in the source mesh.
|
||||
unsigned int *mIndices; // the indexed triangle list array (zero index based)
|
||||
|
||||
// options
|
||||
unsigned int mDepth; // depth to split, a maximum of 10, generally not over 7.
|
||||
float mCpercent; // the concavity threshold percentage. 0=20 is reasonable.
|
||||
float mPpercent; // the percentage volume conservation threshold to collapse hulls. 0-30 is reasonable.
|
||||
|
||||
// hull output limits.
|
||||
unsigned int mMaxVertices; // maximum number of vertices in the output hull. Recommended 32 or less.
|
||||
float mSkinWidth; // a skin width to apply to the output hulls.
|
||||
|
||||
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.
|
||||
|
||||
void calcConvexDecomposition(unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int tcount,
|
||||
const unsigned int *indices,
|
||||
ConvexDecompInterface *callback,
|
||||
float masterVolume,
|
||||
unsigned int depth);
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
|
||||
#endif
|
||||
19
Engine/lib/bullet/Extras/ConvexDecomposition/LICENSE.txt
Normal file
19
Engine/lib/bullet/Extras/ConvexDecomposition/LICENSE.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
448
Engine/lib/bullet/Extras/ConvexDecomposition/bestfit.cpp
Normal file
448
Engine/lib/bullet/Extras/ConvexDecomposition/bestfit.cpp
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
#include "float_math.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
// Geometric Tools, Inc.
|
||||
// http://www.geometrictools.com
|
||||
// Copyright (c) 1998-2006. All Rights Reserved
|
||||
//
|
||||
// The Wild Magic Library (WM3) source code is supplied under the terms of
|
||||
// the license agreement
|
||||
// http://www.geometrictools.com/License/WildMagic3License.pdf
|
||||
// and may not be copied or disclosed except in accordance with the terms
|
||||
// of that agreement.
|
||||
|
||||
#include "bestfit.h"
|
||||
|
||||
namespace BestFit
|
||||
{
|
||||
class Vec3
|
||||
{
|
||||
public:
|
||||
Vec3(void){};
|
||||
Vec3(float _x, float _y, float _z)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
};
|
||||
|
||||
float dot(const Vec3 &v)
|
||||
{
|
||||
return x * v.x + y * v.y + z * v.z; // the dot product
|
||||
}
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
class Eigen
|
||||
{
|
||||
public:
|
||||
void DecrSortEigenStuff(void)
|
||||
{
|
||||
Tridiagonal(); //diagonalize the matrix.
|
||||
QLAlgorithm(); //
|
||||
DecreasingSort();
|
||||
GuaranteeRotation();
|
||||
}
|
||||
|
||||
void Tridiagonal(void)
|
||||
{
|
||||
float fM00 = mElement[0][0];
|
||||
float fM01 = mElement[0][1];
|
||||
float fM02 = mElement[0][2];
|
||||
float fM11 = mElement[1][1];
|
||||
float fM12 = mElement[1][2];
|
||||
float fM22 = mElement[2][2];
|
||||
|
||||
m_afDiag[0] = fM00;
|
||||
m_afSubd[2] = 0;
|
||||
if (fM02 != (float)0.0)
|
||||
{
|
||||
float fLength = sqrtf(fM01 * fM01 + fM02 * fM02);
|
||||
float fInvLength = ((float)1.0) / fLength;
|
||||
fM01 *= fInvLength;
|
||||
fM02 *= fInvLength;
|
||||
float fQ = ((float)2.0) * fM01 * fM12 + fM02 * (fM22 - fM11);
|
||||
m_afDiag[1] = fM11 + fM02 * fQ;
|
||||
m_afDiag[2] = fM22 - fM02 * fQ;
|
||||
m_afSubd[0] = fLength;
|
||||
m_afSubd[1] = fM12 - fM01 * fQ;
|
||||
mElement[0][0] = (float)1.0;
|
||||
mElement[0][1] = (float)0.0;
|
||||
mElement[0][2] = (float)0.0;
|
||||
mElement[1][0] = (float)0.0;
|
||||
mElement[1][1] = fM01;
|
||||
mElement[1][2] = fM02;
|
||||
mElement[2][0] = (float)0.0;
|
||||
mElement[2][1] = fM02;
|
||||
mElement[2][2] = -fM01;
|
||||
m_bIsRotation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_afDiag[1] = fM11;
|
||||
m_afDiag[2] = fM22;
|
||||
m_afSubd[0] = fM01;
|
||||
m_afSubd[1] = fM12;
|
||||
mElement[0][0] = (float)1.0;
|
||||
mElement[0][1] = (float)0.0;
|
||||
mElement[0][2] = (float)0.0;
|
||||
mElement[1][0] = (float)0.0;
|
||||
mElement[1][1] = (float)1.0;
|
||||
mElement[1][2] = (float)0.0;
|
||||
mElement[2][0] = (float)0.0;
|
||||
mElement[2][1] = (float)0.0;
|
||||
mElement[2][2] = (float)1.0;
|
||||
m_bIsRotation = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool QLAlgorithm(void)
|
||||
{
|
||||
const int iMaxIter = 32;
|
||||
|
||||
for (int i0 = 0; i0 < 3; i0++)
|
||||
{
|
||||
int i1;
|
||||
for (i1 = 0; i1 < iMaxIter; i1++)
|
||||
{
|
||||
int i2;
|
||||
for (i2 = i0; i2 <= (3 - 2); i2++)
|
||||
{
|
||||
float fTmp = fabsf(m_afDiag[i2]) + fabsf(m_afDiag[i2 + 1]);
|
||||
if (fabsf(m_afSubd[i2]) + fTmp == fTmp)
|
||||
break;
|
||||
}
|
||||
if (i2 == i0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
float fG = (m_afDiag[i0 + 1] - m_afDiag[i0]) / (((float)2.0) * m_afSubd[i0]);
|
||||
float fR = sqrtf(fG * fG + (float)1.0);
|
||||
if (fG < (float)0.0)
|
||||
{
|
||||
fG = m_afDiag[i2] - m_afDiag[i0] + m_afSubd[i0] / (fG - fR);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
for (int i3 = i2 - 1; i3 >= i0; i3--)
|
||||
{
|
||||
float fF = fSin * m_afSubd[i3];
|
||||
float fB = fCos * m_afSubd[i3];
|
||||
if (fabsf(fF) >= fabsf(fG))
|
||||
{
|
||||
fCos = fG / fF;
|
||||
fR = sqrtf(fCos * fCos + (float)1.0);
|
||||
m_afSubd[i3 + 1] = fF * fR;
|
||||
fSin = ((float)1.0) / fR;
|
||||
fCos *= fSin;
|
||||
}
|
||||
else
|
||||
{
|
||||
fSin = fF / fG;
|
||||
fR = sqrtf(fSin * fSin + (float)1.0);
|
||||
m_afSubd[i3 + 1] = fG * fR;
|
||||
fCos = ((float)1.0) / fR;
|
||||
fSin *= fCos;
|
||||
}
|
||||
fG = m_afDiag[i3 + 1] - fP;
|
||||
fR = (m_afDiag[i3] - fG) * fSin + ((float)2.0) * fB * fCos;
|
||||
fP = fSin * fR;
|
||||
m_afDiag[i3 + 1] = fG + fP;
|
||||
fG = fCos * fR - fB;
|
||||
for (int i4 = 0; i4 < 3; i4++)
|
||||
{
|
||||
fF = mElement[i4][i3 + 1];
|
||||
mElement[i4][i3 + 1] = fSin * mElement[i4][i3] + fCos * fF;
|
||||
mElement[i4][i3] = fCos * mElement[i4][i3] - fSin * fF;
|
||||
}
|
||||
}
|
||||
m_afDiag[i0] -= fP;
|
||||
m_afSubd[i0] = fG;
|
||||
m_afSubd[i2] = (float)0.0;
|
||||
}
|
||||
if (i1 == iMaxIter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DecreasingSort(void)
|
||||
{
|
||||
//sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1]
|
||||
for (int i0 = 0, i1; i0 <= 3 - 2; i0++)
|
||||
{
|
||||
// locate maximum eigenvalue
|
||||
i1 = i0;
|
||||
float fMax = m_afDiag[i1];
|
||||
int i2;
|
||||
for (i2 = i0 + 1; i2 < 3; i2++)
|
||||
{
|
||||
if (m_afDiag[i2] > fMax)
|
||||
{
|
||||
i1 = i2;
|
||||
fMax = m_afDiag[i1];
|
||||
}
|
||||
}
|
||||
|
||||
if (i1 != i0)
|
||||
{
|
||||
// swap eigenvalues
|
||||
m_afDiag[i1] = m_afDiag[i0];
|
||||
m_afDiag[i0] = fMax;
|
||||
// swap eigenvectors
|
||||
for (i2 = 0; i2 < 3; i2++)
|
||||
{
|
||||
float fTmp = mElement[i2][i0];
|
||||
mElement[i2][i0] = mElement[i2][i1];
|
||||
mElement[i2][i1] = fTmp;
|
||||
m_bIsRotation = !m_bIsRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuaranteeRotation(void)
|
||||
{
|
||||
if (!m_bIsRotation)
|
||||
{
|
||||
// change sign on the first column
|
||||
for (int iRow = 0; iRow < 3; iRow++)
|
||||
{
|
||||
mElement[iRow][0] = -mElement[iRow][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float mElement[3][3];
|
||||
float m_afDiag[3];
|
||||
float m_afSubd[3];
|
||||
bool m_bIsRotation;
|
||||
};
|
||||
|
||||
} // namespace BestFit
|
||||
|
||||
using namespace BestFit;
|
||||
|
||||
bool getBestFitPlane(unsigned int vcount,
|
||||
const float *points,
|
||||
unsigned int vstride,
|
||||
const float *weights,
|
||||
unsigned int wstride,
|
||||
float *plane)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
Vec3 kOrigin(0, 0, 0);
|
||||
|
||||
float wtotal = 0;
|
||||
|
||||
if (1)
|
||||
{
|
||||
const char *source = (const char *)points;
|
||||
const char *wsource = (const char *)weights;
|
||||
|
||||
for (unsigned int i = 0; i < vcount; i++)
|
||||
{
|
||||
const float *p = (const float *)source;
|
||||
|
||||
float w = 1;
|
||||
|
||||
if (wsource)
|
||||
{
|
||||
const float *ws = (const float *)wsource;
|
||||
w = *ws; //
|
||||
wsource += wstride;
|
||||
}
|
||||
|
||||
kOrigin.x += p[0] * w;
|
||||
kOrigin.y += p[1] * w;
|
||||
kOrigin.z += p[2] * w;
|
||||
|
||||
wtotal += w;
|
||||
|
||||
source += vstride;
|
||||
}
|
||||
}
|
||||
|
||||
float recip = 1.0f / wtotal; // reciprocol of total weighting
|
||||
|
||||
kOrigin.x *= recip;
|
||||
kOrigin.y *= recip;
|
||||
kOrigin.z *= recip;
|
||||
|
||||
float fSumXX = 0;
|
||||
float fSumXY = 0;
|
||||
float fSumXZ = 0;
|
||||
|
||||
float fSumYY = 0;
|
||||
float fSumYZ = 0;
|
||||
float fSumZZ = 0;
|
||||
|
||||
if (1)
|
||||
{
|
||||
const char *source = (const char *)points;
|
||||
const char *wsource = (const char *)weights;
|
||||
|
||||
for (unsigned int i = 0; i < vcount; i++)
|
||||
{
|
||||
const float *p = (const float *)source;
|
||||
|
||||
float w = 1;
|
||||
|
||||
if (wsource)
|
||||
{
|
||||
const float *ws = (const float *)wsource;
|
||||
w = *ws; //
|
||||
wsource += wstride;
|
||||
}
|
||||
|
||||
Vec3 kDiff;
|
||||
|
||||
kDiff.x = w * (p[0] - kOrigin.x); // apply vertex weighting!
|
||||
kDiff.y = w * (p[1] - kOrigin.y);
|
||||
kDiff.z = w * (p[2] - kOrigin.z);
|
||||
|
||||
fSumXX += kDiff.x * kDiff.x; // 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.
|
||||
|
||||
fSumYY += kDiff.y * kDiff.y;
|
||||
fSumYZ += kDiff.y * kDiff.z;
|
||||
fSumZZ += kDiff.z * kDiff.z;
|
||||
|
||||
source += vstride;
|
||||
}
|
||||
}
|
||||
|
||||
fSumXX *= recip;
|
||||
fSumXY *= recip;
|
||||
fSumXZ *= recip;
|
||||
fSumYY *= recip;
|
||||
fSumYZ *= recip;
|
||||
fSumZZ *= recip;
|
||||
|
||||
// setup the eigensolver
|
||||
Eigen kES;
|
||||
|
||||
kES.mElement[0][0] = fSumXX;
|
||||
kES.mElement[0][1] = fSumXY;
|
||||
kES.mElement[0][2] = fSumXZ;
|
||||
|
||||
kES.mElement[1][0] = fSumXY;
|
||||
kES.mElement[1][1] = fSumYY;
|
||||
kES.mElement[1][2] = fSumYZ;
|
||||
|
||||
kES.mElement[2][0] = fSumXZ;
|
||||
kES.mElement[2][1] = fSumYZ;
|
||||
kES.mElement[2][2] = fSumZZ;
|
||||
|
||||
// compute eigenstuff, smallest eigenvalue is in last position
|
||||
kES.DecrSortEigenStuff();
|
||||
|
||||
Vec3 kNormal;
|
||||
|
||||
kNormal.x = kES.mElement[0][2];
|
||||
kNormal.y = kES.mElement[1][2];
|
||||
kNormal.z = kES.mElement[2][2];
|
||||
|
||||
// the minimum energy
|
||||
plane[0] = kNormal.x;
|
||||
plane[1] = kNormal.y;
|
||||
plane[2] = kNormal.z;
|
||||
|
||||
plane[3] = 0 - kNormal.dot(kOrigin);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
bmin[0] = points[0];
|
||||
bmin[1] = points[1];
|
||||
bmin[2] = points[2];
|
||||
|
||||
bmax[0] = points[0];
|
||||
bmax[1] = points[1];
|
||||
bmax[2] = points[2];
|
||||
|
||||
for (unsigned int i = 1; i < vcount; i++)
|
||||
{
|
||||
source += pstride;
|
||||
const float *p = (const float *)source;
|
||||
|
||||
if (p[0] < bmin[0]) bmin[0] = p[0];
|
||||
if (p[1] < bmin[1]) bmin[1] = p[1];
|
||||
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];
|
||||
}
|
||||
|
||||
float dx = bmax[0] - bmin[0];
|
||||
float dy = bmax[1] - bmin[1];
|
||||
float dz = bmax[2] - bmin[2];
|
||||
|
||||
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.
|
||||
{
|
||||
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[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
|
||||
|
||||
return true; // the extents overlap
|
||||
}
|
||||
63
Engine/lib/bullet/Extras/ConvexDecomposition/bestfit.h
Normal file
63
Engine/lib/bullet/Extras/ConvexDecomposition/bestfit.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef BEST_FIT_H
|
||||
|
||||
#define BEST_FIT_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
// This routine was released in 'snippet' form
|
||||
// by John W. Ratcliff mailto:jratcliff@infiniplex.net
|
||||
// on March 22, 2006.
|
||||
//
|
||||
// This routine computes the 'best fit' plane equation to
|
||||
// a set of input data points with an optional per vertex
|
||||
// weighting component.
|
||||
//
|
||||
// The implementation for this was lifted directly from
|
||||
// David Eberly's Magic Software implementation.
|
||||
|
||||
// computes the best fit plane to a collection of data points.
|
||||
// returns the plane equation as A,B,C,D format. (Ax+By+Cz+D)
|
||||
|
||||
bool getBestFitPlane(unsigned int vcount, // number of input data points
|
||||
const float *points, // starting address of points array.
|
||||
unsigned int vstride, // stride between input points.
|
||||
const float *weights, // *optional point weighting values.
|
||||
unsigned int wstride, // weight stride for each vertex.
|
||||
float *plane);
|
||||
|
||||
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.
|
||||
|
||||
#endif
|
||||
166
Engine/lib/bullet/Extras/ConvexDecomposition/bestfitobb.cpp
Normal file
166
Engine/lib/bullet/Extras/ConvexDecomposition/bestfitobb.cpp
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
#include "float_math.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
#include "bestfitobb.h"
|
||||
#include "float_math.h"
|
||||
|
||||
// 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)
|
||||
{
|
||||
const char *src = (const char *)points;
|
||||
|
||||
float bmin[3] = {1e9, 1e9, 1e9};
|
||||
float bmax[3] = {-1e9, -1e9, -1e9};
|
||||
|
||||
for (unsigned int i = 0; i < vcount; i++)
|
||||
{
|
||||
const float *p = (const float *)src;
|
||||
float t[3];
|
||||
|
||||
fm_inverseRT(matrix, p, t); // inverse rotate translate
|
||||
|
||||
if (t[0] < bmin[0]) bmin[0] = t[0];
|
||||
if (t[1] < bmin[1]) bmin[1] = t[1];
|
||||
if (t[2] < bmin[2]) bmin[2] = t[2];
|
||||
|
||||
if (t[0] > bmax[0]) bmax[0] = t[0];
|
||||
if (t[1] > bmax[1]) bmax[1] = t[1];
|
||||
if (t[2] > bmax[2]) bmax[2] = t[2];
|
||||
|
||||
src += pstride;
|
||||
}
|
||||
|
||||
sides[0] = bmax[0];
|
||||
sides[1] = bmax[1];
|
||||
sides[2] = bmax[2];
|
||||
|
||||
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[2]) > sides[2]) sides[2] = fabsf(bmin[2]);
|
||||
|
||||
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)
|
||||
{
|
||||
float bmin[3];
|
||||
float bmax[3];
|
||||
|
||||
fm_getAABB(vcount, points, pstride, bmin, bmax);
|
||||
|
||||
float center[3];
|
||||
|
||||
center[0] = (bmax[0] - bmin[0]) * 0.5f + bmin[0];
|
||||
center[1] = (bmax[1] - bmin[1]) * 0.5f + bmin[1];
|
||||
center[2] = (bmax[2] - bmin[2]) * 0.5f + bmin[2];
|
||||
|
||||
float ax = 0;
|
||||
float ay = 0;
|
||||
float az = 0;
|
||||
|
||||
float sweep = 45.0f; // 180 degree sweep on all three axes.
|
||||
float steps = 8.0f; // 16 steps on each axis.
|
||||
|
||||
float bestVolume = 1e9;
|
||||
float angle[3] = {0.f, 0.f, 0.f};
|
||||
|
||||
while (sweep >= 1)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
float stepsize = sweep / steps;
|
||||
|
||||
for (float x = ax - sweep; x <= ax + sweep; x += stepsize)
|
||||
{
|
||||
for (float y = ay - sweep; y <= ay + sweep; y += stepsize)
|
||||
{
|
||||
for (float z = az - sweep; z <= az + sweep; z += stepsize)
|
||||
{
|
||||
float pmatrix[16];
|
||||
|
||||
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 + 1] = center[1];
|
||||
pmatrix[3 * 4 + 2] = center[2];
|
||||
|
||||
float psides[3];
|
||||
|
||||
computeOBB(vcount, points, pstride, psides, pmatrix);
|
||||
|
||||
float volume = psides[0] * psides[1] * psides[2]; // the volume of the cube
|
||||
|
||||
if (volume <= bestVolume)
|
||||
{
|
||||
bestVolume = volume;
|
||||
|
||||
sides[0] = psides[0];
|
||||
sides[1] = psides[1];
|
||||
sides[2] = psides[2];
|
||||
|
||||
angle[0] = ax;
|
||||
angle[1] = ay;
|
||||
angle[2] = az;
|
||||
|
||||
memcpy(matrix, pmatrix, sizeof(float) * 16);
|
||||
found = true; // yes, we found an improvement.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
ax = angle[0];
|
||||
ay = angle[1];
|
||||
az = angle[2];
|
||||
|
||||
sweep *= 0.5f; // sweep 1/2 the distance as the last time.
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // no improvement, so just
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Engine/lib/bullet/Extras/ConvexDecomposition/bestfitobb.h
Normal file
41
Engine/lib/bullet/Extras/ConvexDecomposition/bestfitobb.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef BEST_FIT_OBB_H
|
||||
|
||||
#define BEST_FIT_OBB_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
void computeBestFitOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, float *matrix);
|
||||
|
||||
#endif
|
||||
3370
Engine/lib/bullet/Extras/ConvexDecomposition/cd_hull.cpp
Normal file
3370
Engine/lib/bullet/Extras/ConvexDecomposition/cd_hull.cpp
Normal file
File diff suppressed because it is too large
Load diff
148
Engine/lib/bullet/Extras/ConvexDecomposition/cd_hull.h
Normal file
148
Engine/lib/bullet/Extras/ConvexDecomposition/cd_hull.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#ifndef CD_HULL_H
|
||||
|
||||
#define CD_HULL_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
class HullResult
|
||||
{
|
||||
public:
|
||||
HullResult(void)
|
||||
{
|
||||
mPolygons = true;
|
||||
mNumOutputVertices = 0;
|
||||
mOutputVertices = 0;
|
||||
mNumFaces = 0;
|
||||
mNumIndices = 0;
|
||||
mIndices = 0;
|
||||
}
|
||||
bool mPolygons; // true if indices represents polygons, false indices are triangles
|
||||
unsigned int mNumOutputVertices; // number of vertices in the output hull
|
||||
float *mOutputVertices; // array of vertices, 3 floats each x,y,z
|
||||
unsigned int mNumFaces; // the number of faces produced
|
||||
unsigned int mNumIndices; // the total number of indices
|
||||
unsigned int *mIndices; // pointer to indices.
|
||||
|
||||
// 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..
|
||||
};
|
||||
|
||||
enum HullFlag
|
||||
{
|
||||
QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons.
|
||||
QF_REVERSE_ORDER = (1 << 1), // reverse order of the triangle indices.
|
||||
QF_SKIN_WIDTH = (1 << 2), // extrude hull based on this skin width
|
||||
QF_DEFAULT = 0
|
||||
};
|
||||
|
||||
class HullDesc
|
||||
{
|
||||
public:
|
||||
HullDesc(void)
|
||||
{
|
||||
mFlags = QF_DEFAULT;
|
||||
mVcount = 0;
|
||||
mVertices = 0;
|
||||
mVertexStride = sizeof(float) * 3;
|
||||
mNormalEpsilon = 0.001f;
|
||||
mMaxVertices = 4096; // maximum number of points to be considered for a convex hull.
|
||||
mMaxFaces = 4096;
|
||||
mSkinWidth = 0.01f; // default is one centimeter
|
||||
};
|
||||
|
||||
HullDesc(HullFlag flag,
|
||||
unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int stride)
|
||||
{
|
||||
mFlags = flag;
|
||||
mVcount = vcount;
|
||||
mVertices = vertices;
|
||||
mVertexStride = stride;
|
||||
mNormalEpsilon = 0.001f;
|
||||
mMaxVertices = 4096;
|
||||
mSkinWidth = 0.01f; // default is one centimeter
|
||||
}
|
||||
|
||||
bool HasHullFlag(HullFlag flag) const
|
||||
{
|
||||
if (mFlags & flag) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetHullFlag(HullFlag flag)
|
||||
{
|
||||
mFlags |= flag;
|
||||
}
|
||||
|
||||
void ClearHullFlag(HullFlag flag)
|
||||
{
|
||||
mFlags &= ~flag;
|
||||
}
|
||||
|
||||
unsigned int mFlags; // flags to use when generating the convex hull.
|
||||
unsigned int mVcount; // number of vertices in the input point cloud
|
||||
const float *mVertices; // the array of vertices.
|
||||
unsigned int mVertexStride; // the stride of each vertex, in bytes.
|
||||
float mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on.
|
||||
float mSkinWidth;
|
||||
unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull!
|
||||
unsigned int mMaxFaces;
|
||||
};
|
||||
|
||||
enum HullError
|
||||
{
|
||||
QE_OK, // success!
|
||||
QE_FAIL // failed.
|
||||
};
|
||||
|
||||
class HullLibrary
|
||||
{
|
||||
public:
|
||||
HullError CreateConvexHull(const HullDesc &desc, // describes the input request
|
||||
HullResult &result); // contains the resulst
|
||||
|
||||
HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
|
||||
|
||||
private:
|
||||
void BringOutYourDead(const float *verts, unsigned int vcount, float *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount);
|
||||
|
||||
bool CleanupVertices(unsigned int svcount,
|
||||
const float *svertices,
|
||||
unsigned int stride,
|
||||
unsigned int &vcount, // output number of vertices
|
||||
float *vertices, // location to store the results.
|
||||
float normalepsilon,
|
||||
float *scale);
|
||||
};
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
|
||||
#endif
|
||||
1192
Engine/lib/bullet/Extras/ConvexDecomposition/cd_vector.h
Normal file
1192
Engine/lib/bullet/Extras/ConvexDecomposition/cd_vector.h
Normal file
File diff suppressed because it is too large
Load diff
824
Engine/lib/bullet/Extras/ConvexDecomposition/cd_wavefront.cpp
Normal file
824
Engine/lib/bullet/Extras/ConvexDecomposition/cd_wavefront.cpp
Normal file
|
|
@ -0,0 +1,824 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
#include "float_math.h"
|
||||
|
||||
#include "cd_wavefront.h"
|
||||
|
||||
using namespace ConvexDecomposition;
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
typedef std::vector<int> IntVector;
|
||||
typedef std::vector<float> FloatVector;
|
||||
|
||||
#if defined(__APPLE__) || defined(__CELLOS_LV2__)
|
||||
#define stricmp(a, b) strcasecmp((a), (b))
|
||||
#endif
|
||||
|
||||
/*******************************************************************/
|
||||
/******************** InParser.h ********************************/
|
||||
/*******************************************************************/
|
||||
class InPlaceParserInterface
|
||||
{
|
||||
public:
|
||||
virtual ~InPlaceParserInterface(){};
|
||||
|
||||
virtual int ParseLine(int lineno, int argc, const char **argv) = 0; // return TRUE to continue parsing, return FALSE to abort parsing process
|
||||
};
|
||||
|
||||
enum SeparatorType
|
||||
{
|
||||
ST_DATA, // is data
|
||||
ST_HARD, // is a hard separator
|
||||
ST_SOFT, // is a soft separator
|
||||
ST_EOS // is a comment symbol, and everything past this character should be ignored
|
||||
};
|
||||
|
||||
class InPlaceParser
|
||||
{
|
||||
public:
|
||||
InPlaceParser(void)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
InPlaceParser(char *data, int len)
|
||||
{
|
||||
Init();
|
||||
SetSourceData(data, len);
|
||||
}
|
||||
|
||||
InPlaceParser(const char *fname)
|
||||
{
|
||||
Init();
|
||||
SetFile(fname);
|
||||
}
|
||||
|
||||
~InPlaceParser(void);
|
||||
|
||||
void Init(void)
|
||||
{
|
||||
mQuoteChar = 34;
|
||||
mData = 0;
|
||||
mLen = 0;
|
||||
mMyAlloc = false;
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
mHard[i] = ST_DATA;
|
||||
mHardString[i * 2] = i;
|
||||
mHardString[i * 2 + 1] = 0;
|
||||
}
|
||||
mHard[0] = ST_EOS;
|
||||
mHard[32] = ST_SOFT;
|
||||
mHard[9] = ST_SOFT;
|
||||
mHard[13] = ST_SOFT;
|
||||
mHard[10] = ST_SOFT;
|
||||
}
|
||||
|
||||
void SetFile(const char *fname); // use this file as source data to parse.
|
||||
|
||||
void SetSourceData(char *data, int len)
|
||||
{
|
||||
mData = data;
|
||||
mLen = len;
|
||||
mMyAlloc = false;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
{
|
||||
mHard[(int)c] = ST_HARD;
|
||||
}
|
||||
|
||||
void SetHard(char c) // add a hard separator
|
||||
{
|
||||
mHard[(int)c] = ST_HARD;
|
||||
}
|
||||
|
||||
void SetCommentSymbol(char c) // comment character, treated as 'end of string'
|
||||
{
|
||||
mHard[(int)c] = ST_EOS;
|
||||
}
|
||||
|
||||
void ClearHardSeparator(char c)
|
||||
{
|
||||
mHard[(int)c] = ST_DATA;
|
||||
}
|
||||
|
||||
void DefaultSymbols(void); // set up default symbols for hard separator and comment symbol of the '#' character.
|
||||
|
||||
bool EOS(char c)
|
||||
{
|
||||
if (mHard[(int)c] == ST_EOS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetQuoteChar(char c)
|
||||
{
|
||||
mQuoteChar = c;
|
||||
}
|
||||
|
||||
private:
|
||||
inline char *AddHard(int &argc, const char **argv, char *foo);
|
||||
inline bool IsHard(char c);
|
||||
inline char *SkipSpaces(char *foo);
|
||||
inline bool IsWhiteSpace(char c);
|
||||
inline bool IsNonSeparator(char c); // non separator, neither hard nor soft
|
||||
|
||||
bool mMyAlloc; // whether or not *I* allocated the buffer and am responsible for deleting it.
|
||||
char *mData; // ascii data to parse.
|
||||
int mLen; // length of data
|
||||
SeparatorType mHard[256];
|
||||
char mHardString[256 * 2];
|
||||
char mQuoteChar;
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
/******************** InParser.cpp ********************************/
|
||||
/*******************************************************************/
|
||||
void InPlaceParser::SetFile(const char *fname)
|
||||
{
|
||||
if (mMyAlloc)
|
||||
{
|
||||
free(mData);
|
||||
}
|
||||
mData = 0;
|
||||
mLen = 0;
|
||||
mMyAlloc = false;
|
||||
|
||||
FILE *fph = fopen(fname, "rb");
|
||||
if (fph)
|
||||
{
|
||||
fseek(fph, 0L, SEEK_END);
|
||||
mLen = ftell(fph);
|
||||
fseek(fph, 0L, SEEK_SET);
|
||||
if (mLen)
|
||||
{
|
||||
mData = (char *)malloc(sizeof(char) * (mLen + 1));
|
||||
int ok = fread(mData, mLen, 1, fph);
|
||||
if (!ok)
|
||||
{
|
||||
free(mData);
|
||||
mData = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mData[mLen] = 0; // zero byte terminate end of file marker.
|
||||
mMyAlloc = true;
|
||||
}
|
||||
}
|
||||
fclose(fph);
|
||||
}
|
||||
}
|
||||
|
||||
InPlaceParser::~InPlaceParser(void)
|
||||
{
|
||||
if (mMyAlloc)
|
||||
{
|
||||
free(mData);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXARGS 512
|
||||
|
||||
bool InPlaceParser::IsHard(char c)
|
||||
{
|
||||
return mHard[(int)c] == ST_HARD;
|
||||
}
|
||||
|
||||
char *InPlaceParser::AddHard(int &argc, const char **argv, char *foo)
|
||||
{
|
||||
while (IsHard(*foo))
|
||||
{
|
||||
const char *hard = &mHardString[*foo * 2];
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = hard;
|
||||
}
|
||||
foo++;
|
||||
}
|
||||
return foo;
|
||||
}
|
||||
|
||||
bool InPlaceParser::IsWhiteSpace(char c)
|
||||
{
|
||||
return mHard[(int)c] == ST_SOFT;
|
||||
}
|
||||
|
||||
char *InPlaceParser::SkipSpaces(char *foo)
|
||||
{
|
||||
while (!EOS(*foo) && IsWhiteSpace(*foo)) foo++;
|
||||
return foo;
|
||||
}
|
||||
|
||||
bool InPlaceParser::IsNonSeparator(char c)
|
||||
{
|
||||
if (!IsHard(c) && !IsWhiteSpace(c) && c != 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int InPlaceParser::ProcessLine(int lineno, char *line, InPlaceParserInterface *callback)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
const char *argv[MAXARGS];
|
||||
int argc = 0;
|
||||
|
||||
char *foo = line;
|
||||
|
||||
while (!EOS(*foo) && argc < MAXARGS)
|
||||
{
|
||||
foo = SkipSpaces(foo); // skip any leading spaces
|
||||
|
||||
if (EOS(*foo)) break;
|
||||
|
||||
if (*foo == mQuoteChar) // if it is an open quote
|
||||
{
|
||||
foo++;
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = foo;
|
||||
}
|
||||
while (!EOS(*foo) && *foo != mQuoteChar) foo++;
|
||||
if (!EOS(*foo))
|
||||
{
|
||||
*foo = 0; // replace close quote with zero byte EOS
|
||||
foo++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foo = AddHard(argc, argv, foo); // add any hard separators, skip any spaces
|
||||
|
||||
if (IsNonSeparator(*foo)) // add non-hard argument.
|
||||
{
|
||||
bool quote = false;
|
||||
if (*foo == mQuoteChar)
|
||||
{
|
||||
foo++;
|
||||
quote = true;
|
||||
}
|
||||
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = foo;
|
||||
}
|
||||
|
||||
if (quote)
|
||||
{
|
||||
while (*foo && *foo != mQuoteChar) foo++;
|
||||
if (*foo) *foo = 32;
|
||||
}
|
||||
|
||||
// continue..until we hit an eos ..
|
||||
while (!EOS(*foo)) // until we hit EOS
|
||||
{
|
||||
if (IsWhiteSpace(*foo)) // if we hit a space, stomp a zero byte, and exit
|
||||
{
|
||||
*foo = 0;
|
||||
foo++;
|
||||
break;
|
||||
}
|
||||
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];
|
||||
*foo = 0;
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = hard;
|
||||
}
|
||||
foo++;
|
||||
break;
|
||||
}
|
||||
foo++;
|
||||
} // end of while loop...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argc)
|
||||
{
|
||||
ret = callback->ParseLine(lineno, argc, argv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason
|
||||
{
|
||||
assert(callback);
|
||||
if (!mData) return 0;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
int lineno = 0;
|
||||
|
||||
char *foo = mData;
|
||||
char *begin = foo;
|
||||
|
||||
while (*foo)
|
||||
{
|
||||
if (*foo == 10 || *foo == 13)
|
||||
{
|
||||
lineno++;
|
||||
*foo = 0;
|
||||
|
||||
if (*begin) // if there is any data to parse at all...
|
||||
{
|
||||
int v = ProcessLine(lineno, begin, callback);
|
||||
if (v) ret = v;
|
||||
}
|
||||
|
||||
foo++;
|
||||
if (*foo == 10) foo++; // skip line feed, if it is in the carraige-return line-feed format...
|
||||
begin = foo;
|
||||
}
|
||||
else
|
||||
{
|
||||
foo++;
|
||||
}
|
||||
}
|
||||
|
||||
lineno++; // lasst line.
|
||||
|
||||
int v = ProcessLine(lineno, begin, callback);
|
||||
if (v) ret = v;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InPlaceParser::DefaultSymbols(void)
|
||||
{
|
||||
SetHardSeparator(',');
|
||||
SetHardSeparator('(');
|
||||
SetHardSeparator(')');
|
||||
SetHardSeparator('=');
|
||||
SetHardSeparator('[');
|
||||
SetHardSeparator(']');
|
||||
SetHardSeparator('{');
|
||||
SetHardSeparator('}');
|
||||
SetCommentSymbol('#');
|
||||
}
|
||||
|
||||
const char **InPlaceParser::GetArglist(char *line, int &count) // convert source string into an arg list, this is a destructive parse.
|
||||
{
|
||||
const char **ret = 0;
|
||||
|
||||
static const char *argv[MAXARGS];
|
||||
int argc = 0;
|
||||
|
||||
char *foo = line;
|
||||
|
||||
while (!EOS(*foo) && argc < MAXARGS)
|
||||
{
|
||||
foo = SkipSpaces(foo); // skip any leading spaces
|
||||
|
||||
if (EOS(*foo)) break;
|
||||
|
||||
if (*foo == mQuoteChar) // if it is an open quote
|
||||
{
|
||||
foo++;
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = foo;
|
||||
}
|
||||
while (!EOS(*foo) && *foo != mQuoteChar) foo++;
|
||||
if (!EOS(*foo))
|
||||
{
|
||||
*foo = 0; // replace close quote with zero byte EOS
|
||||
foo++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foo = AddHard(argc, argv, foo); // add any hard separators, skip any spaces
|
||||
|
||||
if (IsNonSeparator(*foo)) // add non-hard argument.
|
||||
{
|
||||
bool quote = false;
|
||||
if (*foo == mQuoteChar)
|
||||
{
|
||||
foo++;
|
||||
quote = true;
|
||||
}
|
||||
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = foo;
|
||||
}
|
||||
|
||||
if (quote)
|
||||
{
|
||||
while (*foo && *foo != mQuoteChar) foo++;
|
||||
if (*foo) *foo = 32;
|
||||
}
|
||||
|
||||
// continue..until we hit an eos ..
|
||||
while (!EOS(*foo)) // until we hit EOS
|
||||
{
|
||||
if (IsWhiteSpace(*foo)) // if we hit a space, stomp a zero byte, and exit
|
||||
{
|
||||
*foo = 0;
|
||||
foo++;
|
||||
break;
|
||||
}
|
||||
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];
|
||||
*foo = 0;
|
||||
if (argc < MAXARGS)
|
||||
{
|
||||
argv[argc++] = hard;
|
||||
}
|
||||
foo++;
|
||||
break;
|
||||
}
|
||||
foo++;
|
||||
} // end of while loop...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = argc;
|
||||
if (argc)
|
||||
{
|
||||
ret = argv;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/******************** Geometry.h ********************************/
|
||||
/*******************************************************************/
|
||||
|
||||
class GeometryVertex
|
||||
{
|
||||
public:
|
||||
float mPos[3];
|
||||
float mNormal[3];
|
||||
float mTexel[2];
|
||||
};
|
||||
|
||||
class GeometryInterface
|
||||
{
|
||||
public:
|
||||
virtual void NodeTriangle(const GeometryVertex *v1, const GeometryVertex *v2, const GeometryVertex *v3) {}
|
||||
|
||||
virtual ~GeometryInterface() {}
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
/******************** Obj.h ********************************/
|
||||
/*******************************************************************/
|
||||
|
||||
class OBJ : public InPlaceParserInterface
|
||||
{
|
||||
public:
|
||||
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
|
||||
private:
|
||||
void getVertex(GeometryVertex &v, const char *face) const;
|
||||
|
||||
FloatVector mVerts;
|
||||
FloatVector mTexels;
|
||||
FloatVector mNormals;
|
||||
|
||||
GeometryInterface *mCallback;
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
/******************** Obj.cpp ********************************/
|
||||
/*******************************************************************/
|
||||
|
||||
int OBJ::LoadMesh(const char *fname, GeometryInterface *iface)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mVerts.clear();
|
||||
mTexels.clear();
|
||||
mNormals.clear();
|
||||
|
||||
mCallback = iface;
|
||||
|
||||
InPlaceParser ipp(fname);
|
||||
|
||||
ipp.Parse(this);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//static const char * GetArg(const char **argv,int i,int argc)
|
||||
//{
|
||||
// const char * ret = 0;
|
||||
// if ( i < argc ) ret = argv[i];
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
void OBJ::getVertex(GeometryVertex &v, const char *face) const
|
||||
{
|
||||
v.mPos[0] = 0;
|
||||
v.mPos[1] = 0;
|
||||
v.mPos[2] = 0;
|
||||
|
||||
v.mTexel[0] = 0;
|
||||
v.mTexel[1] = 0;
|
||||
|
||||
v.mNormal[0] = 0;
|
||||
v.mNormal[1] = 1;
|
||||
v.mNormal[2] = 0;
|
||||
|
||||
int index = atoi(face) - 1;
|
||||
|
||||
const char *texel = strstr(face, "/");
|
||||
|
||||
if (texel)
|
||||
{
|
||||
int tindex = atoi(texel + 1) - 1;
|
||||
|
||||
if (tindex >= 0 && tindex < (int)(mTexels.size() / 2))
|
||||
{
|
||||
const float *t = &mTexels[tindex * 2];
|
||||
|
||||
v.mTexel[0] = t[0];
|
||||
v.mTexel[1] = t[1];
|
||||
}
|
||||
|
||||
const char *normal = strstr(texel + 1, "/");
|
||||
if (normal)
|
||||
{
|
||||
int nindex = atoi(normal + 1) - 1;
|
||||
|
||||
if (nindex >= 0 && nindex < (int)(mNormals.size() / 3))
|
||||
{
|
||||
const float *n = &mNormals[nindex * 3];
|
||||
|
||||
v.mNormal[0] = n[0];
|
||||
v.mNormal[1] = n[1];
|
||||
v.mNormal[2] = n[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0 && index < (int)(mVerts.size() / 3))
|
||||
{
|
||||
const float *p = &mVerts[index * 3];
|
||||
|
||||
v.mPos[0] = p[0];
|
||||
v.mPos[1] = p[1];
|
||||
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 ret = 0;
|
||||
|
||||
if (argc >= 1)
|
||||
{
|
||||
const char *foo = argv[0];
|
||||
if (*foo != '#')
|
||||
{
|
||||
if (strcmp(argv[0], "v") == 0 && argc == 4)
|
||||
|
||||
//if ( stricmp(argv[0],"v") == 0 && argc == 4 )
|
||||
{
|
||||
float vx = (float)atof(argv[1]);
|
||||
float vy = (float)atof(argv[2]);
|
||||
float vz = (float)atof(argv[3]);
|
||||
mVerts.push_back(vx);
|
||||
mVerts.push_back(vy);
|
||||
mVerts.push_back(vz);
|
||||
}
|
||||
else if (strcmp(argv[0], "vt") == 0 && argc == 3)
|
||||
|
||||
// else if ( stricmp(argv[0],"vt") == 0 && argc == 3 )
|
||||
{
|
||||
float tx = (float)atof(argv[1]);
|
||||
float ty = (float)atof(argv[2]);
|
||||
mTexels.push_back(tx);
|
||||
mTexels.push_back(ty);
|
||||
}
|
||||
// else if ( stricmp(argv[0],"vn") == 0 && argc == 4 )
|
||||
|
||||
else if (strcmp(argv[0], "vn") == 0 && argc == 4)
|
||||
{
|
||||
float normalx = (float)atof(argv[1]);
|
||||
float normaly = (float)atof(argv[2]);
|
||||
float normalz = (float)atof(argv[3]);
|
||||
mNormals.push_back(normalx);
|
||||
mNormals.push_back(normaly);
|
||||
mNormals.push_back(normalz);
|
||||
}
|
||||
// else if ( stricmp(argv[0],"f") == 0 && argc >= 4 )
|
||||
|
||||
else if (strcmp(argv[0], "f") == 0 && argc >= 4)
|
||||
{
|
||||
GeometryVertex v[32];
|
||||
|
||||
int vcount = argc - 1;
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
getVertex(v[i - 1], argv[i]);
|
||||
}
|
||||
|
||||
// need to generate a normal!
|
||||
#if 0 // not currently implemented
|
||||
if ( mNormals.empty() )
|
||||
{
|
||||
Vector3d<float> p1( v[0].mPos );
|
||||
Vector3d<float> p2( v[1].mPos );
|
||||
Vector3d<float> p3( v[2].mPos );
|
||||
|
||||
Vector3d<float> n;
|
||||
n.ComputeNormal(p3,p2,p1);
|
||||
|
||||
for (int i=0; i<vcount; i++)
|
||||
{
|
||||
v[i].mNormal[0] = n.x;
|
||||
v[i].mNormal[1] = n.y;
|
||||
v[i].mNormal[2] = n.z;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
mCallback->NodeTriangle(&v[0], &v[1], &v[2]);
|
||||
|
||||
if (vcount >= 3) // do the fan
|
||||
{
|
||||
for (int i = 2; i < (vcount - 1); i++)
|
||||
{
|
||||
mCallback->NodeTriangle(&v[0], &v[i], &v[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
class BuildMesh : public GeometryInterface
|
||||
{
|
||||
public:
|
||||
int getIndex(const float *p)
|
||||
{
|
||||
int vcount = mVertices.size() / 3;
|
||||
|
||||
if (vcount > 0)
|
||||
{
|
||||
//New MS STL library checks indices in debug build, so zero causes an assert if it is empty.
|
||||
const float *v = &mVertices[0];
|
||||
|
||||
for (int i = 0; i < vcount; i++)
|
||||
{
|
||||
if (v[0] == p[0] && v[1] == p[1] && v[2] == p[2]) return i;
|
||||
v += 3;
|
||||
}
|
||||
}
|
||||
|
||||
mVertices.push_back(p[0]);
|
||||
mVertices.push_back(p[1]);
|
||||
mVertices.push_back(p[2]);
|
||||
|
||||
return vcount;
|
||||
}
|
||||
|
||||
virtual void NodeTriangle(const GeometryVertex *v1, const GeometryVertex *v2, const GeometryVertex *v3)
|
||||
{
|
||||
mIndices.push_back(getIndex(v1->mPos));
|
||||
mIndices.push_back(getIndex(v2->mPos));
|
||||
mIndices.push_back(getIndex(v3->mPos));
|
||||
}
|
||||
|
||||
const FloatVector &GetVertices(void) const { return mVertices; };
|
||||
const IntVector &GetIndices(void) const { return mIndices; };
|
||||
|
||||
private:
|
||||
FloatVector mVertices;
|
||||
IntVector mIndices;
|
||||
};
|
||||
|
||||
WavefrontObj::WavefrontObj(void)
|
||||
{
|
||||
mVertexCount = 0;
|
||||
mTriCount = 0;
|
||||
mIndices = 0;
|
||||
mVertices = 0;
|
||||
}
|
||||
|
||||
WavefrontObj::~WavefrontObj(void)
|
||||
{
|
||||
delete[] mIndices;
|
||||
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 ret = 0;
|
||||
|
||||
delete[] mVertices;
|
||||
mVertices = 0;
|
||||
delete[] mIndices;
|
||||
mIndices = 0;
|
||||
mVertexCount = 0;
|
||||
mTriCount = 0;
|
||||
|
||||
BuildMesh bm;
|
||||
|
||||
OBJ obj;
|
||||
|
||||
obj.LoadMesh(fname, &bm);
|
||||
|
||||
const FloatVector &vlist = bm.GetVertices();
|
||||
const IntVector &indices = bm.GetIndices();
|
||||
if (vlist.size())
|
||||
{
|
||||
mVertexCount = vlist.size() / 3;
|
||||
mVertices = new float[mVertexCount * 3];
|
||||
memcpy(mVertices, &vlist[0], sizeof(float) * mVertexCount * 3);
|
||||
mTriCount = indices.size() / 3;
|
||||
mIndices = new int[mTriCount * 3 * sizeof(int)];
|
||||
memcpy(mIndices, &indices[0], sizeof(int) * mTriCount * 3);
|
||||
ret = mTriCount;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
57
Engine/lib/bullet/Extras/ConvexDecomposition/cd_wavefront.h
Normal file
57
Engine/lib/bullet/Extras/ConvexDecomposition/cd_wavefront.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef CD_WAVEFRONT_OBJ_H
|
||||
|
||||
#define CD_WAVEFRONT_OBJ_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
class WavefrontObj
|
||||
{
|
||||
public:
|
||||
WavefrontObj(void);
|
||||
~WavefrontObj(void);
|
||||
|
||||
unsigned int loadObj(const char *fname); // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed.
|
||||
|
||||
int mVertexCount;
|
||||
int mTriCount;
|
||||
int *mIndices;
|
||||
float *mVertices;
|
||||
};
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
|
||||
#endif
|
||||
761
Engine/lib/bullet/Extras/ConvexDecomposition/concavity.cpp
Normal file
761
Engine/lib/bullet/Extras/ConvexDecomposition/concavity.cpp
Normal file
|
|
@ -0,0 +1,761 @@
|
|||
#include "float_math.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
#include "concavity.h"
|
||||
#include "raytri.h"
|
||||
#include "bestfit.h"
|
||||
#include "cd_hull.h"
|
||||
#include "meshvolume.h"
|
||||
#include "cd_vector.h"
|
||||
#include "splitplane.h"
|
||||
#include "ConvexDecomposition.h"
|
||||
|
||||
#define WSCALE 4
|
||||
#define CONCAVE_THRESH 0.05f
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
unsigned int getDebugColor(void)
|
||||
{
|
||||
static unsigned int colors[8] =
|
||||
{
|
||||
0xFF0000,
|
||||
0x00FF00,
|
||||
0x0000FF,
|
||||
0xFFFF00,
|
||||
0x00FFFF,
|
||||
0xFF00FF,
|
||||
0xFFFFFF,
|
||||
0xFF8040};
|
||||
|
||||
static int count = 0;
|
||||
|
||||
count++;
|
||||
|
||||
if (count == 8) count = 0;
|
||||
|
||||
assert(count >= 0 && count < 8);
|
||||
|
||||
unsigned int color = colors[count];
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
class Wpoint
|
||||
{
|
||||
public:
|
||||
Wpoint(const Vector3d &p, float w)
|
||||
{
|
||||
mPoint = p;
|
||||
mWeight = w;
|
||||
}
|
||||
|
||||
Vector3d mPoint;
|
||||
float mWeight;
|
||||
};
|
||||
|
||||
typedef std::vector<Wpoint> WpointVector;
|
||||
|
||||
static inline float DistToPt(const float *p, const float *plane)
|
||||
{
|
||||
float x = p[0];
|
||||
float y = p[1];
|
||||
float z = p[2];
|
||||
float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3];
|
||||
return d;
|
||||
}
|
||||
|
||||
static void intersect(const float *p1, const float *p2, float *split, const float *plane)
|
||||
{
|
||||
float dp1 = DistToPt(p1, plane);
|
||||
|
||||
float dir[3];
|
||||
|
||||
dir[0] = p2[0] - p1[0];
|
||||
dir[1] = p2[1] - p1[1];
|
||||
dir[2] = p2[2] - p1[2];
|
||||
|
||||
float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2];
|
||||
float dot2 = dp1 - plane[3];
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
class CTri
|
||||
{
|
||||
public:
|
||||
CTri(void){};
|
||||
|
||||
CTri(const float *p1, const float *p2, const float *p3, unsigned int i1, unsigned int i2, unsigned int i3)
|
||||
{
|
||||
mProcessed = 0;
|
||||
mI1 = i1;
|
||||
mI2 = i2;
|
||||
mI3 = i3;
|
||||
|
||||
mP1.Set(p1);
|
||||
mP2.Set(p2);
|
||||
mP3.Set(p3);
|
||||
|
||||
mPlaneD = mNormal.ComputePlane(mP1, mP2, mP3);
|
||||
}
|
||||
|
||||
float Facing(const CTri &t)
|
||||
{
|
||||
float d = mNormal.Dot(t.mNormal);
|
||||
return d;
|
||||
}
|
||||
|
||||
// clip this line segment against this triangle.
|
||||
bool clip(const Vector3d &start, Vector3d &end) const
|
||||
{
|
||||
Vector3d sect;
|
||||
|
||||
bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr());
|
||||
|
||||
if (hit)
|
||||
{
|
||||
end = sect;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool Concave(const Vector3d &p, float &distance, Vector3d &n) const
|
||||
{
|
||||
n.NearestPointInTriangle(p, mP1, mP2, mP3);
|
||||
distance = p.Distance(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
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 + 1] = i2;
|
||||
indices[tcount * 3 + 2] = i3;
|
||||
tcount++;
|
||||
}
|
||||
|
||||
float getVolume(ConvexDecompInterface *callback) const
|
||||
{
|
||||
unsigned int indices[8 * 3];
|
||||
|
||||
unsigned int tcount = 0;
|
||||
|
||||
addTri(indices, 0, 1, 2, tcount);
|
||||
addTri(indices, 3, 4, 5, tcount);
|
||||
|
||||
addTri(indices, 0, 3, 4, tcount);
|
||||
addTri(indices, 0, 4, 1, tcount);
|
||||
|
||||
addTri(indices, 1, 4, 5, tcount);
|
||||
addTri(indices, 1, 5, 2, tcount);
|
||||
|
||||
addTri(indices, 0, 3, 5, tcount);
|
||||
addTri(indices, 0, 5, 2, tcount);
|
||||
|
||||
const float *vertices = mP1.Ptr();
|
||||
|
||||
if (callback)
|
||||
{
|
||||
unsigned int color = getDebugColor();
|
||||
|
||||
#if 0
|
||||
Vector3d d1 = mNear1;
|
||||
Vector3d d2 = mNear2;
|
||||
Vector3d d3 = mNear3;
|
||||
|
||||
callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00);
|
||||
callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00);
|
||||
callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00);
|
||||
callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000);
|
||||
callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000);
|
||||
callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000);
|
||||
|
||||
callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00);
|
||||
callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00);
|
||||
callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00);
|
||||
|
||||
#else
|
||||
for (unsigned int i = 0; i < tcount; i++)
|
||||
{
|
||||
unsigned int i1 = indices[i * 3 + 0];
|
||||
unsigned int i2 = indices[i * 3 + 1];
|
||||
unsigned int i3 = indices[i * 3 + 2];
|
||||
|
||||
const float *p1 = &vertices[i1 * 3];
|
||||
const float *p2 = &vertices[i2 * 3];
|
||||
const float *p3 = &vertices[i3 * 3];
|
||||
|
||||
callback->ConvexDebugTri(p1, p2, p3, color);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
float v = computeMeshVolume(mP1.Ptr(), tcount, indices);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
float raySect(const Vector3d &p, const Vector3d &dir, Vector3d §) const
|
||||
{
|
||||
float plane[4];
|
||||
|
||||
plane[0] = mNormal.x;
|
||||
plane[1] = mNormal.y;
|
||||
plane[2] = mNormal.z;
|
||||
plane[3] = mPlaneD;
|
||||
|
||||
Vector3d dest = p + dir * 100000;
|
||||
|
||||
intersect(p.Ptr(), dest.Ptr(), sect.Ptr(), plane);
|
||||
|
||||
return sect.Distance(p); // return the intersection distance.
|
||||
}
|
||||
|
||||
float planeDistance(const Vector3d &p) const
|
||||
{
|
||||
float plane[4];
|
||||
|
||||
plane[0] = mNormal.x;
|
||||
plane[1] = mNormal.y;
|
||||
plane[2] = mNormal.z;
|
||||
plane[3] = mPlaneD;
|
||||
|
||||
return DistToPt(p.Ptr(), plane);
|
||||
}
|
||||
|
||||
bool samePlane(const CTri &t) const
|
||||
{
|
||||
const float THRESH = 0.001f;
|
||||
float dd = fabsf(t.mPlaneD - mPlaneD);
|
||||
if (dd > THRESH) return false;
|
||||
dd = fabsf(t.mNormal.x - mNormal.x);
|
||||
if (dd > THRESH) return false;
|
||||
dd = fabsf(t.mNormal.y - mNormal.y);
|
||||
if (dd > THRESH) return false;
|
||||
dd = fabsf(t.mNormal.z - mNormal.z);
|
||||
if (dd > THRESH) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasIndex(unsigned int i) const
|
||||
{
|
||||
if (i == mI1 || i == mI2 || i == mI3) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sharesEdge(const CTri &t) const
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned int count = 0;
|
||||
|
||||
if (t.hasIndex(mI1)) count++;
|
||||
if (t.hasIndex(mI2)) count++;
|
||||
if (t.hasIndex(mI3)) count++;
|
||||
|
||||
if (count >= 2) ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void debug(unsigned int color, ConvexDecompInterface *callback)
|
||||
{
|
||||
callback->ConvexDebugTri(mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color);
|
||||
callback->ConvexDebugTri(mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000);
|
||||
callback->ConvexDebugTri(mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000);
|
||||
callback->ConvexDebugTri(mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000);
|
||||
callback->ConvexDebugPoint(mNear1.Ptr(), 0.01f, 0xFF0000);
|
||||
callback->ConvexDebugPoint(mNear2.Ptr(), 0.01f, 0xFF0000);
|
||||
callback->ConvexDebugPoint(mNear3.Ptr(), 0.01f, 0xFF0000);
|
||||
}
|
||||
|
||||
float area(void)
|
||||
{
|
||||
float a = mConcavity * mP1.Area(mP2, mP3);
|
||||
return a;
|
||||
}
|
||||
|
||||
void addWeighted(WpointVector &list, ConvexDecompInterface *callback)
|
||||
{
|
||||
Wpoint p1(mP1, mC1);
|
||||
Wpoint p2(mP2, mC2);
|
||||
Wpoint p3(mP3, mC3);
|
||||
|
||||
Vector3d d1 = mNear1 - mP1;
|
||||
Vector3d d2 = mNear2 - mP2;
|
||||
Vector3d d3 = mNear3 - mP3;
|
||||
|
||||
d1 *= WSCALE;
|
||||
d2 *= WSCALE;
|
||||
d3 *= WSCALE;
|
||||
|
||||
d1 = d1 + mP1;
|
||||
d2 = d2 + mP2;
|
||||
d3 = d3 + mP3;
|
||||
|
||||
Wpoint p4(d1, mC1);
|
||||
Wpoint p5(d2, mC2);
|
||||
Wpoint p6(d3, mC3);
|
||||
|
||||
list.push_back(p1);
|
||||
list.push_back(p2);
|
||||
list.push_back(p3);
|
||||
|
||||
list.push_back(p4);
|
||||
list.push_back(p5);
|
||||
list.push_back(p6);
|
||||
|
||||
#if 0
|
||||
callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00);
|
||||
callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00);
|
||||
callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00);
|
||||
callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000);
|
||||
callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000);
|
||||
callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000);
|
||||
|
||||
callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00);
|
||||
callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00);
|
||||
callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00);
|
||||
|
||||
Vector3d np1 = mP1 + mNormal*0.05f;
|
||||
Vector3d np2 = mP2 + mNormal*0.05f;
|
||||
Vector3d np3 = mP3 + mNormal*0.05f;
|
||||
|
||||
callback->ConvexDebugTri(mP1.Ptr(), np1.Ptr(), np1.Ptr(), 0xFF00FF );
|
||||
callback->ConvexDebugTri(mP2.Ptr(), np2.Ptr(), np2.Ptr(), 0xFF00FF );
|
||||
callback->ConvexDebugTri(mP3.Ptr(), np3.Ptr(), np3.Ptr(), 0xFF00FF );
|
||||
|
||||
callback->ConvexDebugPoint( np1.Ptr(), 0.01F, 0XFF00FF );
|
||||
callback->ConvexDebugPoint( np2.Ptr(), 0.01F, 0XFF00FF );
|
||||
callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Vector3d mP1;
|
||||
Vector3d mP2;
|
||||
Vector3d mP3;
|
||||
Vector3d mNear1;
|
||||
Vector3d mNear2;
|
||||
Vector3d mNear3;
|
||||
Vector3d mNormal;
|
||||
float mPlaneD;
|
||||
float mConcavity;
|
||||
float mC1;
|
||||
float mC2;
|
||||
float mC3;
|
||||
unsigned int mI1;
|
||||
unsigned int mI2;
|
||||
unsigned int mI3;
|
||||
int mProcessed; // already been added...
|
||||
};
|
||||
|
||||
typedef std::vector<CTri> CTriVector;
|
||||
|
||||
bool featureMatch(CTri &m, const CTriVector &tris, ConvexDecompInterface *callback, const CTriVector &input_mesh)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
float neardot = 0.707f;
|
||||
|
||||
m.mConcavity = 0;
|
||||
|
||||
//gLog->Display("*********** FEATURE MATCH *************\r\n");
|
||||
//gLog->Display("Plane: %0.4f,%0.4f,%0.4f %0.4f\r\n", m.mNormal.x, m.mNormal.y, m.mNormal.z, m.mPlaneD );
|
||||
//gLog->Display("*********************************************\r\n");
|
||||
|
||||
CTriVector::const_iterator i;
|
||||
|
||||
CTri nearest;
|
||||
|
||||
for (i = tris.begin(); i != tris.end(); ++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 );
|
||||
|
||||
if (t.samePlane(m))
|
||||
{
|
||||
//gLog->Display("*** PLANE MATCH!!!\r\n");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
float dot = t.mNormal.Dot(m.mNormal);
|
||||
|
||||
if (dot > neardot)
|
||||
{
|
||||
float d1 = t.planeDistance(m.mP1);
|
||||
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;
|
||||
|
||||
Vector3d n1, n2, n3;
|
||||
|
||||
t.raySect(m.mP1, m.mNormal, m.mNear1);
|
||||
t.raySect(m.mP2, m.mNormal, m.mNear2);
|
||||
t.raySect(m.mP3, m.mNormal, m.mNear3);
|
||||
|
||||
nearest = t;
|
||||
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
CTriVector::const_iterator i;
|
||||
for (i = input_mesh.begin(); i != input_mesh.end(); ++i)
|
||||
{
|
||||
const CTri &c = (*i);
|
||||
if (c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3)
|
||||
{
|
||||
c.clip(m.mP1, m.mNear1);
|
||||
c.clip(m.mP2, m.mNear2);
|
||||
c.clip(m.mP3, m.mNear3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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 );
|
||||
|
||||
m.mC1 = m.mP1.Distance(m.mNear1);
|
||||
m.mC2 = m.mP2.Distance(m.mNear2);
|
||||
m.mC3 = m.mP3.Distance(m.mNear3);
|
||||
|
||||
m.mConcavity = m.mC1;
|
||||
|
||||
if (m.mC2 > m.mConcavity) m.mConcavity = m.mC2;
|
||||
if (m.mC3 > m.mConcavity) m.mConcavity = m.mC3;
|
||||
|
||||
#if 0
|
||||
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.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.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 );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
//gLog->Display("No match\r\n");
|
||||
}
|
||||
|
||||
//gLog->Display("*********************************************\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool isFeatureTri(CTri &t, CTriVector &flist, float fc, ConvexDecompInterface *callback, unsigned int color)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (t.mProcessed == 0) // if not already processed
|
||||
{
|
||||
float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent.
|
||||
|
||||
if (c > 0.85f)
|
||||
{
|
||||
// see if this triangle is a 'feature' triangle. Meaning it shares an
|
||||
// edge with any existing feature triangle and is within roughly the same
|
||||
// concavity of the parent.
|
||||
if (flist.size())
|
||||
{
|
||||
CTriVector::iterator i;
|
||||
for (i = flist.begin(); i != flist.end(); ++i)
|
||||
{
|
||||
CTri &ftri = (*i);
|
||||
if (ftri.sharesEdge(t))
|
||||
{
|
||||
t.mProcessed = 2; // it is now part of a feature.
|
||||
flist.push_back(t); // add it to the feature list.
|
||||
// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t.mProcessed = 2;
|
||||
flist.push_back(t); // add it to the feature list.
|
||||
// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one..
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float computeConcavity(unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int tcount,
|
||||
const unsigned int *indices,
|
||||
ConvexDecompInterface *callback,
|
||||
float *plane, // plane equation to split on
|
||||
float &volume)
|
||||
{
|
||||
float cret = 0;
|
||||
volume = 1;
|
||||
|
||||
HullResult result;
|
||||
HullLibrary hl;
|
||||
HullDesc desc;
|
||||
|
||||
desc.mMaxFaces = 256;
|
||||
desc.mMaxVertices = 256;
|
||||
desc.SetHullFlag(QF_TRIANGLES);
|
||||
|
||||
desc.mVcount = vcount;
|
||||
desc.mVertices = vertices;
|
||||
desc.mVertexStride = sizeof(float) * 3;
|
||||
|
||||
HullError ret = hl.CreateConvexHull(desc, result);
|
||||
|
||||
if (ret == QE_OK)
|
||||
{
|
||||
#if 0
|
||||
float bmin[3];
|
||||
float bmax[3];
|
||||
|
||||
float dx = bmax[0] - bmin[0];
|
||||
float dy = bmax[1] - bmin[1];
|
||||
float dz = bmax[2] - bmin[2];
|
||||
|
||||
Vector3d center;
|
||||
|
||||
center.x = bmin[0] + dx*0.5f;
|
||||
center.y = bmin[1] + dy*0.5f;
|
||||
center.z = bmin[2] + dz*0.5f;
|
||||
#endif
|
||||
|
||||
volume = computeMeshVolume2(result.mOutputVertices, result.mNumFaces, result.mIndices);
|
||||
|
||||
#if 1
|
||||
// ok..now..for each triangle on the original mesh..
|
||||
// we extrude the points to the nearest point on the hull.
|
||||
const unsigned int *source = result.mIndices;
|
||||
|
||||
CTriVector tris;
|
||||
|
||||
for (unsigned int i = 0; i < result.mNumFaces; i++)
|
||||
{
|
||||
unsigned int i1 = *source++;
|
||||
unsigned int i2 = *source++;
|
||||
unsigned int i3 = *source++;
|
||||
|
||||
const float *p1 = &result.mOutputVertices[i1 * 3];
|
||||
const float *p2 = &result.mOutputVertices[i2 * 3];
|
||||
const float *p3 = &result.mOutputVertices[i3 * 3];
|
||||
|
||||
// callback->ConvexDebugTri(p1,p2,p3,0xFFFFFF);
|
||||
|
||||
CTri t(p1, p2, p3, i1, i2, i3); //
|
||||
tris.push_back(t);
|
||||
}
|
||||
|
||||
// we have not pre-computed the plane equation for each triangle in the convex hull..
|
||||
|
||||
float totalVolume = 0;
|
||||
|
||||
CTriVector ftris; // 'feature' triangles.
|
||||
|
||||
const unsigned int *src = indices;
|
||||
|
||||
float maxc = 0;
|
||||
|
||||
if (1)
|
||||
{
|
||||
CTriVector input_mesh;
|
||||
if (1)
|
||||
{
|
||||
const unsigned int *src = indices;
|
||||
for (unsigned int i = 0; i < tcount; i++)
|
||||
{
|
||||
unsigned int i1 = *src++;
|
||||
unsigned int i2 = *src++;
|
||||
unsigned int i3 = *src++;
|
||||
|
||||
const float *p1 = &vertices[i1 * 3];
|
||||
const float *p2 = &vertices[i2 * 3];
|
||||
const float *p3 = &vertices[i3 * 3];
|
||||
|
||||
CTri t(p1, p2, p3, i1, i2, i3);
|
||||
input_mesh.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
CTri maxctri;
|
||||
|
||||
for (unsigned int i = 0; i < tcount; i++)
|
||||
{
|
||||
unsigned int i1 = *src++;
|
||||
unsigned int i2 = *src++;
|
||||
unsigned int i3 = *src++;
|
||||
|
||||
const float *p1 = &vertices[i1 * 3];
|
||||
const float *p2 = &vertices[i2 * 3];
|
||||
const float *p3 = &vertices[i3 * 3];
|
||||
|
||||
CTri t(p1, p2, p3, i1, i2, i3);
|
||||
|
||||
featureMatch(t, tris, callback, input_mesh);
|
||||
|
||||
if (t.mConcavity > CONCAVE_THRESH)
|
||||
{
|
||||
if (t.mConcavity > maxc)
|
||||
{
|
||||
maxc = t.mConcavity;
|
||||
maxctri = t;
|
||||
}
|
||||
|
||||
float v = t.getVolume(0);
|
||||
totalVolume += v;
|
||||
ftris.push_back(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( ftris.size() && 0 )
|
||||
{
|
||||
|
||||
// ok..now we extract the triangles which form the maximum concavity.
|
||||
CTriVector major_feature;
|
||||
float maxarea = 0;
|
||||
|
||||
while ( maxc > CONCAVE_THRESH )
|
||||
{
|
||||
|
||||
unsigned int color = getDebugColor(); //
|
||||
|
||||
CTriVector flist;
|
||||
|
||||
bool found;
|
||||
|
||||
float totalarea = 0;
|
||||
|
||||
do
|
||||
{
|
||||
found = false;
|
||||
CTriVector::iterator i;
|
||||
for (i=ftris.begin(); i!=ftris.end(); ++i)
|
||||
{
|
||||
CTri &t = (*i);
|
||||
if ( isFeatureTri(t,flist,maxc,callback,color) )
|
||||
{
|
||||
found = true;
|
||||
totalarea+=t.area();
|
||||
}
|
||||
}
|
||||
} while ( found );
|
||||
|
||||
|
||||
if ( totalarea > maxarea )
|
||||
{
|
||||
major_feature = flist;
|
||||
maxarea = totalarea;
|
||||
}
|
||||
|
||||
maxc = 0;
|
||||
|
||||
for (unsigned int i=0; i<ftris.size(); i++)
|
||||
{
|
||||
CTri &t = ftris[i];
|
||||
if ( t.mProcessed != 2 )
|
||||
{
|
||||
t.mProcessed = 0;
|
||||
if ( t.mConcavity > maxc )
|
||||
{
|
||||
maxc = t.mConcavity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned int color = getDebugColor();
|
||||
|
||||
WpointVector list;
|
||||
for (unsigned int i=0; i<major_feature.size(); ++i)
|
||||
{
|
||||
major_feature[i].addWeighted(list,callback);
|
||||
major_feature[i].debug(color,callback);
|
||||
}
|
||||
|
||||
getBestFitPlane( list.size(), &list[0].mPoint.x, sizeof(Wpoint), &list[0].mWeight, sizeof(Wpoint), plane );
|
||||
|
||||
computeSplitPlane( vcount, vertices, tcount, indices, callback, plane );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
computeSplitPlane( vcount, vertices, tcount, indices, callback, plane );
|
||||
}
|
||||
#endif
|
||||
|
||||
cret = totalVolume;
|
||||
|
||||
hl.ReleaseResult(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
return cret;
|
||||
}
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
55
Engine/lib/bullet/Extras/ConvexDecomposition/concavity.h
Normal file
55
Engine/lib/bullet/Extras/ConvexDecomposition/concavity.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef COMPUTE_CONCAVITY_H
|
||||
|
||||
#define COMPUTE_CONCAVITY_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
class ConvexDecompInterface;
|
||||
|
||||
// compute's how 'concave' this object is and returns the total volume of the
|
||||
// convex hull as well as the volume of the 'concavity' which was found.
|
||||
float computeConcavity(unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int tcount,
|
||||
const unsigned int *indices,
|
||||
ConvexDecompInterface *callback,
|
||||
float *plane,
|
||||
float &volume);
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
|
||||
#endif
|
||||
197
Engine/lib/bullet/Extras/ConvexDecomposition/fitsphere.cpp
Normal file
197
Engine/lib/bullet/Extras/ConvexDecomposition/fitsphere.cpp
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "fitsphere.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
/*
|
||||
An Efficient Bounding Sphere
|
||||
by Jack Ritter
|
||||
from "Graphics Gems", Academic Press, 1990
|
||||
*/
|
||||
|
||||
/* Routine to calculate tight bounding sphere over */
|
||||
/* a set of points in 3D */
|
||||
/* This contains the routine find_bounding_sphere(), */
|
||||
/* the struct definition, and the globals used for parameters. */
|
||||
/* The abs() of all coordinates must be < BIGNUMBER */
|
||||
/* Code written by Jack Ritter and Lyle Rains. */
|
||||
|
||||
#define BIGNUMBER 100000000.0 /* hundred million */
|
||||
|
||||
static inline void Set(float *n, float x, float y, float z)
|
||||
{
|
||||
n[0] = x;
|
||||
n[1] = y;
|
||||
n[2] = z;
|
||||
}
|
||||
|
||||
static inline void Copy(float *dest, const float *source)
|
||||
{
|
||||
dest[0] = source[0];
|
||||
dest[1] = source[1];
|
||||
dest[2] = source[2];
|
||||
}
|
||||
|
||||
float computeBoundingSphere(unsigned int vcount, const float *points, float *center)
|
||||
{
|
||||
float mRadius;
|
||||
float mRadius2;
|
||||
|
||||
float xmin[3];
|
||||
float xmax[3];
|
||||
float ymin[3];
|
||||
float ymax[3];
|
||||
float zmin[3];
|
||||
float zmax[3];
|
||||
float dia1[3];
|
||||
float dia2[3];
|
||||
|
||||
/* FIRST PASS: find 6 minima/maxima points */
|
||||
Set(xmin, BIGNUMBER, BIGNUMBER, BIGNUMBER);
|
||||
Set(xmax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER);
|
||||
Set(ymin, BIGNUMBER, BIGNUMBER, BIGNUMBER);
|
||||
Set(ymax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER);
|
||||
Set(zmin, BIGNUMBER, BIGNUMBER, BIGNUMBER);
|
||||
Set(zmax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER);
|
||||
|
||||
for (unsigned i = 0; i < vcount; i++)
|
||||
{
|
||||
const float *caller_p = &points[i * 3];
|
||||
|
||||
if (caller_p[0] < xmin[0])
|
||||
Copy(xmin, caller_p); /* New xminimum point */
|
||||
if (caller_p[0] > xmax[0])
|
||||
Copy(xmax, caller_p);
|
||||
if (caller_p[1] < ymin[1])
|
||||
Copy(ymin, caller_p);
|
||||
if (caller_p[1] > ymax[1])
|
||||
Copy(ymax, caller_p);
|
||||
if (caller_p[2] < zmin[2])
|
||||
Copy(zmin, caller_p);
|
||||
if (caller_p[2] > zmax[2])
|
||||
Copy(zmax, caller_p);
|
||||
}
|
||||
|
||||
/* Set xspan = distance between the 2 points xmin & xmax (squared) */
|
||||
float dx = xmax[0] - xmin[0];
|
||||
float dy = xmax[1] - xmin[1];
|
||||
float dz = xmax[2] - xmin[2];
|
||||
float xspan = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
/* Same for y & z spans */
|
||||
dx = ymax[0] - ymin[0];
|
||||
dy = ymax[1] - ymin[1];
|
||||
dz = ymax[2] - ymin[2];
|
||||
float yspan = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
dx = zmax[0] - zmin[0];
|
||||
dy = zmax[1] - zmin[1];
|
||||
dz = zmax[2] - zmin[2];
|
||||
float zspan = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
/* Set points dia1 & dia2 to the maximally separated pair */
|
||||
Copy(dia1, xmin);
|
||||
Copy(dia2, xmax); /* assume xspan biggest */
|
||||
float maxspan = xspan;
|
||||
|
||||
if (yspan > maxspan)
|
||||
{
|
||||
maxspan = yspan;
|
||||
Copy(dia1, ymin);
|
||||
Copy(dia2, ymax);
|
||||
}
|
||||
|
||||
if (zspan > maxspan)
|
||||
{
|
||||
Copy(dia1, zmin);
|
||||
Copy(dia2, zmax);
|
||||
}
|
||||
|
||||
/* dia1,dia2 is a diameter of initial sphere */
|
||||
/* calc initial center */
|
||||
center[0] = (dia1[0] + dia2[0]) * 0.5f;
|
||||
center[1] = (dia1[1] + dia2[1]) * 0.5f;
|
||||
center[2] = (dia1[2] + dia2[2]) * 0.5f;
|
||||
|
||||
/* calculate initial radius**2 and radius */
|
||||
|
||||
dx = dia2[0] - center[0]; /* x component of radius vector */
|
||||
dy = dia2[1] - center[1]; /* y component of radius vector */
|
||||
dz = dia2[2] - center[2]; /* z component of radius vector */
|
||||
|
||||
mRadius2 = dx * dx + dy * dy + dz * dz;
|
||||
mRadius = float(sqrt(mRadius2));
|
||||
|
||||
/* SECOND PASS: increment current sphere */
|
||||
|
||||
if (1)
|
||||
{
|
||||
for (unsigned i = 0; i < vcount; i++)
|
||||
{
|
||||
const float *caller_p = &points[i * 3];
|
||||
|
||||
dx = caller_p[0] - center[0];
|
||||
dy = caller_p[1] - center[1];
|
||||
dz = caller_p[2] - center[2];
|
||||
|
||||
float old_to_p_sq = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
if (old_to_p_sq > mRadius2) /* do r**2 test first */
|
||||
{ /* this point is outside of current sphere */
|
||||
float old_to_p = float(sqrt(old_to_p_sq));
|
||||
/* calc radius of new sphere */
|
||||
mRadius = (mRadius + old_to_p) * 0.5f;
|
||||
mRadius2 = mRadius * mRadius; /* for next r**2 compare */
|
||||
float old_to_new = old_to_p - mRadius;
|
||||
|
||||
/* calc center of new sphere */
|
||||
|
||||
float recip = 1.0f / old_to_p;
|
||||
|
||||
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 cz = (mRadius * center[2] + old_to_new * caller_p[2]) * recip;
|
||||
|
||||
Set(center, cx, cy, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mRadius;
|
||||
}
|
||||
41
Engine/lib/bullet/Extras/ConvexDecomposition/fitsphere.h
Normal file
41
Engine/lib/bullet/Extras/ConvexDecomposition/fitsphere.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef FIT_SPHERE_H
|
||||
|
||||
#define FIT_SPHERE_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
float computeBoundingSphere(unsigned int vcount, const float *points, float *center);
|
||||
|
||||
#endif
|
||||
238
Engine/lib/bullet/Extras/ConvexDecomposition/float_math.cpp
Normal file
238
Engine/lib/bullet/Extras/ConvexDecomposition/float_math.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#include "float_math.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
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 _y = pos[1] - matrix[3 * 4 + 1];
|
||||
float _z = pos[2] - matrix[3 * 4 + 2];
|
||||
|
||||
// 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[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);
|
||||
}
|
||||
|
||||
void fm_identity(float *matrix) // set 4x4 matrix to identity.
|
||||
{
|
||||
matrix[0 * 4 + 0] = 1;
|
||||
matrix[1 * 4 + 1] = 1;
|
||||
matrix[2 * 4 + 2] = 1;
|
||||
matrix[3 * 4 + 3] = 1;
|
||||
|
||||
matrix[1 * 4 + 0] = 0;
|
||||
matrix[2 * 4 + 0] = 0;
|
||||
matrix[3 * 4 + 0] = 0;
|
||||
|
||||
matrix[0 * 4 + 1] = 0;
|
||||
matrix[2 * 4 + 1] = 0;
|
||||
matrix[3 * 4 + 1] = 0;
|
||||
|
||||
matrix[0 * 4 + 2] = 0;
|
||||
matrix[1 * 4 + 2] = 0;
|
||||
matrix[3 * 4 + 2] = 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)
|
||||
{
|
||||
float quat[4];
|
||||
fm_eulerToQuat(ax, ay, az, quat);
|
||||
fm_quatToMatrix(quat, matrix);
|
||||
}
|
||||
|
||||
void fm_getAABB(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax)
|
||||
{
|
||||
const unsigned char *source = (const unsigned char *)points;
|
||||
|
||||
bmin[0] = points[0];
|
||||
bmin[1] = points[1];
|
||||
bmin[2] = points[2];
|
||||
|
||||
bmax[0] = points[0];
|
||||
bmax[1] = points[1];
|
||||
bmax[2] = points[2];
|
||||
|
||||
for (unsigned int i = 1; i < vcount; i++)
|
||||
{
|
||||
source += pstride;
|
||||
const float *p = (const float *)source;
|
||||
|
||||
if (p[0] < bmin[0]) bmin[0] = p[0];
|
||||
if (p[1] < bmin[1]) bmin[1] = p[1];
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
void fm_eulerToQuat(float roll, float pitch, float yaw, float *quat) // convert euler angles to quaternion.
|
||||
{
|
||||
roll *= 0.5f;
|
||||
pitch *= 0.5f;
|
||||
yaw *= 0.5f;
|
||||
|
||||
float cr = cosf(roll);
|
||||
float cp = cosf(pitch);
|
||||
float cy = cosf(yaw);
|
||||
|
||||
float sr = sinf(roll);
|
||||
float sp = sinf(pitch);
|
||||
float sy = sinf(yaw);
|
||||
|
||||
float cpcy = cp * cy;
|
||||
float spsy = sp * sy;
|
||||
float spcy = sp * cy;
|
||||
float cpsy = cp * sy;
|
||||
|
||||
quat[0] = (sr * cpcy - cr * spsy);
|
||||
quat[1] = (cr * spcy + sr * cpsy);
|
||||
quat[2] = (cr * cpsy - sr * spcy);
|
||||
quat[3] = cr * cpcy + sr * spsy;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
matrix[0 * 4 + 0] = 1 - 2 * (yy + zz);
|
||||
matrix[1 * 4 + 0] = 2 * (xy - wz);
|
||||
matrix[2 * 4 + 0] = 2 * (xz + wy);
|
||||
|
||||
matrix[0 * 4 + 1] = 2 * (xy + wz);
|
||||
matrix[1 * 4 + 1] = 1 - 2 * (xx + zz);
|
||||
matrix[2 * 4 + 1] = 2 * (yz - wx);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void fm_quatRotate(const float *quat, const float *v, float *r) // rotate a vector directly by a quaternion.
|
||||
{
|
||||
float left[4];
|
||||
|
||||
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[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];
|
||||
|
||||
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)
|
||||
{
|
||||
t[0] = matrix[3 * 4 + 0];
|
||||
t[1] = matrix[3 * 4 + 1];
|
||||
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
|
||||
{
|
||||
float tr = matrix[0 * 4 + 0] + matrix[1 * 4 + 1] + matrix[2 * 4 + 2];
|
||||
|
||||
// check the diagonal
|
||||
|
||||
if (tr > 0.0f)
|
||||
{
|
||||
float s = (float)sqrt((double)(tr + 1.0f));
|
||||
quat[3] = s * 0.5f;
|
||||
s = 0.5f / s;
|
||||
quat[0] = (matrix[1 * 4 + 2] - matrix[2 * 4 + 1]) * s;
|
||||
quat[1] = (matrix[2 * 4 + 0] - matrix[0 * 4 + 2]) * s;
|
||||
quat[2] = (matrix[0 * 4 + 1] - matrix[1 * 4 + 0]) * s;
|
||||
}
|
||||
else
|
||||
{
|
||||
// diagonal is negative
|
||||
int nxt[3] = {1, 2, 0};
|
||||
float qa[4];
|
||||
|
||||
int i = 0;
|
||||
|
||||
if (matrix[1 * 4 + 1] > matrix[0 * 4 + 0]) i = 1;
|
||||
if (matrix[2 * 4 + 2] > matrix[i * 4 + i]) i = 2;
|
||||
|
||||
int j = nxt[i];
|
||||
int k = nxt[j];
|
||||
|
||||
float s = sqrtf(((matrix[i * 4 + i] - (matrix[j * 4 + j] + matrix[k * 4 + k])) + 1.0f));
|
||||
|
||||
qa[i] = s * 0.5f;
|
||||
|
||||
if (s != 0.0f) s = 0.5f / s;
|
||||
|
||||
qa[3] = (matrix[j * 4 + k] - matrix[k * 4 + j]) * s;
|
||||
qa[j] = (matrix[i * 4 + j] + matrix[j * 4 + i]) * s;
|
||||
qa[k] = (matrix[i * 4 + k] + matrix[k * 4 + i]) * s;
|
||||
|
||||
quat[0] = qa[0];
|
||||
quat[1] = qa[1];
|
||||
quat[2] = qa[2];
|
||||
quat[3] = qa[3];
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
71
Engine/lib/bullet/Extras/ConvexDecomposition/float_math.h
Normal file
71
Engine/lib/bullet/Extras/ConvexDecomposition/float_math.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef FLOAT_MATH_H
|
||||
|
||||
#define FLOAT_MATH_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4324) // disable padding warning
|
||||
#pragma warning(disable : 4244) // disable padding warning
|
||||
#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 : 4996) //Turn off warnings about deprecated C routines
|
||||
#pragma warning(disable : 4786) // Disable the "debug name too long" warning
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
// a set of routines that last you do common 3d math
|
||||
// operations without any vector, matrix, or quaternion
|
||||
// classes or templates.
|
||||
//
|
||||
// a vector (or point) is a 'float *' to 3 floating point numbers.
|
||||
// a matrix is a 'float *' to an array of 16 floating point numbers representing a 4x4 transformation matrix compatible with D3D or OGL
|
||||
// a quaternion is a 'float *' to 4 floats representing a quaternion x,y,z,w
|
||||
|
||||
const float FM_PI = 3.141592654f;
|
||||
const float FM_DEG_TO_RAD = ((2.0f * FM_PI) / 360.0f);
|
||||
const float FM_RAD_TO_DEG = (360.0f / (2.0f * FM_PI));
|
||||
|
||||
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_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_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_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_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 )
|
||||
|
||||
#endif
|
||||
124
Engine/lib/bullet/Extras/ConvexDecomposition/meshvolume.cpp
Normal file
124
Engine/lib/bullet/Extras/ConvexDecomposition/meshvolume.cpp
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include "float_math.h"
|
||||
#include "meshvolume.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
float computeMeshVolume(const float *vertices, unsigned int tcount, const unsigned int *indices)
|
||||
{
|
||||
float volume = 0;
|
||||
|
||||
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];
|
||||
|
||||
volume += det(p1, p2, p3); // compute the volume of the tetrahedran relative to the origin.
|
||||
}
|
||||
|
||||
volume *= (1.0f / 6.0f);
|
||||
if (volume < 0)
|
||||
volume *= -1;
|
||||
return volume;
|
||||
}
|
||||
|
||||
inline void CrossProduct(const float *a, const float *b, float *cross)
|
||||
{
|
||||
cross[0] = a[1] * b[2] - a[2] * b[1];
|
||||
cross[1] = a[2] * b[0] - a[0] * b[2];
|
||||
cross[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
inline float DotProduct(const float *a, const float *b)
|
||||
{
|
||||
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)
|
||||
{
|
||||
float a[3];
|
||||
float b[3];
|
||||
float c[3];
|
||||
|
||||
a[0] = p1[0] - p0[0];
|
||||
a[1] = p1[1] - p0[1];
|
||||
a[2] = p1[2] - p0[2];
|
||||
|
||||
b[0] = p2[0] - p0[0];
|
||||
b[1] = p2[1] - p0[1];
|
||||
b[2] = p2[2] - p0[2];
|
||||
|
||||
c[0] = p3[0] - p0[0];
|
||||
c[1] = p3[1] - p0[1];
|
||||
c[2] = p3[2] - p0[2];
|
||||
|
||||
float cross[3];
|
||||
|
||||
CrossProduct(b, c, cross);
|
||||
|
||||
float volume = DotProduct(a, cross);
|
||||
|
||||
if (volume < 0)
|
||||
return -volume;
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
float computeMeshVolume2(const float *vertices, unsigned int tcount, const unsigned int *indices)
|
||||
{
|
||||
float volume = 0;
|
||||
|
||||
const float *p0 = vertices;
|
||||
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];
|
||||
|
||||
volume += tetVolume(p0, p1, p2, p3); // compute the volume of the tetrahdren relative to the root vertice
|
||||
}
|
||||
|
||||
return volume * (1.0f / 6.0f);
|
||||
}
|
||||
42
Engine/lib/bullet/Extras/ConvexDecomposition/meshvolume.h
Normal file
42
Engine/lib/bullet/Extras/ConvexDecomposition/meshvolume.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef MESH_VOLUME_H
|
||||
|
||||
#define MESH_VOLUME_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// 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);
|
||||
|
||||
#endif
|
||||
227
Engine/lib/bullet/Extras/ConvexDecomposition/planetri.cpp
Normal file
227
Engine/lib/bullet/Extras/ConvexDecomposition/planetri.cpp
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
#include "float_math.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "planetri.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
static inline float DistToPt(const float *p, const float *plane)
|
||||
{
|
||||
float x = p[0];
|
||||
float y = p[1];
|
||||
float z = p[2];
|
||||
float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3];
|
||||
return d;
|
||||
}
|
||||
|
||||
static PlaneTriResult getSidePlane(const float *p, const float *plane, float epsilon)
|
||||
{
|
||||
float d = DistToPt(p, plane);
|
||||
|
||||
if ((d + epsilon) > 0)
|
||||
return PTR_FRONT; // it is 'in front' within the provided epsilon value.
|
||||
|
||||
return PTR_BACK;
|
||||
}
|
||||
|
||||
static void add(const float *p, float *dest, unsigned int tstride, unsigned int &pcount)
|
||||
{
|
||||
char *d = (char *)dest;
|
||||
d = d + pcount * tstride;
|
||||
dest = (float *)d;
|
||||
dest[0] = p[0];
|
||||
dest[1] = p[1];
|
||||
dest[2] = p[2];
|
||||
pcount++;
|
||||
assert(pcount <= 4);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
float dp1 = DistToPt(p1, plane);
|
||||
|
||||
float dir[3];
|
||||
|
||||
dir[0] = p2[0] - p1[0];
|
||||
dir[1] = p2[1] - p1[1];
|
||||
dir[2] = p2[2] - p1[2];
|
||||
|
||||
float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2];
|
||||
float dot2 = dp1 - plane[3];
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format
|
||||
const float *triangle, // the source triangle.
|
||||
unsigned int tstride, // stride in bytes of the input and output triangles
|
||||
float epsilon, // the co-planer epsilon value.
|
||||
float *front, // the triangle in front of the
|
||||
unsigned int &fcount, // number of vertices in the 'front' triangle
|
||||
float *back, // the triangle in back of the plane
|
||||
unsigned int &bcount) // the number of vertices in the 'back' triangle.
|
||||
{
|
||||
fcount = 0;
|
||||
bcount = 0;
|
||||
|
||||
const char *tsource = (const char *)triangle;
|
||||
|
||||
// get the three vertices of the triangle.
|
||||
const float *p1 = (const float *)(tsource);
|
||||
const float *p2 = (const float *)(tsource + tstride);
|
||||
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);
|
||||
|
||||
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.
|
||||
{
|
||||
add(p1, front, tstride, fcount);
|
||||
add(p2, front, tstride, fcount);
|
||||
add(p3, front, tstride, fcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(p1, back, tstride, bcount); // if all three are in 'abck' then copy to the 'back' output triangle.
|
||||
add(p2, back, tstride, bcount);
|
||||
add(p3, back, tstride, bcount);
|
||||
}
|
||||
return r1; // if all three points are on the same side of the plane return result
|
||||
}
|
||||
|
||||
// ok.. we need to split the triangle at the plane.
|
||||
|
||||
// First test ray segment P1 to P2
|
||||
if (r1 == r2) // if these are both on the same side...
|
||||
{
|
||||
if (r1 == PTR_FRONT)
|
||||
{
|
||||
add(p1, front, tstride, fcount);
|
||||
add(p2, front, tstride, fcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(p1, back, tstride, bcount);
|
||||
add(p2, back, tstride, bcount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float split[3]; // split the point
|
||||
intersect(p1, p2, split, plane);
|
||||
|
||||
if (r1 == PTR_FRONT)
|
||||
{
|
||||
add(p1, front, tstride, fcount);
|
||||
add(split, front, tstride, fcount);
|
||||
|
||||
add(split, back, tstride, bcount);
|
||||
add(p2, back, tstride, bcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(p1, back, tstride, bcount);
|
||||
add(split, back, tstride, bcount);
|
||||
|
||||
add(split, front, tstride, fcount);
|
||||
add(p2, front, tstride, fcount);
|
||||
}
|
||||
}
|
||||
|
||||
// Next test ray segment P2 to P3
|
||||
if (r2 == r3) // if these are both on the same side...
|
||||
{
|
||||
if (r3 == PTR_FRONT)
|
||||
{
|
||||
add(p3, front, tstride, fcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(p3, back, tstride, bcount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float split[3]; // split the point
|
||||
intersect(p2, p3, split, plane);
|
||||
|
||||
if (r3 == PTR_FRONT)
|
||||
{
|
||||
add(split, front, tstride, fcount);
|
||||
add(split, back, tstride, bcount);
|
||||
|
||||
add(p3, front, tstride, fcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(split, front, tstride, fcount);
|
||||
add(split, back, tstride, bcount);
|
||||
|
||||
add(p3, back, tstride, bcount);
|
||||
}
|
||||
}
|
||||
|
||||
// Next test ray segment P3 to P1
|
||||
if (r3 != r1) // if these are both on the same side...
|
||||
{
|
||||
float split[3]; // split the point
|
||||
|
||||
intersect(p3, p1, split, plane);
|
||||
|
||||
if (r1 == PTR_FRONT)
|
||||
{
|
||||
add(split, front, tstride, fcount);
|
||||
add(split, back, tstride, bcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(split, front, tstride, fcount);
|
||||
add(split, back, tstride, bcount);
|
||||
}
|
||||
}
|
||||
|
||||
return PTR_SPLIT;
|
||||
}
|
||||
55
Engine/lib/bullet/Extras/ConvexDecomposition/planetri.h
Normal file
55
Engine/lib/bullet/Extras/ConvexDecomposition/planetri.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef PLANE_TRI_H
|
||||
|
||||
#define PLANE_TRI_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
enum PlaneTriResult
|
||||
{
|
||||
PTR_FRONT,
|
||||
PTR_BACK,
|
||||
PTR_SPLIT
|
||||
};
|
||||
|
||||
PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format
|
||||
const float *triangle, // the source position triangle.
|
||||
unsigned int tstride, // stride in bytes between vertices of the triangle.
|
||||
float epsilon, // the co-planer epsilon value.
|
||||
float *front, // the triangle in front of the
|
||||
unsigned int &fcount, // number of vertices in the 'front' triangle.
|
||||
float *back, // the triangle in back of the plane
|
||||
unsigned int &bcount); // the number of vertices in the 'back' triangle.
|
||||
|
||||
#endif
|
||||
12
Engine/lib/bullet/Extras/ConvexDecomposition/premake4.lua
Normal file
12
Engine/lib/bullet/Extras/ConvexDecomposition/premake4.lua
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
project "ConvexDecomposition"
|
||||
|
||||
kind "StaticLib"
|
||||
|
||||
includedirs {".","../../src"}
|
||||
if os.is("Linux") then
|
||||
buildoptions{"-fPIC"}
|
||||
end
|
||||
files {
|
||||
"**.cpp",
|
||||
"**.h"
|
||||
}
|
||||
128
Engine/lib/bullet/Extras/ConvexDecomposition/raytri.cpp
Normal file
128
Engine/lib/bullet/Extras/ConvexDecomposition/raytri.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include "float_math.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "raytri.h"
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
/* a = b - c */
|
||||
#define vector(a, b, c) \
|
||||
(a)[0] = (b)[0] - (c)[0]; \
|
||||
(a)[1] = (b)[1] - (c)[1]; \
|
||||
(a)[2] = (b)[2] - (c)[2];
|
||||
|
||||
#define innerProduct(v, q) \
|
||||
((v)[0] * (q)[0] + \
|
||||
(v)[1] * (q)[1] + \
|
||||
(v)[2] * (q)[2])
|
||||
|
||||
#define crossProduct(a, b, c) \
|
||||
(a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \
|
||||
(a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \
|
||||
(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)
|
||||
{
|
||||
float e1[3], e2[3], h[3], s[3], q[3];
|
||||
float a, f, u, v;
|
||||
|
||||
vector(e1, v1, v0);
|
||||
vector(e2, v2, v0);
|
||||
crossProduct(h, d, e2);
|
||||
a = innerProduct(e1, h);
|
||||
|
||||
if (a > -0.00001 && a < 0.00001)
|
||||
return (false);
|
||||
|
||||
f = 1 / a;
|
||||
vector(s, p, v0);
|
||||
u = f * (innerProduct(s, h));
|
||||
|
||||
if (u < 0.0 || u > 1.0)
|
||||
return (false);
|
||||
|
||||
crossProduct(q, s, e1);
|
||||
v = f * innerProduct(d, q);
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
return (false);
|
||||
// at this stage we can compute t to find out where
|
||||
// the intersection point is on the line
|
||||
t = f * innerProduct(e2, q);
|
||||
if (t > 0) // ray intersection
|
||||
return (true);
|
||||
else // this means that there is a line intersection
|
||||
// but not a ray intersection
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool lineIntersectsTriangle(const float *rayStart, const float *rayEnd, const float *p1, const float *p2, const float *p3, float *sect)
|
||||
{
|
||||
float dir[3];
|
||||
|
||||
dir[0] = rayEnd[0] - rayStart[0];
|
||||
dir[1] = rayEnd[1] - rayStart[1];
|
||||
dir[2] = rayEnd[2] - rayStart[2];
|
||||
|
||||
float d = sqrtf(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]);
|
||||
float r = 1.0f / d;
|
||||
|
||||
dir[0] *= r;
|
||||
dir[1] *= r;
|
||||
dir[2] *= r;
|
||||
|
||||
float t;
|
||||
|
||||
bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
if (t > d)
|
||||
{
|
||||
sect[0] = rayStart[0] + dir[0] * t;
|
||||
sect[1] = rayStart[1] + dir[1] * t;
|
||||
sect[2] = rayStart[2] + dir[2] * t;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
43
Engine/lib/bullet/Extras/ConvexDecomposition/raytri.h
Normal file
43
Engine/lib/bullet/Extras/ConvexDecomposition/raytri.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef RAY_TRI_H
|
||||
|
||||
#define RAY_TRI_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
// 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 rayIntersectsTriangle(const float *p, const float *d, const float *v0, const float *v1, const float *v2, float &t);
|
||||
|
||||
#endif
|
||||
294
Engine/lib/bullet/Extras/ConvexDecomposition/splitplane.cpp
Normal file
294
Engine/lib/bullet/Extras/ConvexDecomposition/splitplane.cpp
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
#include "float_math.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
#include "splitplane.h"
|
||||
#include "ConvexDecomposition.h"
|
||||
#include "cd_vector.h"
|
||||
#include "cd_hull.h"
|
||||
#include "cd_wavefront.h"
|
||||
#include "bestfit.h"
|
||||
#include "planetri.h"
|
||||
#include "vlookup.h"
|
||||
#include "meshvolume.h"
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
static void computePlane(const float *A, const float *B, const float *C, float *plane)
|
||||
{
|
||||
float vx = (B[0] - C[0]);
|
||||
float vy = (B[1] - C[1]);
|
||||
float vz = (B[2] - C[2]);
|
||||
|
||||
float wx = (A[0] - B[0]);
|
||||
float wy = (A[1] - B[1]);
|
||||
float wz = (A[2] - B[2]);
|
||||
|
||||
float vw_x = vy * wz - vz * wy;
|
||||
float vw_y = vz * wx - vx * wz;
|
||||
float vw_z = vx * wy - vy * wx;
|
||||
|
||||
float mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
|
||||
|
||||
if (mag < 0.000001f)
|
||||
{
|
||||
mag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mag = 1.0f / mag;
|
||||
}
|
||||
|
||||
float x = vw_x * mag;
|
||||
float y = vw_y * mag;
|
||||
float z = vw_z * mag;
|
||||
|
||||
float D = 0.0f - ((x * A[0]) + (y * A[1]) + (z * A[2]));
|
||||
|
||||
plane[0] = x;
|
||||
plane[1] = y;
|
||||
plane[2] = z;
|
||||
plane[3] = D;
|
||||
}
|
||||
|
||||
class Rect3d
|
||||
{
|
||||
public:
|
||||
Rect3d(void){};
|
||||
|
||||
Rect3d(const float *bmin, const float *bmax)
|
||||
{
|
||||
mMin[0] = bmin[0];
|
||||
mMin[1] = bmin[1];
|
||||
mMin[2] = bmin[2];
|
||||
|
||||
mMax[0] = bmax[0];
|
||||
mMax[1] = bmax[1];
|
||||
mMax[2] = bmax[2];
|
||||
}
|
||||
|
||||
void SetMin(const float *bmin)
|
||||
{
|
||||
mMin[0] = bmin[0];
|
||||
mMin[1] = bmin[1];
|
||||
mMin[2] = bmin[2];
|
||||
}
|
||||
|
||||
void SetMax(const float *bmax)
|
||||
{
|
||||
mMax[0] = bmax[0];
|
||||
mMax[1] = bmax[1];
|
||||
mMax[2] = bmax[2];
|
||||
}
|
||||
|
||||
void SetMin(float x, float y, float z)
|
||||
{
|
||||
mMin[0] = x;
|
||||
mMin[1] = y;
|
||||
mMin[2] = z;
|
||||
}
|
||||
|
||||
void SetMax(float x, float y, float z)
|
||||
{
|
||||
mMax[0] = x;
|
||||
mMax[1] = y;
|
||||
mMax[2] = z;
|
||||
}
|
||||
|
||||
float mMin[3];
|
||||
float mMax[3];
|
||||
};
|
||||
|
||||
void splitRect(unsigned int axis,
|
||||
const Rect3d &source,
|
||||
Rect3d &b1,
|
||||
Rect3d &b2,
|
||||
const float *midpoint)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case 0:
|
||||
b1.SetMin(source.mMin);
|
||||
b1.SetMax(midpoint[0], source.mMax[1], source.mMax[2]);
|
||||
|
||||
b2.SetMin(midpoint[0], source.mMin[1], source.mMin[2]);
|
||||
b2.SetMax(source.mMax);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
b1.SetMin(source.mMin);
|
||||
b1.SetMax(source.mMax[0], midpoint[1], source.mMax[2]);
|
||||
|
||||
b2.SetMin(source.mMin[0], midpoint[1], source.mMin[2]);
|
||||
b2.SetMax(source.mMax);
|
||||
|
||||
break;
|
||||
case 2:
|
||||
b1.SetMin(source.mMin);
|
||||
b1.SetMax(source.mMax[0], source.mMax[1], midpoint[2]);
|
||||
|
||||
b2.SetMin(source.mMin[0], source.mMin[1], midpoint[2]);
|
||||
b2.SetMax(source.mMax);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool computeSplitPlane(unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int tcount,
|
||||
const unsigned int *indices,
|
||||
ConvexDecompInterface *callback,
|
||||
float *plane)
|
||||
{
|
||||
float bmin[3] = {1e9, 1e9, 1e9};
|
||||
float bmax[3] = {-1e9, -1e9, -1e9};
|
||||
|
||||
for (unsigned int i = 0; i < vcount; i++)
|
||||
{
|
||||
const float *p = &vertices[i * 3];
|
||||
|
||||
if (p[0] < bmin[0]) bmin[0] = p[0];
|
||||
if (p[1] < bmin[1]) bmin[1] = p[1];
|
||||
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];
|
||||
}
|
||||
|
||||
float dx = bmax[0] - bmin[0];
|
||||
float dy = bmax[1] - bmin[1];
|
||||
float dz = bmax[2] - bmin[2];
|
||||
|
||||
float laxis = dx;
|
||||
|
||||
unsigned int axis = 0;
|
||||
|
||||
if (dy > dx)
|
||||
{
|
||||
axis = 1;
|
||||
laxis = dy;
|
||||
}
|
||||
|
||||
if (dz > dx && dz > dy)
|
||||
{
|
||||
axis = 2;
|
||||
laxis = dz;
|
||||
}
|
||||
|
||||
float p1[3];
|
||||
float p2[3];
|
||||
float p3[3];
|
||||
|
||||
p3[0] = p2[0] = p1[0] = bmin[0] + dx * 0.5f;
|
||||
p3[1] = p2[1] = p1[1] = bmin[1] + dy * 0.5f;
|
||||
p3[2] = p2[2] = p1[2] = bmin[2] + dz * 0.5f;
|
||||
|
||||
Rect3d b(bmin, bmax);
|
||||
|
||||
Rect3d b1, b2;
|
||||
|
||||
splitRect(axis, b, b1, b2, p1);
|
||||
|
||||
// callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00);
|
||||
// callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00);
|
||||
|
||||
switch (axis)
|
||||
{
|
||||
case 0:
|
||||
p2[1] = bmin[1];
|
||||
p2[2] = bmin[2];
|
||||
|
||||
if (dz > dy)
|
||||
{
|
||||
p3[1] = bmax[1];
|
||||
p3[2] = bmin[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
p3[1] = bmin[1];
|
||||
p3[2] = bmax[2];
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
p2[0] = bmin[0];
|
||||
p2[2] = bmin[2];
|
||||
|
||||
if (dx > dz)
|
||||
{
|
||||
p3[0] = bmax[0];
|
||||
p3[2] = bmin[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
p3[0] = bmin[0];
|
||||
p3[2] = bmax[2];
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
p2[0] = bmin[0];
|
||||
p2[1] = bmin[1];
|
||||
|
||||
if (dx > dy)
|
||||
{
|
||||
p3[0] = bmax[0];
|
||||
p3[1] = bmin[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
p3[0] = bmin[0];
|
||||
p3[1] = bmax[1];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// callback->ConvexDebugTri(p1,p2,p3,0xFF0000);
|
||||
|
||||
computePlane(p1, p2, p3, plane);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
55
Engine/lib/bullet/Extras/ConvexDecomposition/splitplane.h
Normal file
55
Engine/lib/bullet/Extras/ConvexDecomposition/splitplane.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef SPLIT_PLANE_H
|
||||
|
||||
#define SPLIT_PLANE_H
|
||||
|
||||
//** Computes an 'optimal' split plane for the supplied mesh.
|
||||
//** needs much improvement since it currently just splits along
|
||||
//** the longest side of the AABB.
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
namespace ConvexDecomposition
|
||||
{
|
||||
class ConvexDecompInterface;
|
||||
|
||||
bool computeSplitPlane(unsigned int vcount,
|
||||
const float *vertices,
|
||||
unsigned int tcount,
|
||||
const unsigned int *indices,
|
||||
ConvexDecompInterface *callback,
|
||||
float *plane);
|
||||
|
||||
} // namespace ConvexDecomposition
|
||||
|
||||
#endif
|
||||
311
Engine/lib/bullet/Extras/ConvexDecomposition/vlookup.cpp
Normal file
311
Engine/lib/bullet/Extras/ConvexDecomposition/vlookup.cpp
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
#include "float_math.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#pragma warning(disable : 4786)
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
// CodeSnippet provided by John W. Ratcliff
|
||||
// on March 23, 2006.
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// Personal website: http://jratcliffscarab.blogspot.com
|
||||
// Coding Website: http://codesuppository.blogspot.com
|
||||
// FundRaising Blog: http://amillionpixels.blogspot.com
|
||||
// Fundraising site: http://www.amillionpixels.us
|
||||
// New Temple Site: http://newtemple.blogspot.com
|
||||
//
|
||||
// This snippet shows how to 'hide' the complexity of
|
||||
// the STL by wrapping some useful piece of functionality
|
||||
// around a handful of discrete API calls.
|
||||
//
|
||||
// This API allows you to create an indexed triangle list
|
||||
// from a collection of raw input triangles. Internally
|
||||
// it uses an STL set to build the lookup table very rapidly.
|
||||
//
|
||||
// Here is how you would use it to build an indexed triangle
|
||||
// list from a raw list of triangles.
|
||||
//
|
||||
// (1) create a 'VertexLookup' interface by calling
|
||||
//
|
||||
// VertexLook vl = Vl_createVertexLookup();
|
||||
//
|
||||
// (2) For each vertice in each triangle call:
|
||||
//
|
||||
// unsigned int i1 = Vl_getIndex(vl,p1);
|
||||
// unsigned int i2 = Vl_getIndex(vl,p2);
|
||||
// unsigned int i3 = Vl_getIndex(vl,p3);
|
||||
//
|
||||
// save the 3 indices into your triangle list array.
|
||||
//
|
||||
// (3) Get the vertex array by calling:
|
||||
//
|
||||
// const float *vertices = Vl_getVertices(vl);
|
||||
//
|
||||
// (4) Get the number of vertices so you can copy them into
|
||||
// your own buffer.
|
||||
// unsigned int vcount = Vl_getVcount(vl);
|
||||
//
|
||||
// (5) Release the VertexLookup interface when you are done with it.
|
||||
// Vl_releaseVertexLookup(vl);
|
||||
//
|
||||
// Teaches the following lessons:
|
||||
//
|
||||
// How to wrap the complexity of STL and C++ classes around a
|
||||
// simple API interface.
|
||||
//
|
||||
// How to use an STL set and custom comparator operator for
|
||||
// a complex data type.
|
||||
//
|
||||
// How to create a template class.
|
||||
//
|
||||
// How to achieve significant performance improvements by
|
||||
// taking advantage of built in STL containers in just
|
||||
// a few lines of code.
|
||||
//
|
||||
// You could easily modify this code to support other vertex
|
||||
// formats with any number of interpolants.
|
||||
|
||||
#include "vlookup.h"
|
||||
|
||||
namespace Vlookup
|
||||
{
|
||||
class VertexPosition
|
||||
{
|
||||
public:
|
||||
VertexPosition(void){};
|
||||
VertexPosition(const float *p)
|
||||
{
|
||||
mPos[0] = p[0];
|
||||
mPos[1] = p[1];
|
||||
mPos[2] = p[2];
|
||||
};
|
||||
|
||||
void Set(int index, const float *pos)
|
||||
{
|
||||
const float *p = &pos[index * 3];
|
||||
|
||||
mPos[0] = p[0];
|
||||
mPos[1] = p[1];
|
||||
mPos[2] = p[2];
|
||||
};
|
||||
|
||||
float GetX(void) const { return mPos[0]; };
|
||||
float GetY(void) const { return mPos[1]; };
|
||||
float GetZ(void) const { return mPos[2]; };
|
||||
|
||||
float mPos[3];
|
||||
};
|
||||
|
||||
typedef std::vector<VertexPosition> VertexVector;
|
||||
|
||||
struct Tracker
|
||||
{
|
||||
VertexPosition mFind; // vertice to locate.
|
||||
VertexVector *mList;
|
||||
|
||||
Tracker()
|
||||
{
|
||||
mList = 0;
|
||||
}
|
||||
|
||||
void SetSearch(const VertexPosition &match, VertexVector *list)
|
||||
{
|
||||
mFind = match;
|
||||
mList = list;
|
||||
};
|
||||
};
|
||||
|
||||
struct VertexID
|
||||
{
|
||||
int mID;
|
||||
Tracker *mTracker;
|
||||
|
||||
VertexID(int ID, Tracker *Tracker)
|
||||
{
|
||||
mID = ID;
|
||||
mTracker = Tracker;
|
||||
}
|
||||
};
|
||||
|
||||
class VertexLess
|
||||
{
|
||||
public:
|
||||
bool operator()(VertexID v1, VertexID v2) const;
|
||||
|
||||
private:
|
||||
const VertexPosition &Get(VertexID index) const
|
||||
{
|
||||
if (index.mID == -1) return index.mTracker->mFind;
|
||||
VertexVector &vlist = *index.mTracker->mList;
|
||||
return vlist[index.mID];
|
||||
}
|
||||
};
|
||||
|
||||
template <class Type>
|
||||
class VertexPool
|
||||
{
|
||||
public:
|
||||
typedef std::set<VertexID, VertexLess> VertexSet;
|
||||
typedef std::vector<Type> VertexVector;
|
||||
|
||||
int getVertex(const Type &vtx)
|
||||
{
|
||||
mTracker.SetSearch(vtx, &mVtxs);
|
||||
VertexSet::iterator found;
|
||||
found = mVertSet.find(VertexID(-1, &mTracker));
|
||||
if (found != mVertSet.end())
|
||||
{
|
||||
return found->mID;
|
||||
}
|
||||
int idx = (int)mVtxs.size();
|
||||
mVtxs.push_back(vtx);
|
||||
mVertSet.insert(VertexID(idx, &mTracker));
|
||||
return idx;
|
||||
};
|
||||
|
||||
const float *GetPos(int idx) const
|
||||
{
|
||||
return mVtxs[idx].mPos;
|
||||
}
|
||||
|
||||
const Type &Get(int idx) const
|
||||
{
|
||||
return mVtxs[idx];
|
||||
};
|
||||
|
||||
unsigned int GetSize(void) const
|
||||
{
|
||||
return mVtxs.size();
|
||||
};
|
||||
|
||||
void Clear(int reservesize) // clear the vertice pool.
|
||||
{
|
||||
mVertSet.clear();
|
||||
mVtxs.clear();
|
||||
mVtxs.reserve(reservesize);
|
||||
};
|
||||
|
||||
const VertexVector &GetVertexList(void) const { return mVtxs; };
|
||||
|
||||
void Set(const Type &vtx)
|
||||
{
|
||||
mVtxs.push_back(vtx);
|
||||
}
|
||||
|
||||
unsigned int GetVertexCount(void) const
|
||||
{
|
||||
return mVtxs.size();
|
||||
};
|
||||
|
||||
Type *getBuffer(void)
|
||||
{
|
||||
return &mVtxs[0];
|
||||
};
|
||||
|
||||
private:
|
||||
VertexSet mVertSet; // ordered list.
|
||||
VertexVector mVtxs; // set of vertices.
|
||||
Tracker mTracker;
|
||||
};
|
||||
|
||||
bool VertexLess::operator()(VertexID v1, VertexID v2) const
|
||||
{
|
||||
const VertexPosition &a = Get(v1);
|
||||
const VertexPosition &b = Get(v2);
|
||||
|
||||
int ixA = (int)(a.GetX() * 10000.0f);
|
||||
int ixB = (int)(b.GetX() * 10000.0f);
|
||||
|
||||
if (ixA < ixB) return true;
|
||||
if (ixA > ixB) return false;
|
||||
|
||||
int iyA = (int)(a.GetY() * 10000.0f);
|
||||
int iyB = (int)(b.GetY() * 10000.0f);
|
||||
|
||||
if (iyA < iyB) return true;
|
||||
if (iyA > iyB) return false;
|
||||
|
||||
int izA = (int)(a.GetZ() * 10000.0f);
|
||||
int izB = (int)(b.GetZ() * 10000.0f);
|
||||
|
||||
if (izA < izB) return true;
|
||||
if (izA > izB) return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Vlookup
|
||||
|
||||
using namespace Vlookup;
|
||||
|
||||
VertexLookup Vl_createVertexLookup(void)
|
||||
{
|
||||
VertexLookup ret = new VertexPool<VertexPosition>;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Vl_releaseVertexLookup(VertexLookup vlook)
|
||||
{
|
||||
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||
delete vp;
|
||||
}
|
||||
|
||||
unsigned int Vl_getIndex(VertexLookup vlook, const float *pos) // get index.
|
||||
{
|
||||
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||
VertexPosition p(pos);
|
||||
return vp->getVertex(p);
|
||||
}
|
||||
|
||||
const float *Vl_getVertices(VertexLookup vlook)
|
||||
{
|
||||
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||
return vp->GetPos(0);
|
||||
}
|
||||
|
||||
unsigned int Vl_getVcount(VertexLookup vlook)
|
||||
{
|
||||
VertexPool<VertexPosition> *vp = (VertexPool<VertexPosition> *)vlook;
|
||||
return vp->GetVertexCount();
|
||||
}
|
||||
115
Engine/lib/bullet/Extras/ConvexDecomposition/vlookup.h
Normal file
115
Engine/lib/bullet/Extras/ConvexDecomposition/vlookup.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#ifndef VLOOKUP_H
|
||||
|
||||
#define VLOOKUP_H
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 2004 Open Dynamics Framework Group
|
||||
www.physicstools.org
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
// http://codesuppository.blogspot.com
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// http://www.amillionpixels.us
|
||||
//
|
||||
|
||||
// CodeSnippet provided by John W. Ratcliff
|
||||
// on March 23, 2006.
|
||||
//
|
||||
// mailto: jratcliff@infiniplex.net
|
||||
//
|
||||
// Personal website: http://jratcliffscarab.blogspot.com
|
||||
// Coding Website: http://codesuppository.blogspot.com
|
||||
// FundRaising Blog: http://amillionpixels.blogspot.com
|
||||
// Fundraising site: http://www.amillionpixels.us
|
||||
// New Temple Site: http://newtemple.blogspot.com
|
||||
//
|
||||
// This snippet shows how to 'hide' the complexity of
|
||||
// the STL by wrapping some useful piece of functionality
|
||||
// around a handful of discrete API calls.
|
||||
//
|
||||
// This API allows you to create an indexed triangle list
|
||||
// from a collection of raw input triangles. Internally
|
||||
// it uses an STL set to build the lookup table very rapidly.
|
||||
//
|
||||
// Here is how you would use it to build an indexed triangle
|
||||
// list from a raw list of triangles.
|
||||
//
|
||||
// (1) create a 'VertexLookup' interface by calling
|
||||
//
|
||||
// VertexLook vl = Vl_createVertexLookup();
|
||||
//
|
||||
// (2) For each vertice in each triangle call:
|
||||
//
|
||||
// unsigned int i1 = Vl_getIndex(vl,p1);
|
||||
// unsigned int i2 = Vl_getIndex(vl,p2);
|
||||
// unsigned int i3 = Vl_getIndex(vl,p3);
|
||||
//
|
||||
// save the 3 indices into your triangle list array.
|
||||
//
|
||||
// (3) Get the vertex array by calling:
|
||||
//
|
||||
// const float *vertices = Vl_getVertices(vl);
|
||||
//
|
||||
// (4) Get the number of vertices so you can copy them into
|
||||
// your own buffer.
|
||||
// unsigned int vcount = Vl_getVcount(vl);
|
||||
//
|
||||
// (5) Release the VertexLookup interface when you are done with it.
|
||||
// Vl_releaseVertexLookup(vl);
|
||||
//
|
||||
// Teaches the following lessons:
|
||||
//
|
||||
// How to wrap the complexity of STL and C++ classes around a
|
||||
// simple API interface.
|
||||
//
|
||||
// How to use an STL set and custom comparator operator for
|
||||
// a complex data type.
|
||||
//
|
||||
// How to create a template class.
|
||||
//
|
||||
// How to achieve significant performance improvements by
|
||||
// taking advantage of built in STL containers in just
|
||||
// a few lines of code.
|
||||
//
|
||||
// You could easily modify this code to support other vertex
|
||||
// formats with any number of interpolants.
|
||||
//
|
||||
// Hide C++ classes from the rest of your application by
|
||||
// keeping them in the CPP and wrapping them in a namespace
|
||||
// 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.
|
||||
|
||||
typedef void *VertexLookup;
|
||||
|
||||
VertexLookup Vl_createVertexLookup(void);
|
||||
void Vl_releaseVertexLookup(VertexLookup vlook);
|
||||
|
||||
unsigned int Vl_getIndex(VertexLookup vlook, const float *pos); // get index.
|
||||
const float *Vl_getVertices(VertexLookup vlook);
|
||||
unsigned int Vl_getVcount(VertexLookup vlook);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue