remove Extras/obsolete/quickstep
improve serialization based on feedback: make it easier to serialize a single object, or single shape, or single bvh. Modified Bullet/Demos/ConcaveDemo to use btSerializer to serialize the btOptimizedBvh (or optionally the trimesh+bvh) You can also serialize trimesh without BVH, use: serializer->setSerializationFlags(BT_SERIALIZE_NO_BVH);// or BT_SERIALIZE_NO_TRIANGLEINFOMAP
This commit is contained in:
@@ -6,16 +6,19 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# You shouldn't have to modify anything below this line
|
||||
########################################################
|
||||
|
||||
IF (USE_GLUT)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter
|
||||
)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
|
||||
IF (WIN32)
|
||||
@@ -51,10 +54,12 @@ ELSE (USE_GLUT)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter
|
||||
)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport BulletDynamics BulletCollision LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(AppConcaveDemo
|
||||
|
||||
@@ -20,6 +20,18 @@ subject to the following restrictions:
|
||||
#include "GL_ShapeDrawer.h"
|
||||
#include "GlutStuff.h"
|
||||
|
||||
#include "btBulletWorldImporter.h"
|
||||
|
||||
#define SERIALIZE_TO_DISK 1
|
||||
|
||||
//by default, the sample only (de)serializes the BVH to disk.
|
||||
//If you enable the SERIALIZE_SHAPE define then it will serialize the entire collision shape
|
||||
//then the animation will not play, because it is using the deserialized vertices
|
||||
//#define SERIALIZE_SHAPE
|
||||
|
||||
|
||||
|
||||
|
||||
//#define USE_PARALLEL_DISPATCHER 1
|
||||
#ifdef USE_PARALLEL_DISPATCHER
|
||||
#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
|
||||
@@ -186,55 +198,60 @@ void ConcaveDemo::initPhysics()
|
||||
bool useQuantizedAabbCompression = true;
|
||||
|
||||
//comment out the next line to read the BVH from disk (first run the demo once to create the BVH)
|
||||
#define SERIALIZE_TO_DISK 1
|
||||
|
||||
#ifdef SERIALIZE_TO_DISK
|
||||
|
||||
|
||||
btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000);
|
||||
|
||||
trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax);
|
||||
m_collisionShapes.push_back(trimeshShape);
|
||||
|
||||
|
||||
///we can serialize the BVH data
|
||||
void* buffer = 0;
|
||||
int numBytes = trimeshShape->getOptimizedBvh()->calculateSerializeBufferSize();
|
||||
buffer = btAlignedAlloc(numBytes,16);
|
||||
bool swapEndian = false;
|
||||
trimeshShape->getOptimizedBvh()->serialize(buffer,numBytes,swapEndian);
|
||||
FILE* file = fopen("bvh.bin","wb");
|
||||
fwrite(buffer,1,numBytes,file);
|
||||
fclose(file);
|
||||
btAlignedFree(buffer);
|
||||
|
||||
|
||||
int maxSerializeBufferSize = 1024*1024*5;
|
||||
btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize);
|
||||
//serializer->setSerializationFlags(BT_SERIALIZE_NO_BVH);// or BT_SERIALIZE_NO_TRIANGLEINFOMAP
|
||||
serializer->startSerialization();
|
||||
//registering a name is optional, it allows you to retrieve the shape by name
|
||||
//serializer->registerNameForPointer(trimeshShape,"mymesh");
|
||||
#ifdef SERIALIZE_SHAPE
|
||||
trimeshShape->serializeSingleShape(serializer);
|
||||
#else
|
||||
trimeshShape->serializeSingleBvh(serializer);
|
||||
#endif
|
||||
serializer->finishSerialization();
|
||||
FILE* f2 = fopen("myShape.bullet","wb");
|
||||
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2);
|
||||
fclose(f2);
|
||||
|
||||
#else
|
||||
|
||||
trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,false);
|
||||
|
||||
char* fileName = "bvh.bin";
|
||||
|
||||
FILE* file = fopen(fileName,"rb");
|
||||
int size=0;
|
||||
btOptimizedBvh* bvh = 0;
|
||||
|
||||
if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */
|
||||
printf("Error: cannot get filesize from %s\n", fileName);
|
||||
exit(0);
|
||||
} else
|
||||
btBulletWorldImporter import(0);//don't store info into the world
|
||||
if (import.loadFile("myShape.bullet"))
|
||||
{
|
||||
int numBvh = import.getNumBvhs();
|
||||
if (numBvh)
|
||||
{
|
||||
btOptimizedBvh* bvh = import.getBvhByIndex(0);
|
||||
btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000);
|
||||
|
||||
fseek(file, 0, SEEK_SET);
|
||||
trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax,false);
|
||||
trimeshShape->setOptimizedBvh(bvh);
|
||||
//trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax);
|
||||
//trimeshShape->setOptimizedBvh(bvh);
|
||||
|
||||
int buffersize = size+btOptimizedBvh::getAlignmentSerializationPadding();
|
||||
}
|
||||
int numShape = import.getNumCollisionShapes();
|
||||
if (numShape)
|
||||
{
|
||||
trimeshShape = (btBvhTriangleMeshShape*)import.getCollisionShapeByIndex(0);
|
||||
|
||||
void* buffer = btAlignedAlloc(buffersize,16);
|
||||
int read = fread(buffer,1,size,file);
|
||||
fclose(file);
|
||||
bool swapEndian = false;
|
||||
bvh = btOptimizedBvh::deSerializeInPlace(buffer,buffersize,swapEndian);
|
||||
//if you know the name, you can also try to get the shape by name:
|
||||
const char* meshName = import.getNameForPointer(trimeshShape);
|
||||
if (meshName)
|
||||
trimeshShape = (btBvhTriangleMeshShape*)import.getCollisionShapeByName(meshName);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
trimeshShape->setOptimizedBvh(bvh);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -377,6 +377,7 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
int maxSerializeBufferSize = 1024*1024*5;
|
||||
btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize);
|
||||
//serializer->setSerializationFlags(BT_SERIALIZE_NO_DUPLICATE_ASSERT);
|
||||
m_dynamicsWorld->serialize(serializer);
|
||||
FILE* f2 = fopen("testFile.bullet","wb");
|
||||
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2);
|
||||
|
||||
@@ -21,7 +21,7 @@ ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter
|
||||
|
||||
IF (USE_GLUT)
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
|
||||
IF (WIN32)
|
||||
@@ -59,7 +59,7 @@ IF (USE_GLUT)
|
||||
ELSE (USE_GLUT)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision LinearMath BulletFileLoader ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(AppSerializeDemo
|
||||
|
||||
@@ -18,13 +18,54 @@ m_verboseDumpAllTypes(false)
|
||||
|
||||
btBulletWorldImporter::~btBulletWorldImporter()
|
||||
{
|
||||
for (int i=0;i<m_allocatedCollisionShapes.size();i++)
|
||||
}
|
||||
|
||||
void btBulletWorldImporter::deleteAllData()
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<m_allocatedCollisionShapes.size();i++)
|
||||
{
|
||||
delete m_allocatedCollisionShapes[i];
|
||||
}
|
||||
m_allocatedCollisionShapes.clear();
|
||||
|
||||
for (i=0;i<m_allocatedRigidBodies.size();i++)
|
||||
{
|
||||
delete m_allocatedRigidBodies[i];
|
||||
}
|
||||
m_allocatedRigidBodies.clear();
|
||||
|
||||
for (i=0;i<m_allocatedConstraints.size();i++)
|
||||
{
|
||||
delete m_allocatedConstraints[i];
|
||||
}
|
||||
m_allocatedConstraints.clear();
|
||||
|
||||
for (i=0;i<m_allocatedBvhs.size();i++)
|
||||
{
|
||||
delete m_allocatedBvhs[i];
|
||||
}
|
||||
m_allocatedBvhs.clear();
|
||||
|
||||
for (i=0;i<m_allocatedTriangleInfoMaps.size();i++)
|
||||
{
|
||||
delete m_allocatedTriangleInfoMaps[i];
|
||||
}
|
||||
m_allocatedTriangleInfoMaps.clear();
|
||||
for (i=0;i<m_allocatedTriangleIndexArrays.size();i++)
|
||||
{
|
||||
delete m_allocatedTriangleIndexArrays[i];
|
||||
}
|
||||
m_allocatedTriangleIndexArrays.clear();
|
||||
for (i=0;i<m_allocatedNames.size();i++)
|
||||
{
|
||||
delete m_allocatedNames[i];
|
||||
}
|
||||
m_allocatedNames.clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool btBulletWorldImporter::loadFile( const char* fileName)
|
||||
{
|
||||
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
||||
@@ -114,7 +155,7 @@ btCollisionShape* btBulletWorldImporter::convertCollisionShape( btCollisionShap
|
||||
btVector3 planeNormal,localScaling;
|
||||
planeNormal.deSerializeFloat(planeData->m_planeNormal);
|
||||
localScaling.deSerializeFloat(planeData->m_localScaling);
|
||||
shape = new btStaticPlaneShape(planeNormal,btScalar(planeData->m_planeConstant));
|
||||
shape = createPlaneShape(planeNormal,planeData->m_planeConstant);
|
||||
shape->setLocalScaling(localScaling);
|
||||
|
||||
break;
|
||||
@@ -305,13 +346,27 @@ btCollisionShape* btBulletWorldImporter::convertCollisionShape( btCollisionShap
|
||||
|
||||
if (trimesh->m_quantizedFloatBvh)
|
||||
{
|
||||
bvh = createOptimizedBvh();
|
||||
bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);
|
||||
btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh);
|
||||
if (bvhPtr && *bvhPtr)
|
||||
{
|
||||
bvh = *bvhPtr;
|
||||
} else
|
||||
{
|
||||
bvh = createOptimizedBvh();
|
||||
bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);
|
||||
}
|
||||
}
|
||||
if (trimesh->m_quantizedDoubleBvh)
|
||||
{
|
||||
bvh = createOptimizedBvh();
|
||||
bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);
|
||||
btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh);
|
||||
if (bvhPtr && *bvhPtr)
|
||||
{
|
||||
bvh = *bvhPtr;
|
||||
} else
|
||||
{
|
||||
bvh = createOptimizedBvh();
|
||||
bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,12 +424,25 @@ btCollisionShape* btBulletWorldImporter::convertCollisionShape( btCollisionShap
|
||||
|
||||
}
|
||||
|
||||
char* btBulletWorldImporter::duplicateName(const char* name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
int l = strlen(name);
|
||||
char* newName = new char[l+1];
|
||||
memcpy(newName,name,l);
|
||||
newName[l] = 0;
|
||||
m_allocatedNames.push_back(newName);
|
||||
return newName;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFile2)
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
|
||||
|
||||
if (ok)
|
||||
@@ -387,7 +455,24 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
bulletFile2->dumpChunks(bulletFile2->getFileDNA());
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i=0;i<bulletFile2->m_bvhs.size();i++)
|
||||
{
|
||||
btOptimizedBvh* bvh = createOptimizedBvh();
|
||||
|
||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||
{
|
||||
btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
|
||||
bvh->deSerializeDouble(*bvhData);
|
||||
} else
|
||||
{
|
||||
btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
|
||||
bvh->deSerializeFloat(*bvhData);
|
||||
}
|
||||
m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh);
|
||||
}
|
||||
|
||||
|
||||
|
||||
btHashMap<btHashPtr,btCollisionShape*> shapeMap;
|
||||
|
||||
for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
|
||||
@@ -396,11 +481,17 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btCollisionShape* shape = convertCollisionShape(shapeData);
|
||||
if (shape)
|
||||
shapeMap.insert(shapeData,shape);
|
||||
|
||||
if (shape&& shapeData->m_name)
|
||||
{
|
||||
char* newname = duplicateName(shapeData->m_name);
|
||||
m_objectNameMap.insert(shape,newname);
|
||||
m_nameShapeMap.insert(newname,shape);
|
||||
}
|
||||
}
|
||||
|
||||
btHashMap<btHashPtr,btCollisionObject*> bodyMap;
|
||||
|
||||
|
||||
for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
|
||||
{
|
||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||
@@ -559,12 +650,12 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
rbB = &getFixedBody();
|
||||
}
|
||||
|
||||
btTypedConstraint* constraint = 0;
|
||||
|
||||
switch (constraintData->m_objectType)
|
||||
{
|
||||
case POINT2POINT_CONSTRAINT_TYPE:
|
||||
{
|
||||
btPoint2PointConstraint* constraint = 0;
|
||||
|
||||
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
||||
{
|
||||
btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData;
|
||||
@@ -573,12 +664,12 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btVector3 pivotInA,pivotInB;
|
||||
pivotInA.deSerializeDouble(p2pData->m_pivotInA);
|
||||
pivotInB.deSerializeDouble(p2pData->m_pivotInB);
|
||||
constraint = new btPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
|
||||
constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
|
||||
} else
|
||||
{
|
||||
btVector3 pivotInA;
|
||||
pivotInA.deSerializeDouble(p2pData->m_pivotInA);
|
||||
constraint = new btPoint2PointConstraint(*rbA,pivotInA);
|
||||
constraint = createPoint2PointConstraint(*rbA,pivotInA);
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -588,19 +679,17 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btVector3 pivotInA,pivotInB;
|
||||
pivotInA.deSerializeFloat(p2pData->m_pivotInA);
|
||||
pivotInB.deSerializeFloat(p2pData->m_pivotInB);
|
||||
constraint = new btPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
|
||||
constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
|
||||
|
||||
} else
|
||||
{
|
||||
btVector3 pivotInA;
|
||||
pivotInA.deSerializeFloat(p2pData->m_pivotInA);
|
||||
constraint = new btPoint2PointConstraint(*rbA,pivotInA);
|
||||
constraint = createPoint2PointConstraint(*rbA,pivotInA);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
|
||||
constraint->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||
break;
|
||||
}
|
||||
case HINGE_CONSTRAINT_TYPE:
|
||||
@@ -615,12 +704,12 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btTransform rbAFrame,rbBFrame;
|
||||
rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);
|
||||
rbBFrame.deSerializeDouble(hingeData->m_rbBFrame);
|
||||
hinge = new btHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
} else
|
||||
{
|
||||
btTransform rbAFrame;
|
||||
rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);
|
||||
hinge = new btHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
}
|
||||
if (hingeData->m_enableAngularMotor)
|
||||
{
|
||||
@@ -636,12 +725,12 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btTransform rbAFrame,rbBFrame;
|
||||
rbAFrame.deSerializeFloat(hingeData->m_rbAFrame);
|
||||
rbBFrame.deSerializeFloat(hingeData->m_rbBFrame);
|
||||
hinge = new btHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
} else
|
||||
{
|
||||
btTransform rbAFrame;
|
||||
rbAFrame.deSerializeFloat(hingeData->m_rbAFrame);
|
||||
hinge = new btHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
|
||||
}
|
||||
if (hingeData->m_enableAngularMotor)
|
||||
{
|
||||
@@ -650,10 +739,8 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
hinge->setAngularOnly(hingeData->m_angularOnly!=0);
|
||||
hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor));
|
||||
}
|
||||
m_dynamicsWorld->addConstraint(hinge,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
|
||||
hinge->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||
|
||||
|
||||
constraint = hinge;
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -667,19 +754,17 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btTransform rbAFrame,rbBFrame;
|
||||
rbAFrame.deSerializeFloat(coneData->m_rbAFrame);
|
||||
rbBFrame.deSerializeFloat(coneData->m_rbBFrame);
|
||||
coneTwist = new btConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame);
|
||||
coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame);
|
||||
} else
|
||||
{
|
||||
btTransform rbAFrame;
|
||||
rbAFrame.deSerializeFloat(coneData->m_rbAFrame);
|
||||
coneTwist = new btConeTwistConstraint(*rbA,rbAFrame);
|
||||
coneTwist = createConeTwistConstraint(*rbA,rbAFrame);
|
||||
}
|
||||
coneTwist->setLimit(coneData->m_swingSpan1,coneData->m_swingSpan2,coneData->m_twistSpan,coneData->m_limitSoftness,coneData->m_biasFactor,coneData->m_relaxationFactor);
|
||||
coneTwist->setDamping(coneData->m_damping);
|
||||
m_dynamicsWorld->addConstraint(coneTwist,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
|
||||
coneTwist->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||
|
||||
|
||||
constraint = coneTwist;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -693,12 +778,12 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btTransform rbAFrame,rbBFrame;
|
||||
rbAFrame.deSerializeFloat(dofData->m_rbAFrame);
|
||||
rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
|
||||
dof = new btGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
|
||||
dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
|
||||
} else
|
||||
{
|
||||
btTransform rbBFrame;
|
||||
rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
|
||||
dof = new btGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
|
||||
dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
|
||||
}
|
||||
btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
|
||||
angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit);
|
||||
@@ -711,8 +796,7 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
dof->setLinearLowerLimit(linLowerLimit);
|
||||
dof->setLinearUpperLimit(linUpperlimit);
|
||||
|
||||
m_dynamicsWorld->addConstraint(dof,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
|
||||
dof->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||
constraint = dof;
|
||||
break;
|
||||
}
|
||||
case SLIDER_CONSTRAINT_TYPE:
|
||||
@@ -724,22 +808,19 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
btTransform rbAFrame,rbBFrame;
|
||||
rbAFrame.deSerializeFloat(sliderData->m_rbAFrame);
|
||||
rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);
|
||||
slider = new btSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
|
||||
slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
|
||||
} else
|
||||
{
|
||||
btTransform rbBFrame;
|
||||
rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);
|
||||
slider = new btSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
|
||||
slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
|
||||
}
|
||||
slider->setLowerLinLimit(sliderData->m_linearLowerLimit);
|
||||
slider->setUpperLinLimit(sliderData->m_linearUpperLimit);
|
||||
slider->setLowerAngLimit(sliderData->m_angularLowerLimit);
|
||||
slider->setUpperAngLimit(sliderData->m_angularUpperLimit);
|
||||
slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0);
|
||||
|
||||
m_dynamicsWorld->addConstraint(slider,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
|
||||
slider->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||
|
||||
constraint = slider;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -749,22 +830,25 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
|
||||
}
|
||||
};
|
||||
|
||||
if (constraint)
|
||||
{
|
||||
constraint->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||
if (constraintData->m_name)
|
||||
{
|
||||
char* newname = duplicateName(constraintData->m_name);
|
||||
m_nameConstraintMap.insert(newname,constraint);
|
||||
m_objectNameMap.insert(constraint,newname);
|
||||
}
|
||||
if(m_dynamicsWorld)
|
||||
m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
btTypedConstraint* btBulletWorldImporter::createUniversalD6Constraint(class btRigidBody* body0,class btRigidBody* otherBody,
|
||||
btTransform& localAttachmentFrameRef,
|
||||
btTransform& localAttachmentOther,
|
||||
const btVector3& linearMinLimits,
|
||||
const btVector3& linearMaxLimits,
|
||||
const btVector3& angularMinLimits,
|
||||
const btVector3& angularMaxLimits,
|
||||
bool disableCollisionsBetweenLinkedBodies)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
btCollisionObject* btBulletWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName)
|
||||
{
|
||||
@@ -784,69 +868,102 @@ btRigidBody* btBulletWorldImporter::createRigidBody(bool isDynamic, btScalar ma
|
||||
btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);
|
||||
body->setWorldTransform(startTransform);
|
||||
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
if (m_dynamicsWorld)
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
|
||||
if (bodyName)
|
||||
{
|
||||
char* newname = duplicateName(bodyName);
|
||||
m_objectNameMap.insert(body,newname);
|
||||
m_nameBodyMap.insert(newname,body);
|
||||
}
|
||||
m_allocatedRigidBodies.push_back(body);
|
||||
return body;
|
||||
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
|
||||
{
|
||||
return 0;
|
||||
btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
btCollisionShape* btBulletWorldImporter::createBoxShape(const btVector3& halfExtents)
|
||||
{
|
||||
return new btBoxShape(halfExtents);
|
||||
btBoxShape* shape = new btBoxShape(halfExtents);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
btCollisionShape* btBulletWorldImporter::createSphereShape(btScalar radius)
|
||||
{
|
||||
return new btSphereShape(radius);
|
||||
btSphereShape* shape = new btSphereShape(radius);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height)
|
||||
{
|
||||
return new btCapsuleShapeX(radius,height);
|
||||
btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height)
|
||||
{
|
||||
return new btCapsuleShape(radius,height);
|
||||
btCapsuleShape* shape = new btCapsuleShape(radius,height);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height)
|
||||
{
|
||||
return new btCapsuleShapeZ(radius,height);
|
||||
btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createCylinderShapeX(btScalar radius,btScalar height)
|
||||
{
|
||||
return new btCylinderShapeX(btVector3(height,radius,radius));
|
||||
btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius));
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createCylinderShapeY(btScalar radius,btScalar height)
|
||||
{
|
||||
return new btCylinderShape(btVector3(radius,height,radius));
|
||||
btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius));
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height)
|
||||
{
|
||||
return new btCylinderShapeZ(btVector3(radius,radius,height));
|
||||
btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height));
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btTriangleIndexVertexArray* btBulletWorldImporter::createTriangleMeshContainer()
|
||||
{
|
||||
return new btTriangleIndexVertexArray();
|
||||
btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray();
|
||||
m_allocatedTriangleIndexArrays.push_back(in);
|
||||
return in;
|
||||
}
|
||||
|
||||
btOptimizedBvh* btBulletWorldImporter::createOptimizedBvh()
|
||||
{
|
||||
return new btOptimizedBvh();
|
||||
btOptimizedBvh* bvh = new btOptimizedBvh();
|
||||
m_allocatedBvhs.push_back(bvh);
|
||||
return bvh;
|
||||
}
|
||||
|
||||
|
||||
btTriangleInfoMap* btBulletWorldImporter::createTriangleInfoMap()
|
||||
{
|
||||
return new btTriangleInfoMap();
|
||||
btTriangleInfoMap* tim = new btTriangleInfoMap();
|
||||
m_allocatedTriangleInfoMaps.push_back(tim);
|
||||
return tim;
|
||||
}
|
||||
|
||||
btBvhTriangleMeshShape* btBulletWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh)
|
||||
@@ -855,9 +972,14 @@ btBvhTriangleMeshShape* btBulletWorldImporter::createBvhTriangleMeshShape(btStri
|
||||
{
|
||||
btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false);
|
||||
bvhTriMesh->setOptimizedBvh(bvh);
|
||||
m_allocatedCollisionShapes.push_back(bvhTriMesh);
|
||||
return bvhTriMesh;
|
||||
}
|
||||
return new btBvhTriangleMeshShape(trimesh,true);
|
||||
|
||||
btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true);
|
||||
m_allocatedCollisionShapes.push_back(ts);
|
||||
return ts;
|
||||
|
||||
}
|
||||
btCollisionShape* btBulletWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh)
|
||||
{
|
||||
@@ -865,16 +987,23 @@ btCollisionShape* btBulletWorldImporter::createConvexTriangleMeshShape(btStridin
|
||||
}
|
||||
btGImpactMeshShape* btBulletWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh)
|
||||
{
|
||||
return new btGImpactMeshShape(trimesh);
|
||||
btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh);
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
|
||||
}
|
||||
btConvexHullShape* btBulletWorldImporter::createConvexHullShape()
|
||||
{
|
||||
return new btConvexHullShape();
|
||||
btConvexHullShape* shape = new btConvexHullShape();
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btCompoundShape* btBulletWorldImporter::createCompoundShape()
|
||||
{
|
||||
return new btCompoundShape();
|
||||
btCompoundShape* shape = new btCompoundShape();
|
||||
m_allocatedCollisionShapes.push_back(shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
btRigidBody& btBulletWorldImporter::getFixedBody()
|
||||
@@ -884,3 +1013,163 @@ btRigidBody& btBulletWorldImporter::getFixedBody()
|
||||
return s_fixed;
|
||||
}
|
||||
|
||||
btPoint2PointConstraint* btBulletWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB)
|
||||
{
|
||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,rbB,pivotInA,pivotInB);
|
||||
m_allocatedConstraints.push_back(p2p);
|
||||
return p2p;
|
||||
}
|
||||
|
||||
btPoint2PointConstraint* btBulletWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA)
|
||||
{
|
||||
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,pivotInA);
|
||||
m_allocatedConstraints.push_back(p2p);
|
||||
return p2p;
|
||||
}
|
||||
|
||||
|
||||
btHingeConstraint* btBulletWorldImporter::createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA)
|
||||
{
|
||||
btHingeConstraint* hinge = new btHingeConstraint(rbA,rbB,rbAFrame,rbBFrame,useReferenceFrameA);
|
||||
m_allocatedConstraints.push_back(hinge);
|
||||
return hinge;
|
||||
}
|
||||
|
||||
btHingeConstraint* btBulletWorldImporter::createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA)
|
||||
{
|
||||
btHingeConstraint* hinge = new btHingeConstraint(rbA,rbAFrame,useReferenceFrameA);
|
||||
m_allocatedConstraints.push_back(hinge);
|
||||
return hinge;
|
||||
}
|
||||
|
||||
btConeTwistConstraint* btBulletWorldImporter::createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame)
|
||||
{
|
||||
btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbB,rbAFrame,rbBFrame);
|
||||
m_allocatedConstraints.push_back(cone);
|
||||
return cone;
|
||||
}
|
||||
|
||||
btConeTwistConstraint* btBulletWorldImporter::createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame)
|
||||
{
|
||||
btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbAFrame);
|
||||
m_allocatedConstraints.push_back(cone);
|
||||
return cone;
|
||||
}
|
||||
|
||||
|
||||
btGeneric6DofConstraint* btBulletWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
|
||||
{
|
||||
btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);
|
||||
m_allocatedConstraints.push_back(dof);
|
||||
return dof;
|
||||
}
|
||||
|
||||
btGeneric6DofConstraint* btBulletWorldImporter::createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB)
|
||||
{
|
||||
btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbB,frameInB,useLinearReferenceFrameB);
|
||||
m_allocatedConstraints.push_back(dof);
|
||||
return dof;
|
||||
}
|
||||
btSliderConstraint* btBulletWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
|
||||
{
|
||||
btSliderConstraint* slider = new btSliderConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);
|
||||
m_allocatedConstraints.push_back(slider);
|
||||
return slider;
|
||||
}
|
||||
|
||||
btSliderConstraint* btBulletWorldImporter::createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA)
|
||||
{
|
||||
btSliderConstraint* slider = new btSliderConstraint(rbB,frameInB,useLinearReferenceFrameA);
|
||||
m_allocatedConstraints.push_back(slider);
|
||||
return slider;
|
||||
}
|
||||
|
||||
|
||||
// query for data
|
||||
int btBulletWorldImporter::getNumCollisionShapes() const
|
||||
{
|
||||
return m_allocatedCollisionShapes.size();
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::getCollisionShapeByIndex(int index)
|
||||
{
|
||||
return m_allocatedCollisionShapes[index];
|
||||
}
|
||||
|
||||
btCollisionShape* btBulletWorldImporter::getCollisionShapeByName(const char* name)
|
||||
{
|
||||
btCollisionShape** shapePtr = m_nameShapeMap.find(name);
|
||||
if (shapePtr&& *shapePtr)
|
||||
{
|
||||
return *shapePtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
btRigidBody* btBulletWorldImporter::getRigidBodyByName(const char* name)
|
||||
{
|
||||
btRigidBody** bodyPtr = m_nameBodyMap.find(name);
|
||||
if (bodyPtr && *bodyPtr)
|
||||
{
|
||||
*bodyPtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
btTypedConstraint* btBulletWorldImporter::getConstraintByName(const char* name)
|
||||
{
|
||||
btTypedConstraint** constraintPtr = m_nameConstraintMap.find(name);
|
||||
if (constraintPtr && *constraintPtr)
|
||||
{
|
||||
return *constraintPtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* btBulletWorldImporter::getNameForPointer(const void* ptr) const
|
||||
{
|
||||
const char*const * namePtr = m_objectNameMap.find(ptr);
|
||||
if (namePtr && *namePtr)
|
||||
return *namePtr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int btBulletWorldImporter::getNumRigidBodies() const
|
||||
{
|
||||
return m_allocatedRigidBodies.size();
|
||||
}
|
||||
|
||||
btCollisionObject* btBulletWorldImporter::getRigidBodyByIndex(int index) const
|
||||
{
|
||||
return m_allocatedRigidBodies[index];
|
||||
}
|
||||
int btBulletWorldImporter::getNumConstraints() const
|
||||
{
|
||||
return m_allocatedConstraints.size();
|
||||
}
|
||||
|
||||
btTypedConstraint* btBulletWorldImporter::getConstraintByIndex(int index) const
|
||||
{
|
||||
return m_allocatedConstraints[index];
|
||||
}
|
||||
|
||||
int btBulletWorldImporter::getNumBvhs() const
|
||||
{
|
||||
return m_allocatedBvhs.size();
|
||||
}
|
||||
btOptimizedBvh* btBulletWorldImporter::getBvhByIndex(int index) const
|
||||
{
|
||||
return m_allocatedBvhs[index];
|
||||
}
|
||||
|
||||
int btBulletWorldImporter::getNumTriangleInfoMaps() const
|
||||
{
|
||||
return m_allocatedTriangleInfoMaps.size();
|
||||
}
|
||||
|
||||
btTriangleInfoMap* btBulletWorldImporter::getTriangleInfoMapByIndex(int index) const
|
||||
{
|
||||
return m_allocatedTriangleInfoMaps[index];
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,12 @@ class btGImpactMeshShape;
|
||||
class btOptimizedBvh;
|
||||
struct btTriangleInfoMap;
|
||||
class btBvhTriangleMeshShape;
|
||||
class btPoint2PointConstraint;
|
||||
class btHingeConstraint;
|
||||
class btConeTwistConstraint;
|
||||
class btGeneric6DofConstraint;
|
||||
class btSliderConstraint;
|
||||
|
||||
|
||||
|
||||
namespace bParse
|
||||
@@ -58,18 +64,40 @@ protected:
|
||||
|
||||
btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData );
|
||||
|
||||
btAlignedObjectArray<btCollisionShape*> m_allocatedCollisionShapes;
|
||||
btAlignedObjectArray<btCollisionShape*> m_allocatedCollisionShapes;
|
||||
btAlignedObjectArray<btCollisionObject*> m_allocatedRigidBodies;
|
||||
btAlignedObjectArray<btTypedConstraint*> m_allocatedConstraints;
|
||||
btAlignedObjectArray<btOptimizedBvh*> m_allocatedBvhs;
|
||||
btAlignedObjectArray<btTriangleInfoMap*> m_allocatedTriangleInfoMaps;
|
||||
btAlignedObjectArray<btTriangleIndexVertexArray*> m_allocatedTriangleIndexArrays;
|
||||
btAlignedObjectArray<char*> m_allocatedNames;
|
||||
|
||||
btHashMap<btHashPtr,btOptimizedBvh*> m_bvhMap;
|
||||
btHashMap<btHashPtr,btTriangleInfoMap*> m_timMap;
|
||||
|
||||
btHashMap<btHashString,btCollisionShape*> m_nameShapeMap;
|
||||
btHashMap<btHashString,btRigidBody*> m_nameBodyMap;
|
||||
btHashMap<btHashString,btTypedConstraint*> m_nameConstraintMap;
|
||||
btHashMap<btHashPtr,const char*> m_objectNameMap;
|
||||
|
||||
//methods
|
||||
|
||||
btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
|
||||
|
||||
static btRigidBody& getFixedBody();
|
||||
|
||||
char* duplicateName(const char* name);
|
||||
|
||||
public:
|
||||
|
||||
btBulletWorldImporter(btDynamicsWorld* world);
|
||||
btBulletWorldImporter(btDynamicsWorld* world=0);
|
||||
|
||||
virtual ~btBulletWorldImporter();
|
||||
|
||||
///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load.
|
||||
///make sure you don't use the dynamics world containing objects after you call this method
|
||||
void deleteAllData();
|
||||
|
||||
bool loadFile(const char* fileName);
|
||||
|
||||
///the memoryBuffer might be modified (for example if endian swaps are necessary)
|
||||
@@ -87,25 +115,31 @@ public:
|
||||
return m_verboseDumpAllTypes;
|
||||
}
|
||||
|
||||
///those virtuals are called by load
|
||||
virtual btTypedConstraint* createUniversalD6Constraint(
|
||||
class btRigidBody* body0,class btRigidBody* otherBody,
|
||||
btTransform& localAttachmentFrameRef,
|
||||
btTransform& localAttachmentOther,
|
||||
const btVector3& linearMinLimits,
|
||||
const btVector3& linearMaxLimits,
|
||||
const btVector3& angularMinLimits,
|
||||
const btVector3& angularMaxLimits,
|
||||
bool disableCollisionsBetweenLinkedBodies
|
||||
);
|
||||
// query for data
|
||||
int getNumCollisionShapes() const;
|
||||
btCollisionShape* getCollisionShapeByIndex(int index);
|
||||
int getNumRigidBodies() const;
|
||||
btCollisionObject* getRigidBodyByIndex(int index) const;
|
||||
int getNumConstraints() const;
|
||||
btTypedConstraint* getConstraintByIndex(int index) const;
|
||||
int getNumBvhs() const;
|
||||
btOptimizedBvh* getBvhByIndex(int index) const;
|
||||
int getNumTriangleInfoMaps() const;
|
||||
btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const;
|
||||
|
||||
virtual btRigidBody* createRigidBody(bool isDynamic,
|
||||
btScalar mass,
|
||||
const btTransform& startTransform,
|
||||
btCollisionShape* shape,const char* bodyName);
|
||||
// queris involving named objects
|
||||
btCollisionShape* getCollisionShapeByName(const char* name);
|
||||
btRigidBody* getRigidBodyByName(const char* name);
|
||||
btTypedConstraint* getConstraintByName(const char* name);
|
||||
const char* getNameForPointer(const void* ptr) const;
|
||||
|
||||
///those virtuals are called by load and can be overridden by the user
|
||||
|
||||
//bodies
|
||||
virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
||||
virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
||||
|
||||
///shapes
|
||||
|
||||
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
|
||||
virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
|
||||
@@ -119,13 +153,27 @@ public:
|
||||
virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
|
||||
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
|
||||
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
|
||||
virtual btOptimizedBvh* createOptimizedBvh();
|
||||
virtual btTriangleInfoMap* createTriangleInfoMap();
|
||||
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
|
||||
virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh);
|
||||
virtual class btConvexHullShape* createConvexHullShape();
|
||||
virtual class btCompoundShape* createCompoundShape();
|
||||
|
||||
///acceleration and connectivity structures
|
||||
virtual btOptimizedBvh* createOptimizedBvh();
|
||||
virtual btTriangleInfoMap* createTriangleInfoMap();
|
||||
|
||||
///constraints
|
||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
|
||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
|
||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false);
|
||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false);
|
||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
|
||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
|
||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
|
||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||
|
||||
};
|
||||
|
||||
#endif //BULLET_WORLD_IMPORTER_H
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
IF (BUILD_BLEND_DEMO)
|
||||
IF (BUILD_BLEND_DEMO OR INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
SUBDIRS(BlenderSerialize )
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
|
||||
# makesdna and HeaderGenerator are for advanced use only
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BU_AlgebraicPolynomialSolver.h"
|
||||
#include <math.h>
|
||||
#include <btMinMax.h>
|
||||
|
||||
int BU_AlgebraicPolynomialSolver::Solve2Quadratic(btScalar p, btScalar q)
|
||||
{
|
||||
|
||||
btScalar basic_h_local;
|
||||
btScalar basic_h_local_delta;
|
||||
|
||||
basic_h_local = p * 0.5f;
|
||||
basic_h_local_delta = basic_h_local * basic_h_local - q;
|
||||
if (basic_h_local_delta > 0.0f) {
|
||||
basic_h_local_delta = btSqrt(basic_h_local_delta);
|
||||
m_roots[0] = - basic_h_local + basic_h_local_delta;
|
||||
m_roots[1] = - basic_h_local - basic_h_local_delta;
|
||||
return 2;
|
||||
}
|
||||
else if (btGreaterEqual(basic_h_local_delta, SIMD_EPSILON)) {
|
||||
m_roots[0] = - basic_h_local;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int BU_AlgebraicPolynomialSolver::Solve2QuadraticFull(btScalar a,btScalar b, btScalar c)
|
||||
{
|
||||
btScalar radical = b * b - 4.0f * a * c;
|
||||
if(radical >= 0.f)
|
||||
{
|
||||
btScalar sqrtRadical = btSqrt(radical);
|
||||
btScalar idenom = 1.0f/(2.0f * a);
|
||||
m_roots[0]=(-b + sqrtRadical) * idenom;
|
||||
m_roots[1]=(-b - sqrtRadical) * idenom;
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define cubic_rt(x) \
|
||||
((x) > 0.0f ? btPow((btScalar)(x), 0.333333333333333333333333f) : \
|
||||
((x) < 0.0f ? -btPow((btScalar)-(x), 0.333333333333333333333333f) : 0.0f))
|
||||
|
||||
|
||||
|
||||
/* */
|
||||
/* this function solves the following cubic equation: */
|
||||
/* */
|
||||
/* 3 2 */
|
||||
/* lead * x + a * x + b * x + c = 0. */
|
||||
/* */
|
||||
/* it returns the number of different roots found, and stores the roots in */
|
||||
/* roots[0,2]. it returns -1 for a degenerate equation 0 = 0. */
|
||||
/* */
|
||||
int BU_AlgebraicPolynomialSolver::Solve3Cubic(btScalar lead, btScalar a, btScalar b, btScalar c)
|
||||
{
|
||||
btScalar p, q, r;
|
||||
btScalar delta, u, phi;
|
||||
btScalar dummy;
|
||||
|
||||
if (lead != 1.0) {
|
||||
/* */
|
||||
/* transform into normal form: x^3 + a x^2 + b x + c = 0 */
|
||||
/* */
|
||||
if (btEqual(lead, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* we have a x^2 + b x + c = 0 */
|
||||
/* */
|
||||
if (btEqual(a, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* we have b x + c = 0 */
|
||||
/* */
|
||||
if (btEqual(b, SIMD_EPSILON)) {
|
||||
if (btEqual(c, SIMD_EPSILON)) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_roots[0] = -c / b;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p = c / a;
|
||||
q = b / a;
|
||||
return Solve2QuadraticFull(a,b,c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
a = a / lead;
|
||||
b = b / lead;
|
||||
c = c / lead;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
/* we substitute x = y - a / 3 in order to eliminate the quadric term. */
|
||||
/* we get x^3 + p x + q = 0 */
|
||||
/* */
|
||||
a /= 3.0f;
|
||||
u = a * a;
|
||||
p = b / 3.0f - u;
|
||||
q = a * (2.0f * u - b) + c;
|
||||
|
||||
/* */
|
||||
/* now use Cardano's formula */
|
||||
/* */
|
||||
if (btEqual(p, SIMD_EPSILON)) {
|
||||
if (btEqual(q, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* one triple root */
|
||||
/* */
|
||||
m_roots[0] = -a;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* */
|
||||
/* one real and two complex roots */
|
||||
/* */
|
||||
m_roots[0] = cubic_rt(-q) - a;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
q /= 2.0f;
|
||||
delta = p * p * p + q * q;
|
||||
if (delta > 0.0f) {
|
||||
/* */
|
||||
/* one real and two complex roots. note that v = -p / u. */
|
||||
/* */
|
||||
u = -q + btSqrt(delta);
|
||||
u = cubic_rt(u);
|
||||
m_roots[0] = u - p / u - a;
|
||||
return 1;
|
||||
}
|
||||
else if (delta < 0.0) {
|
||||
/* */
|
||||
/* Casus irreducibilis: we have three real roots */
|
||||
/* */
|
||||
r = btSqrt(-p);
|
||||
p *= -r;
|
||||
r *= 2.0;
|
||||
phi = btAcos(-q / p) / 3.0f;
|
||||
dummy = SIMD_2_PI / 3.0f;
|
||||
m_roots[0] = r * btCos(phi) - a;
|
||||
m_roots[1] = r * btCos(phi + dummy) - a;
|
||||
m_roots[2] = r * btCos(phi - dummy) - a;
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
/* */
|
||||
/* one single and one btScalar root */
|
||||
/* */
|
||||
r = cubic_rt(-q);
|
||||
m_roots[0] = 2.0f * r - a;
|
||||
m_roots[1] = -r - a;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
/* this function solves the following quartic equation: */
|
||||
/* */
|
||||
/* 4 3 2 */
|
||||
/* lead * x + a * x + b * x + c * x + d = 0. */
|
||||
/* */
|
||||
/* it returns the number of different roots found, and stores the roots in */
|
||||
/* roots[0,3]. it returns -1 for a degenerate equation 0 = 0. */
|
||||
/* */
|
||||
int BU_AlgebraicPolynomialSolver::Solve4Quartic(btScalar lead, btScalar a, btScalar b, btScalar c, btScalar d)
|
||||
{
|
||||
btScalar p, q ,r;
|
||||
btScalar u, v, w;
|
||||
int i, num_roots, num_tmp;
|
||||
//btScalar tmp[2];
|
||||
|
||||
if (lead != 1.0) {
|
||||
/* */
|
||||
/* transform into normal form: x^4 + a x^3 + b x^2 + c x + d = 0 */
|
||||
/* */
|
||||
if (btEqual(lead, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* we have a x^3 + b x^2 + c x + d = 0 */
|
||||
/* */
|
||||
if (btEqual(a, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* we have b x^2 + c x + d = 0 */
|
||||
/* */
|
||||
if (btEqual(b, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* we have c x + d = 0 */
|
||||
/* */
|
||||
if (btEqual(c, SIMD_EPSILON)) {
|
||||
if (btEqual(d, SIMD_EPSILON)) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_roots[0] = -d / c;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p = c / b;
|
||||
q = d / b;
|
||||
return Solve2QuadraticFull(b,c,d);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Solve3Cubic(1.0, b / a, c / a, d / a);
|
||||
}
|
||||
}
|
||||
else {
|
||||
a = a / lead;
|
||||
b = b / lead;
|
||||
c = c / lead;
|
||||
d = d / lead;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
/* we substitute x = y - a / 4 in order to eliminate the cubic term. */
|
||||
/* we get: y^4 + p y^2 + q y + r = 0. */
|
||||
/* */
|
||||
a /= 4.0f;
|
||||
p = b - 6.0f * a * a;
|
||||
q = a * (8.0f * a * a - 2.0f * b) + c;
|
||||
r = a * (a * (b - 3.f * a * a) - c) + d;
|
||||
if (btEqual(q, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* biquadratic equation: y^4 + p y^2 + r = 0. */
|
||||
/* */
|
||||
num_roots = Solve2Quadratic(p, r);
|
||||
if (num_roots > 0) {
|
||||
if (m_roots[0] > 0.0f) {
|
||||
if (num_roots > 1) {
|
||||
if ((m_roots[1] > 0.0f) && (m_roots[1] != m_roots[0])) {
|
||||
u = btSqrt(m_roots[1]);
|
||||
m_roots[2] = u - a;
|
||||
m_roots[3] = -u - a;
|
||||
u = btSqrt(m_roots[0]);
|
||||
m_roots[0] = u - a;
|
||||
m_roots[1] = -u - a;
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
u = btSqrt(m_roots[0]);
|
||||
m_roots[0] = u - a;
|
||||
m_roots[1] = -u - a;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
u = btSqrt(m_roots[0]);
|
||||
m_roots[0] = u - a;
|
||||
m_roots[1] = -u - a;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (btEqual(r, SIMD_EPSILON)) {
|
||||
/* */
|
||||
/* no absolute term: y (y^3 + p y + q) = 0. */
|
||||
/* */
|
||||
num_roots = Solve3Cubic(1.0, 0.0, p, q);
|
||||
for (i = 0; i < num_roots; ++i) m_roots[i] -= a;
|
||||
if (num_roots != -1) {
|
||||
m_roots[num_roots] = -a;
|
||||
++num_roots;
|
||||
}
|
||||
else {
|
||||
m_roots[0] = -a;
|
||||
num_roots = 1;;
|
||||
}
|
||||
return num_roots;
|
||||
}
|
||||
else {
|
||||
/* */
|
||||
/* we solve the resolvent cubic equation */
|
||||
/* */
|
||||
num_roots = Solve3Cubic(1.0f, -0.5f * p, -r, 0.5f * r * p - 0.125f * q * q);
|
||||
if (num_roots == -1) {
|
||||
num_roots = 1;
|
||||
m_roots[0] = 0.0f;
|
||||
}
|
||||
|
||||
/* */
|
||||
/* build two quadric equations */
|
||||
/* */
|
||||
w = m_roots[0];
|
||||
u = w * w - r;
|
||||
v = 2.0f * w - p;
|
||||
|
||||
if (btEqual(u, SIMD_EPSILON))
|
||||
u = 0.0;
|
||||
else if (u > 0.0f)
|
||||
u = btSqrt(u);
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (btEqual(v, SIMD_EPSILON))
|
||||
v = 0.0;
|
||||
else if (v > 0.0f)
|
||||
v = btSqrt(v);
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (q < 0.0f) v = -v;
|
||||
w -= u;
|
||||
num_roots=Solve2Quadratic(v, w);
|
||||
for (i = 0; i < num_roots; ++i)
|
||||
{
|
||||
m_roots[i] -= a;
|
||||
}
|
||||
w += 2.0f *u;
|
||||
btScalar tmp[2];
|
||||
tmp[0] = m_roots[0];
|
||||
tmp[1] = m_roots[1];
|
||||
|
||||
num_tmp = Solve2Quadratic(-v, w);
|
||||
for (i = 0; i < num_tmp; ++i)
|
||||
{
|
||||
m_roots[i + num_roots] = tmp[i] - a;
|
||||
m_roots[i]=tmp[i];
|
||||
}
|
||||
|
||||
return (num_tmp + num_roots);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H
|
||||
#define BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H
|
||||
|
||||
#include "BU_PolynomialSolverInterface.h"
|
||||
|
||||
/// BU_AlgebraicPolynomialSolver implements polynomial root finding by analytically solving algebraic equations.
|
||||
/// Polynomials up to 4rd degree are supported, Cardano's formula is used for 3rd degree
|
||||
class BU_AlgebraicPolynomialSolver : public BUM_PolynomialSolverInterface
|
||||
{
|
||||
public:
|
||||
BU_AlgebraicPolynomialSolver() {};
|
||||
|
||||
int Solve2Quadratic(btScalar p, btScalar q);
|
||||
int Solve2QuadraticFull(btScalar a,btScalar b, btScalar c);
|
||||
int Solve3Cubic(btScalar lead, btScalar a, btScalar b, btScalar c);
|
||||
int Solve4Quartic(btScalar lead, btScalar a, btScalar b, btScalar c, btScalar d);
|
||||
|
||||
|
||||
btScalar GetRoot(int i) const
|
||||
{
|
||||
return m_roots[i];
|
||||
}
|
||||
|
||||
private:
|
||||
btScalar m_roots[4];
|
||||
|
||||
};
|
||||
|
||||
#endif //BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BU_Collidable.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include <LinearMath/btTransform.h>
|
||||
#include "BU_MotionStateInterface.h"
|
||||
|
||||
BU_Collidable::BU_Collidable(BU_MotionStateInterface& motion,btPolyhedralConvexShape& shape,void* userPointer )
|
||||
:m_motionState(motion),m_shape(shape),m_userPointer(userPointer)
|
||||
{
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BU_COLLIDABLE
|
||||
#define BU_COLLIDABLE
|
||||
|
||||
|
||||
class btPolyhedralConvexShape;
|
||||
class BU_MotionStateInterface;
|
||||
#include <LinearMath/btPoint3.h>
|
||||
|
||||
class BU_Collidable
|
||||
{
|
||||
public:
|
||||
BU_Collidable(BU_MotionStateInterface& motion,btPolyhedralConvexShape& shape, void* userPointer);
|
||||
|
||||
void* GetUserPointer() const
|
||||
{
|
||||
return m_userPointer;
|
||||
}
|
||||
|
||||
BU_MotionStateInterface& GetMotionState()
|
||||
{
|
||||
return m_motionState;
|
||||
}
|
||||
inline const BU_MotionStateInterface& GetMotionState() const
|
||||
{
|
||||
return m_motionState;
|
||||
}
|
||||
|
||||
inline const btPolyhedralConvexShape& GetShape() const
|
||||
{
|
||||
return m_shape;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
BU_MotionStateInterface& m_motionState;
|
||||
btPolyhedralConvexShape& m_shape;
|
||||
void* m_userPointer;
|
||||
|
||||
};
|
||||
|
||||
#endif //BU_COLLIDABLE
|
||||
@@ -1,581 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "BU_CollisionPair.h"
|
||||
#include "NarrowPhaseCollision/BU_VertexPoly.h"
|
||||
#include "NarrowPhaseCollision/BU_EdgeEdge.h"
|
||||
#include "BU_Collidable.h"
|
||||
|
||||
|
||||
#include "BU_MotionStateInterface.h"
|
||||
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
|
||||
#include <btMinMax.h>
|
||||
#include "LinearMath/btTransformUtil.h"
|
||||
|
||||
|
||||
|
||||
BU_CollisionPair::BU_CollisionPair(const btPolyhedralConvexShape* convexA,const btPolyhedralConvexShape* convexB,btScalar tolerance)
|
||||
: m_convexA(convexA),m_convexB(convexB),m_screwing(btVector3(0,0,0),btVector3(0,0,0)),
|
||||
m_tolerance(tolerance)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// if there exists a time-of-impact between any feature_pair (edgeA,edgeB),
|
||||
// (vertexA,faceB) or (vertexB,faceA) in [0..1], report true and smallest time
|
||||
|
||||
|
||||
/*
|
||||
bool BU_CollisionPair::GetTimeOfImpact(const btVector3& linearMotionA,const btQuaternion& angularMotionA,const btVector3& linearMotionB,const btQuaternion& angularMotionB, btScalar& toi,btTransform& impactTransA,btTransform& impactTransB)
|
||||
|
||||
*/
|
||||
|
||||
bool BU_CollisionPair::calcTimeOfImpact(
|
||||
const btTransform& fromA,
|
||||
const btTransform& toA,
|
||||
const btTransform& fromB,
|
||||
const btTransform& toB,
|
||||
CastResult& result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
btVector3 linvelA,angvelA;
|
||||
btVector3 linvelB,angvelB;
|
||||
|
||||
btTransformUtil::calculateVelocity(fromA,toA,1.f,linvelA,angvelA);
|
||||
btTransformUtil::calculateVelocity(fromB,toB,1.f,linvelB,angvelB);
|
||||
|
||||
|
||||
btVector3 linearMotionA = toA.getOrigin() - fromA.getOrigin();
|
||||
btQuaternion angularMotionA(0,0,0,1.f);
|
||||
btVector3 linearMotionB = toB.getOrigin() - fromB.getOrigin();
|
||||
btQuaternion angularMotionB(0,0,0,1);
|
||||
|
||||
|
||||
|
||||
result.m_fraction = 1.f;
|
||||
|
||||
btTransform impactTransA;
|
||||
btTransform impactTransB;
|
||||
|
||||
int index=0;
|
||||
|
||||
btScalar toiUnscaled=result.m_fraction;
|
||||
const btScalar toiUnscaledLimit = result.m_fraction;
|
||||
|
||||
btTransform a2w;
|
||||
a2w = fromA;
|
||||
btTransform b2w = fromB;
|
||||
|
||||
/* debugging code
|
||||
{
|
||||
const int numvertsB = m_convexB->getNumVertices();
|
||||
for (int v=0;v<numvertsB;v++)
|
||||
{
|
||||
btPoint3 pt;
|
||||
m_convexB->getVertex(v,pt);
|
||||
pt = b2w * pt;
|
||||
char buf[1000];
|
||||
|
||||
if (pt.y() < 0.)
|
||||
{
|
||||
sprintf(buf,"PRE ERROR (%d) %.20E %.20E %.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
} else
|
||||
{
|
||||
sprintf(buf,"PRE %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
btTransform b2wp = b2w;
|
||||
|
||||
b2wp.setOrigin(b2w.getOrigin() + linearMotionB);
|
||||
b2wp.setRotation( b2w.getRotation() + angularMotionB);
|
||||
|
||||
impactTransB = b2wp;
|
||||
|
||||
btTransform a2wp;
|
||||
a2wp.setOrigin(a2w.getOrigin()+ linearMotionA);
|
||||
a2wp.setRotation(a2w.getRotation()+angularMotionA);
|
||||
|
||||
impactTransA = a2wp;
|
||||
|
||||
btTransform a2winv;
|
||||
a2winv = a2w.inverse();
|
||||
|
||||
btTransform b2wpinv;
|
||||
b2wpinv = b2wp.inverse();
|
||||
|
||||
btTransform b2winv;
|
||||
b2winv = b2w.inverse();
|
||||
|
||||
btTransform a2wpinv;
|
||||
a2wpinv = a2wp.inverse();
|
||||
|
||||
//Redon's version with concatenated transforms
|
||||
|
||||
btTransform relative;
|
||||
|
||||
relative = b2w * b2wpinv * a2wp * a2winv;
|
||||
|
||||
//relative = a2winv * a2wp * b2wpinv * b2w;
|
||||
|
||||
btQuaternion qrel;
|
||||
relative.getBasis().getRotation(qrel);
|
||||
|
||||
btVector3 linvel = relative.getOrigin();
|
||||
|
||||
if (linvel.length() < SCREWEPSILON)
|
||||
{
|
||||
linvel.setValue(0.,0.,0.);
|
||||
}
|
||||
btVector3 angvel;
|
||||
angvel[0] = 2.f * btAsin (qrel[0]);
|
||||
angvel[1] = 2.f * btAsin (qrel[1]);
|
||||
angvel[2] = 2.f * btAsin (qrel[2]);
|
||||
|
||||
if (angvel.length() < SCREWEPSILON)
|
||||
{
|
||||
angvel.setValue(0.f,0.f,0.f);
|
||||
}
|
||||
|
||||
//Redon's version with concatenated transforms
|
||||
m_screwing = BU_Screwing(linvel,angvel);
|
||||
|
||||
btTransform w2s;
|
||||
m_screwing.LocalMatrix(w2s);
|
||||
|
||||
btTransform s2w;
|
||||
s2w = w2s.inverse();
|
||||
|
||||
//impactTransA = a2w;
|
||||
//impactTransB = b2w;
|
||||
|
||||
bool hit = false;
|
||||
|
||||
if (btFuzzyZero(m_screwing.GetS()) && btFuzzyZero(m_screwing.GetW()))
|
||||
{
|
||||
//W = 0 , S = 0 , no collision
|
||||
//toi = 0;
|
||||
/*
|
||||
{
|
||||
const int numvertsB = m_convexB->getNumVertices();
|
||||
for (int v=0;v<numvertsB;v++)
|
||||
{
|
||||
btPoint3 pt;
|
||||
m_convexB->getVertex(v,pt);
|
||||
pt = impactTransB * pt;
|
||||
char buf[1000];
|
||||
|
||||
if (pt.y() < 0.)
|
||||
{
|
||||
sprintf(buf,"EARLY POST ERROR (%d) %.20E,%.20E,%.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf,"EARLY POST %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return false;//don't continue moving within epsilon
|
||||
}
|
||||
|
||||
#define EDGEEDGE
|
||||
#ifdef EDGEEDGE
|
||||
|
||||
BU_EdgeEdge edgeEdge;
|
||||
|
||||
//for all edged in A check agains all edges in B
|
||||
for (int ea = 0;ea < m_convexA->getNumEdges();ea++)
|
||||
{
|
||||
btPoint3 pA0,pA1;
|
||||
|
||||
m_convexA->getEdge(ea,pA0,pA1);
|
||||
|
||||
pA0= a2w * pA0;//in world space
|
||||
pA0 = w2s * pA0;//in screwing space
|
||||
|
||||
pA1= a2w * pA1;//in world space
|
||||
pA1 = w2s * pA1;//in screwing space
|
||||
|
||||
int numedgesB = m_convexB->getNumEdges();
|
||||
for (int eb = 0; eb < numedgesB;eb++)
|
||||
{
|
||||
{
|
||||
btPoint3 pB0,pB1;
|
||||
m_convexB->getEdge(eb,pB0,pB1);
|
||||
|
||||
pB0= b2w * pB0;//in world space
|
||||
pB0 = w2s * pB0;//in screwing space
|
||||
|
||||
pB1= b2w * pB1;//in world space
|
||||
pB1 = w2s * pB1;//in screwing space
|
||||
|
||||
|
||||
btScalar lambda,mu;
|
||||
|
||||
toiUnscaled = 1.;
|
||||
|
||||
btVector3 edgeDirA(pA1-pA0);
|
||||
btVector3 edgeDirB(pB1-pB0);
|
||||
|
||||
if (edgeEdge.GetTimeOfImpact(m_screwing,pA0,edgeDirA,pB0,edgeDirB,toiUnscaled,lambda,mu))
|
||||
{
|
||||
//printf("edgeedge potential hit\n");
|
||||
if (toiUnscaled>=0)
|
||||
{
|
||||
if (toiUnscaled < toiUnscaledLimit)
|
||||
{
|
||||
|
||||
//inside check is already done by checking the mu and gamma !
|
||||
|
||||
btPoint3 vtx = pA0+lambda * (pA1-pA0);
|
||||
btPoint3 hitpt = m_screwing.InBetweenPosition(vtx,toiUnscaled);
|
||||
|
||||
btPoint3 hitptWorld = s2w * hitpt;
|
||||
{
|
||||
|
||||
if (toiUnscaled < result.m_fraction)
|
||||
result.m_fraction = toiUnscaled;
|
||||
|
||||
hit = true;
|
||||
|
||||
btVector3 hitNormal = edgeDirB.cross(edgeDirA);
|
||||
|
||||
hitNormal = m_screwing.InBetweenVector(hitNormal,toiUnscaled);
|
||||
|
||||
|
||||
hitNormal.normalize();
|
||||
|
||||
//an approximated normal can be calculated by taking the cross product of both edges
|
||||
//take care of the sign !
|
||||
|
||||
btVector3 hitNormalWorld = s2w.getBasis() * hitNormal ;
|
||||
|
||||
btScalar dist = m_screwing.GetU().dot(hitNormalWorld);
|
||||
if (dist > 0)
|
||||
hitNormalWorld *= -1;
|
||||
|
||||
//todo: this is the wrong point, because b2winv is still at begin of motion
|
||||
// not at time-of-impact location!
|
||||
//bhitpt = b2winv * hitptWorld;
|
||||
|
||||
// m_manifold.SetContactPoint(BUM_FeatureEdgeEdge,index,ea,eb,hitptWorld,hitNormalWorld);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
};
|
||||
#endif //EDGEEDGE
|
||||
|
||||
#define VERTEXFACE
|
||||
#ifdef VERTEXFACE
|
||||
|
||||
// for all vertices in A, for each face in B,do vertex-face
|
||||
{
|
||||
const int numvertsA = m_convexA->getNumVertices();
|
||||
for (int v=0;v<numvertsA;v++)
|
||||
//int v=3;
|
||||
|
||||
{
|
||||
btPoint3 vtx;
|
||||
m_convexA->getVertex(v,vtx);
|
||||
|
||||
vtx = a2w * vtx;//in world space
|
||||
vtx = w2s * vtx;//in screwing space
|
||||
|
||||
const int numplanesB = m_convexB->getNumPlanes();
|
||||
|
||||
for (int p = 0 ; p < numplanesB; p++)
|
||||
//int p=2;
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
btVector3 planeNorm;
|
||||
btPoint3 planeSupport;
|
||||
|
||||
m_convexB->getPlane(planeNorm,planeSupport,p);
|
||||
|
||||
|
||||
planeSupport = b2w * planeSupport;//transform to world space
|
||||
btVector3 planeNormWorld = b2w.getBasis() * planeNorm;
|
||||
|
||||
planeSupport = w2s * planeSupport ; //transform to screwing space
|
||||
planeNorm = w2s.getBasis() * planeNormWorld;
|
||||
|
||||
planeNorm.normalize();
|
||||
|
||||
btScalar d = planeSupport.dot(planeNorm);
|
||||
|
||||
btVector4 planeEq(planeNorm[0],planeNorm[1],planeNorm[2],d);
|
||||
|
||||
BU_VertexPoly vtxApolyB;
|
||||
|
||||
toiUnscaled = 1.;
|
||||
|
||||
if ((p==2) && (v==6))
|
||||
{
|
||||
// printf("%f toiUnscaled\n",toiUnscaled);
|
||||
|
||||
}
|
||||
if (vtxApolyB.GetTimeOfImpact(m_screwing,vtx,planeEq,toiUnscaled,false))
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
if (toiUnscaled >= 0. )
|
||||
{
|
||||
//not only collect the first point, get every contactpoint, later we have to check the
|
||||
//manifold properly!
|
||||
|
||||
if (toiUnscaled <= toiUnscaledLimit)
|
||||
{
|
||||
// printf("toiUnscaled %f\n",toiUnscaled );
|
||||
|
||||
btPoint3 hitpt = m_screwing.InBetweenPosition(vtx,toiUnscaled);
|
||||
btVector3 hitNormal = m_screwing.InBetweenVector(planeNorm ,toiUnscaled);
|
||||
|
||||
btVector3 hitNormalWorld = s2w.getBasis() * hitNormal ;
|
||||
btPoint3 hitptWorld = s2w * hitpt;
|
||||
|
||||
|
||||
hitpt = b2winv * hitptWorld;
|
||||
//vertex has to be 'within' the facet's boundary
|
||||
if (m_convexB->isInside(hitpt,m_tolerance))
|
||||
{
|
||||
// m_manifold.SetContactPoint(BUM_FeatureVertexFace, index,v,p,hitptWorld,hitNormalWorld);
|
||||
|
||||
if (toiUnscaled < result.m_fraction)
|
||||
result.m_fraction= toiUnscaled;
|
||||
hit = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// for all vertices in B, for each face in A,do vertex-face
|
||||
//copy and pasted from all verts A -> all planes B so potential typos!
|
||||
//todo: make this into one method with a kind of 'swapped' logic
|
||||
//
|
||||
{
|
||||
const int numvertsB = m_convexB->getNumVertices();
|
||||
for (int v=0;v<numvertsB;v++)
|
||||
//int v=0;
|
||||
|
||||
{
|
||||
btPoint3 vtx;
|
||||
m_convexB->getVertex(v,vtx);
|
||||
|
||||
vtx = b2w * vtx;//in world space
|
||||
/*
|
||||
|
||||
char buf[1000];
|
||||
|
||||
if (vtx.y() < 0.)
|
||||
{
|
||||
sprintf(buf,"ERROR !!!!!!!!!\n",v,vtx.x(),vtx.y(),vtx.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
}
|
||||
sprintf(buf,"vertexWorld(%d) = (%.20E,%.20E,%.20E)\n",v,vtx.x(),vtx.y(),vtx.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
|
||||
*/
|
||||
vtx = w2s * vtx;//in screwing space
|
||||
|
||||
const int numplanesA = m_convexA->getNumPlanes();
|
||||
|
||||
for (int p = 0 ; p < numplanesA; p++)
|
||||
//int p=2;
|
||||
{
|
||||
|
||||
{
|
||||
btVector3 planeNorm;
|
||||
btPoint3 planeSupport;
|
||||
|
||||
m_convexA->getPlane(planeNorm,planeSupport,p);
|
||||
|
||||
|
||||
planeSupport = a2w * planeSupport;//transform to world space
|
||||
btVector3 planeNormWorld = a2w.getBasis() * planeNorm;
|
||||
|
||||
planeSupport = w2s * planeSupport ; //transform to screwing space
|
||||
planeNorm = w2s.getBasis() * planeNormWorld;
|
||||
|
||||
planeNorm.normalize();
|
||||
|
||||
btScalar d = planeSupport.dot(planeNorm);
|
||||
|
||||
btVector4 planeEq(planeNorm[0],planeNorm[1],planeNorm[2],d);
|
||||
|
||||
BU_VertexPoly vtxBpolyA;
|
||||
|
||||
toiUnscaled = 1.;
|
||||
|
||||
if (vtxBpolyA.GetTimeOfImpact(m_screwing,vtx,planeEq,toiUnscaled,true))
|
||||
{
|
||||
if (toiUnscaled>=0.)
|
||||
{
|
||||
if (toiUnscaled < toiUnscaledLimit)
|
||||
{
|
||||
btPoint3 hitpt = m_screwing.InBetweenPosition( vtx , -toiUnscaled);
|
||||
btVector3 hitNormal = m_screwing.InBetweenVector(-planeNorm ,-toiUnscaled);
|
||||
//btScalar len = hitNormal.length()-1;
|
||||
|
||||
//assert( btFuzzyZero(len) );
|
||||
|
||||
|
||||
btVector3 hitNormalWorld = s2w.getBasis() * hitNormal ;
|
||||
btPoint3 hitptWorld = s2w * hitpt;
|
||||
hitpt = a2winv * hitptWorld;
|
||||
|
||||
|
||||
//vertex has to be 'within' the facet's boundary
|
||||
if (m_convexA->isInside(hitpt,m_tolerance))
|
||||
{
|
||||
|
||||
// m_manifold.SetContactPoint(BUM_FeatureFaceVertex,index,p,v,hitptWorld,hitNormalWorld);
|
||||
if (toiUnscaled <result.m_fraction)
|
||||
result.m_fraction = toiUnscaled;
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif// VERTEXFACE
|
||||
|
||||
//the manifold now consists of all points/normals generated by feature-pairs that have a time-of-impact within this frame
|
||||
//in addition there are contact points from previous frames
|
||||
//we have to cleanup the manifold, using an additional epsilon/tolerance
|
||||
//as long as the distance from the contactpoint (in worldspace) to both objects is within this epsilon we keep the point
|
||||
//else throw it away
|
||||
|
||||
|
||||
if (hit)
|
||||
{
|
||||
|
||||
//try to avoid numerical drift on close contact
|
||||
|
||||
if (result.m_fraction < 0.00001)
|
||||
{
|
||||
// printf("toiUnscaledMin< 0.00001\n");
|
||||
impactTransA = a2w;
|
||||
impactTransB = b2w;
|
||||
|
||||
} else
|
||||
{
|
||||
|
||||
//btScalar vel = linearMotionB.length();
|
||||
|
||||
//todo: check this margin
|
||||
result.m_fraction *= 0.99f;
|
||||
|
||||
//move B to new position
|
||||
impactTransB.setOrigin(b2w.getOrigin()+ result.m_fraction*linearMotionB);
|
||||
btQuaternion ornB = b2w.getRotation()+angularMotionB*result.m_fraction;
|
||||
ornB.normalize();
|
||||
impactTransB.setRotation(ornB);
|
||||
|
||||
//now transform A
|
||||
btTransform a2s,a2b;
|
||||
a2s.mult( w2s , a2w);
|
||||
a2s= m_screwing.InBetweenTransform(a2s,result.m_fraction);
|
||||
a2s.multInverseLeft(w2s,a2s);
|
||||
a2b.multInverseLeft(b2w, a2s);
|
||||
|
||||
//transform by motion B
|
||||
impactTransA.mult(impactTransB, a2b);
|
||||
//normalize rotation
|
||||
btQuaternion orn;
|
||||
impactTransA.getBasis().getRotation(orn);
|
||||
orn.normalize();
|
||||
impactTransA.setBasis(btMatrix3x3(orn));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
const int numvertsB = m_convexB->getNumVertices();
|
||||
for (int v=0;v<numvertsB;v++)
|
||||
{
|
||||
btPoint3 pt;
|
||||
m_convexB->getVertex(v,pt);
|
||||
pt = impactTransB * pt;
|
||||
char buf[1000];
|
||||
|
||||
if (pt.y() < 0.)
|
||||
{
|
||||
sprintf(buf,"POST ERROR (%d) %.20E,%.20E,%.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf,"POST %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z());
|
||||
if (debugFile)
|
||||
fwrite(buf,1,strlen(buf),debugFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return hit;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BU_COLLISIONPAIR
|
||||
#define BU_COLLISIONPAIR
|
||||
|
||||
#include <NarrowPhaseCollision/BU_Screwing.h>
|
||||
#include <NarrowPhaseCollision/ConvexCast.h>
|
||||
|
||||
|
||||
#include <btQuaternion.h>
|
||||
|
||||
class btPolyhedralConvexShape;
|
||||
|
||||
|
||||
///BU_CollisionPair implements collision algorithm for algebraic time of impact calculation of feature based shapes.
|
||||
class BU_CollisionPair : public btConvexCast
|
||||
{
|
||||
|
||||
public:
|
||||
BU_CollisionPair(const btPolyhedralConvexShape* convexA,const btPolyhedralConvexShape* convexB,btScalar tolerance=0.2f);
|
||||
//toi
|
||||
|
||||
virtual bool calcTimeOfImpact(
|
||||
const btTransform& fromA,
|
||||
const btTransform& toA,
|
||||
const btTransform& fromB,
|
||||
const btTransform& toB,
|
||||
CastResult& result);
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
const btPolyhedralConvexShape* m_convexA;
|
||||
const btPolyhedralConvexShape* m_convexB;
|
||||
BU_Screwing m_screwing;
|
||||
btScalar m_tolerance;
|
||||
|
||||
};
|
||||
#endif //BU_COLLISIONPAIR
|
||||
@@ -1,578 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BU_EdgeEdge.h"
|
||||
#include "BU_Screwing.h"
|
||||
#include <LinearMath/btPoint3.h>
|
||||
#include <LinearMath/btPoint3.h>
|
||||
|
||||
//#include "BU_IntervalArithmeticPolynomialSolver.h"
|
||||
#include "BU_AlgebraicPolynomialSolver.h"
|
||||
|
||||
#define USE_ALGEBRAIC
|
||||
#ifdef USE_ALGEBRAIC
|
||||
#define BU_Polynomial BU_AlgebraicPolynomialSolver
|
||||
#else
|
||||
#define BU_Polynomial BU_IntervalArithmeticPolynomialSolver
|
||||
#endif
|
||||
|
||||
BU_EdgeEdge::BU_EdgeEdge()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool BU_EdgeEdge::GetTimeOfImpact(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,//edge in object A
|
||||
const btVector3& u,
|
||||
const btPoint3& c,//edge in object B
|
||||
const btVector3& v,
|
||||
btScalar &minTime,
|
||||
btScalar &lambda1,
|
||||
btScalar& mu1
|
||||
|
||||
)
|
||||
{
|
||||
bool hit=false;
|
||||
|
||||
btScalar lambda;
|
||||
btScalar mu;
|
||||
|
||||
const btScalar w=screwAB.GetW();
|
||||
const btScalar s=screwAB.GetS();
|
||||
|
||||
if (btFuzzyZero(s) &&
|
||||
btFuzzyZero(w))
|
||||
{
|
||||
//no motion, no collision
|
||||
return false;
|
||||
}
|
||||
|
||||
if (btFuzzyZero(w) )
|
||||
{
|
||||
//pure translation W=0, S <> 0
|
||||
//no trig, f(t)=t
|
||||
btScalar det = u.y()*v.x()-u.x()*v.y();
|
||||
if (!btFuzzyZero(det))
|
||||
{
|
||||
lambda = (a.x()*v.y() - c.x() * v.y() - v.x() * a.y() + v.x() * c.y()) / det;
|
||||
mu = (u.y() * a.x() - u.y() * c.x() - u.x() * a.y() + u.x() * c.y()) / det;
|
||||
|
||||
if (mu >=0 && mu <= 1 && lambda >= 0 && lambda <= 1)
|
||||
{
|
||||
// single potential collision is
|
||||
btScalar t = (c.z()-a.z()+mu*v.z()-lambda*u.z())/s;
|
||||
//if this is on the edge, and time t within [0..1] report hit
|
||||
if (t>=0 && t <= minTime)
|
||||
{
|
||||
hit = true;
|
||||
lambda1 = lambda;
|
||||
mu1 = mu;
|
||||
minTime=t;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
//parallel case, not yet
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (btFuzzyZero(s) )
|
||||
{
|
||||
if (btFuzzyZero(u.z()) )
|
||||
{
|
||||
if (btFuzzyZero(v.z()) )
|
||||
{
|
||||
//u.z()=0,v.z()=0
|
||||
if (btFuzzyZero(a.z()-c.z()))
|
||||
{
|
||||
//printf("NOT YET planar problem, 4 vertex=edge cases\n");
|
||||
|
||||
} else
|
||||
{
|
||||
//printf("parallel but distinct planes, no collision\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
btScalar mu = (a.z() - c.z())/v.z();
|
||||
if (0<=mu && mu <= 1)
|
||||
{
|
||||
// printf("NOT YET//u.z()=0,v.z()<>0\n");
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
} else
|
||||
{
|
||||
//u.z()<>0
|
||||
|
||||
if (btFuzzyZero(v.z()) )
|
||||
{
|
||||
//printf("u.z()<>0,v.z()=0\n");
|
||||
lambda = (c.z() - a.z())/u.z();
|
||||
if (0<=lambda && lambda <= 1)
|
||||
{
|
||||
//printf("u.z()<>0,v.z()=0\n");
|
||||
btPoint3 rotPt(a.x()+lambda * u.x(), a.y()+lambda * u.y(),0.f);
|
||||
btScalar r2 = rotPt.length2();//px*px + py*py;
|
||||
|
||||
//either y=a*x+b, or x = a*x+b...
|
||||
//depends on whether value v.x() is zero or not
|
||||
btScalar aa;
|
||||
btScalar bb;
|
||||
|
||||
if (btFuzzyZero(v.x()))
|
||||
{
|
||||
aa = v.x()/v.y();
|
||||
bb= c.x()+ (-c.y() /v.y()) *v.x();
|
||||
} else
|
||||
{
|
||||
//line is c+mu*v;
|
||||
//x = c.x()+mu*v.x();
|
||||
//mu = ((x-c.x())/v.x());
|
||||
//y = c.y()+((x-c.x())/v.x())*v.y();
|
||||
//y = c.y()+ (-c.x() /v.x()) *v.y() + (x /v.x()) *v.y();
|
||||
//y = a*x+b,where a = v.y()/v.x(), b= c.y()+ (-c.x() /v.x()) *v.y();
|
||||
aa = v.y()/v.x();
|
||||
bb= c.y()+ (-c.x() /v.x()) *v.y();
|
||||
}
|
||||
|
||||
btScalar disc = aa*aa*r2 + r2 - bb*bb;
|
||||
if (disc <0)
|
||||
{
|
||||
//edge doesn't intersect the circle (motion of the vertex)
|
||||
return false;
|
||||
}
|
||||
btScalar rad = btSqrt(r2);
|
||||
|
||||
if (btFuzzyZero(disc))
|
||||
{
|
||||
btPoint3 intersectPt;
|
||||
|
||||
btScalar mu;
|
||||
//intersectionPoint edge with circle;
|
||||
if (btFuzzyZero(v.x()))
|
||||
{
|
||||
intersectPt.setY( (-2*aa*bb)/(2*(aa*aa+1)));
|
||||
intersectPt.setX( aa*intersectPt.y()+bb );
|
||||
mu = ((intersectPt.y()-c.y())/v.y());
|
||||
} else
|
||||
{
|
||||
intersectPt.setX((-2*aa*bb)/(2*(aa*aa+1)));
|
||||
intersectPt.setY(aa*intersectPt.x()+bb);
|
||||
mu = ((intersectPt.getX()-c.getX())/v.getX());
|
||||
|
||||
}
|
||||
|
||||
if (0 <= mu && mu <= 1)
|
||||
{
|
||||
hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
|
||||
}
|
||||
//only one solution
|
||||
} else
|
||||
{
|
||||
//two points...
|
||||
//intersectionPoint edge with circle;
|
||||
btPoint3 intersectPt;
|
||||
//intersectionPoint edge with circle;
|
||||
if (btFuzzyZero(v.x()))
|
||||
{
|
||||
btScalar mu;
|
||||
|
||||
intersectPt.setY((-2.f*aa*bb+2.f*btSqrt(disc))/(2.f*(aa*aa+1.f)));
|
||||
intersectPt.setX(aa*intersectPt.y()+bb);
|
||||
mu = ((intersectPt.getY()-c.getY())/v.getY());
|
||||
if (0.f <= mu && mu <= 1.f)
|
||||
{
|
||||
hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
|
||||
}
|
||||
intersectPt.setY((-2.f*aa*bb-2.f*btSqrt(disc))/(2.f*(aa*aa+1.f)));
|
||||
intersectPt.setX(aa*intersectPt.y()+bb);
|
||||
mu = ((intersectPt.getY()-c.getY())/v.getY());
|
||||
if (0 <= mu && mu <= 1)
|
||||
{
|
||||
hit = hit || Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
btScalar mu;
|
||||
|
||||
intersectPt.setX((-2.f*aa*bb+2.f*btSqrt(disc))/(2*(aa*aa+1.f)));
|
||||
intersectPt.setY(aa*intersectPt.x()+bb);
|
||||
mu = ((intersectPt.getX()-c.getX())/v.getX());
|
||||
if (0 <= mu && mu <= 1)
|
||||
{
|
||||
hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
|
||||
}
|
||||
intersectPt.setX((-2.f*aa*bb-2.f*btSqrt(disc))/(2.f*(aa*aa+1.f)));
|
||||
intersectPt.setY(aa*intersectPt.x()+bb);
|
||||
mu = ((intersectPt.getX()-c.getX())/v.getX());
|
||||
if (0.f <= mu && mu <= 1.f)
|
||||
{
|
||||
hit = hit || Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int k=0;
|
||||
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} else
|
||||
{
|
||||
//u.z()<>0,v.z()<>0
|
||||
//printf("general case with s=0\n");
|
||||
hit = GetTimeOfImpactbteralCase(screwAB,a,u,c,v,minTime,lambda,mu);
|
||||
if (hit)
|
||||
{
|
||||
lambda1 = lambda;
|
||||
mu1 = mu;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
//printf("general case, W<>0,S<>0\n");
|
||||
hit = GetTimeOfImpactbteralCase(screwAB,a,u,c,v,minTime,lambda,mu);
|
||||
if (hit)
|
||||
{
|
||||
lambda1 = lambda;
|
||||
mu1 = mu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//W <> 0,pure rotation
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
|
||||
bool BU_EdgeEdge::GetTimeOfImpactbteralCase(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,//edge in object A
|
||||
const btVector3& u,
|
||||
const btPoint3& c,//edge in object B
|
||||
const btVector3& v,
|
||||
btScalar &minTime,
|
||||
btScalar &lambda,
|
||||
btScalar& mu
|
||||
|
||||
)
|
||||
{
|
||||
bool hit = false;
|
||||
|
||||
btScalar coefs[4]={0.f,0.f,0.f,0.f};
|
||||
BU_Polynomial polynomialSolver;
|
||||
int numroots = 0;
|
||||
|
||||
//btScalar eps=1e-15f;
|
||||
//btScalar eps2=1e-20f;
|
||||
btScalar s=screwAB.GetS();
|
||||
btScalar w = screwAB.GetW();
|
||||
|
||||
btScalar ax = a.x();
|
||||
btScalar ay = a.y();
|
||||
btScalar az = a.z();
|
||||
btScalar cx = c.x();
|
||||
btScalar cy = c.y();
|
||||
btScalar cz = c.z();
|
||||
btScalar vx = v.x();
|
||||
btScalar vy = v.y();
|
||||
btScalar vz = v.z();
|
||||
btScalar ux = u.x();
|
||||
btScalar uy = u.y();
|
||||
btScalar uz = u.z();
|
||||
|
||||
|
||||
if (!btFuzzyZero(v.z()))
|
||||
{
|
||||
|
||||
//Maple Autogenerated C code
|
||||
btScalar t1,t2,t3,t4,t7,t8,t10;
|
||||
btScalar t13,t14,t15,t16,t17,t18,t19,t20;
|
||||
btScalar t21,t22,t23,t24,t25,t26,t27,t28,t29,t30;
|
||||
btScalar t31,t32,t33,t34,t35,t36,t39,t40;
|
||||
btScalar t41,t43,t48;
|
||||
btScalar t63;
|
||||
|
||||
btScalar aa,bb,cc,dd;//the coefficients
|
||||
|
||||
t1 = v.y()*s; t2 = t1*u.x();
|
||||
t3 = v.x()*s;
|
||||
t4 = t3*u.y();
|
||||
t7 = btTan(w/2.0f);
|
||||
t8 = 1.0f/t7;
|
||||
t10 = 1.0f/v.z();
|
||||
aa = (t2-t4)*t8*t10;
|
||||
t13 = a.x()*t7;
|
||||
t14 = u.z()*v.y();
|
||||
t15 = t13*t14;
|
||||
t16 = u.x()*v.z();
|
||||
t17 = a.y()*t7;
|
||||
t18 = t16*t17;
|
||||
t19 = u.y()*v.z();
|
||||
t20 = t13*t19;
|
||||
t21 = v.y()*u.x();
|
||||
t22 = c.z()*t7;
|
||||
t23 = t21*t22;
|
||||
t24 = v.x()*a.z();
|
||||
t25 = t7*u.y();
|
||||
t26 = t24*t25;
|
||||
t27 = c.y()*t7;
|
||||
t28 = t16*t27;
|
||||
t29 = a.z()*t7;
|
||||
t30 = t21*t29;
|
||||
t31 = u.z()*v.x();
|
||||
t32 = t31*t27;
|
||||
t33 = t31*t17;
|
||||
t34 = c.x()*t7;
|
||||
t35 = t34*t19;
|
||||
t36 = t34*t14;
|
||||
t39 = v.x()*c.z();
|
||||
t40 = t39*t25;
|
||||
t41 = 2.0f*t1*u.y()-t15+t18-t20-t23-t26+t28+t30+t32+t33-t35-t36+2.0f*t3*u.x()+t40;
|
||||
bb = t41*t8*t10;
|
||||
t43 = t7*u.x();
|
||||
t48 = u.y()*v.y();
|
||||
cc = (-2.0f*t39*t43+2.0f*t24*t43+t4-2.0f*t48*t22+2.0f*t34*t16-2.0f*t31*t13-t2
|
||||
-2.0f*t17*t14+2.0f*t19*t27+2.0f*t48*t29)*t8*t10;
|
||||
t63 = -t36+t26+t32-t40+t23+t35-t20+t18-t28-t33+t15-t30;
|
||||
dd = t63*t8*t10;
|
||||
|
||||
coefs[0]=aa;
|
||||
coefs[1]=bb;
|
||||
coefs[2]=cc;
|
||||
coefs[3]=dd;
|
||||
|
||||
} else
|
||||
{
|
||||
|
||||
btScalar t1,t2,t3,t4,t7,t8,t10;
|
||||
btScalar t13,t14,t15,t16,t17,t18,t19,t20;
|
||||
btScalar t21,t22,t23,t24,t25,t26,t27,t28,t29,t30;
|
||||
btScalar t31,t32,t33,t34,t35,t36,t37,t38,t57;
|
||||
btScalar p1,p2,p3,p4;
|
||||
|
||||
t1 = uy*s;
|
||||
t2 = t1*vx;
|
||||
t3 = ux*s;
|
||||
t4 = t3*vy;
|
||||
t7 = btTan(w/2.0f);
|
||||
t8 = 1/t7;
|
||||
t10 = 1/uz;
|
||||
t13 = ux*az;
|
||||
t14 = t7*vy;
|
||||
t15 = t13*t14;
|
||||
t16 = ax*t7;
|
||||
t17 = uy*vz;
|
||||
t18 = t16*t17;
|
||||
t19 = cx*t7;
|
||||
t20 = t19*t17;
|
||||
t21 = vy*uz;
|
||||
t22 = t19*t21;
|
||||
t23 = ay*t7;
|
||||
t24 = vx*uz;
|
||||
t25 = t23*t24;
|
||||
t26 = uy*cz;
|
||||
t27 = t7*vx;
|
||||
t28 = t26*t27;
|
||||
t29 = t16*t21;
|
||||
t30 = cy*t7;
|
||||
t31 = ux*vz;
|
||||
t32 = t30*t31;
|
||||
t33 = ux*cz;
|
||||
t34 = t33*t14;
|
||||
t35 = t23*t31;
|
||||
t36 = t30*t24;
|
||||
t37 = uy*az;
|
||||
t38 = t37*t27;
|
||||
|
||||
p4 = (-t2+t4)*t8*t10;
|
||||
p3 = 2.0f*t1*vy+t15-t18-t20-t22+t25+t28-t29+t32-t34+t35+t36-t38+2.0f*t3*vx;
|
||||
p2 = -2.0f*t33*t27-2.0f*t26*t14-2.0f*t23*t21+2.0f*t37*t14+2.0f*t30*t17+2.0f*t13
|
||||
*t27+t2-t4+2.0f*t19*t31-2.0f*t16*t24;
|
||||
t57 = -t22+t29+t36-t25-t32+t34+t35-t28-t15+t20-t18+t38;
|
||||
p1 = t57*t8*t10;
|
||||
|
||||
coefs[0] = p4;
|
||||
coefs[1] = p3;
|
||||
coefs[2] = p2;
|
||||
coefs[1] = p1;
|
||||
|
||||
}
|
||||
|
||||
numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
|
||||
|
||||
for (int i=0;i<numroots;i++)
|
||||
{
|
||||
//btScalar tau = roots[i];//polynomialSolver.GetRoot(i);
|
||||
btScalar tau = polynomialSolver.GetRoot(i);
|
||||
|
||||
//check whether mu and lambda are in range [0..1]
|
||||
|
||||
if (!btFuzzyZero(v.z()))
|
||||
{
|
||||
btScalar A1=(ux-ux*tau*tau-2.f*tau*uy)-((1.f+tau*tau)*vx*uz/vz);
|
||||
btScalar B1=((1.f+tau*tau)*(cx*btTan(1.f/2.f*w)*vz+
|
||||
vx*az*btTan(1.f/2.f*w)-vx*cz*btTan(1.f/2.f*w)+
|
||||
vx*s*tau)/btTan(1.f/2.f*w)/vz)-(ax-ax*tau*tau-2.f*tau*ay);
|
||||
lambda = B1/A1;
|
||||
|
||||
mu = (a.z()-c.z()+lambda*u.z()+(s*tau)/(btTan(w/2.f)))/v.z();
|
||||
|
||||
|
||||
//double check in original equation
|
||||
|
||||
btScalar lhs = (a.x()+lambda*u.x())
|
||||
*((1.f-tau*tau)/(1.f+tau*tau))-
|
||||
(a.y()+lambda*u.y())*((2.f*tau)/(1.f+tau*tau));
|
||||
|
||||
lhs = lambda*((ux-ux*tau*tau-2.f*tau*uy)-((1.f+tau*tau)*vx*uz/vz));
|
||||
|
||||
btScalar rhs = c.x()+mu*v.x();
|
||||
|
||||
rhs = ((1.f+tau*tau)*(cx*btTan(1.f/2.f*w)*vz+vx*az*btTan(1.f/2.f*w)-
|
||||
vx*cz*btTan(1.f/2.f*w)+vx*s*tau)/(btTan(1.f/2.f*w)*vz))-
|
||||
|
||||
(ax-ax*tau*tau-2.f*tau*ay);
|
||||
|
||||
/*btScalar res = coefs[0]*tau*tau*tau+
|
||||
coefs[1]*tau*tau+
|
||||
coefs[2]*tau+
|
||||
coefs[3];*/
|
||||
|
||||
//lhs should be rhs !
|
||||
|
||||
if (0.<= mu && mu <=1 && 0.<=lambda && lambda <= 1)
|
||||
{
|
||||
|
||||
} else
|
||||
{
|
||||
//skip this solution, not really touching
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
btScalar t = 2.f*btAtan(tau)/screwAB.GetW();
|
||||
//tau = tan (wt/2) so 2*atan (tau)/w
|
||||
if (t>=0.f && t<minTime)
|
||||
{
|
||||
#ifdef STATS_EDGE_EDGE
|
||||
printf(" ax = %12.12f\n ay = %12.12f\n az = %12.12f\n",a.x(),a.y(),a.z());
|
||||
printf(" ux = %12.12f\n uy = %12.12f\n uz = %12.12f\n",u.x(),u.y(),u.z());
|
||||
printf(" cx = %12.12f\n cy = %12.12f\n cz = %12.12f\n",c.x(),c.y(),c.z());
|
||||
printf(" vx = %12.12f\n vy = %12.12f\n vz = %12.12f\n",v.x(),v.y(),v.z());
|
||||
printf(" s = %12.12f\n w = %12.12f\n", s, w);
|
||||
|
||||
printf(" tau = %12.12f \n lambda = %12.12f \n mu = %f\n",tau,lambda,mu);
|
||||
printf(" ---------------------------------------------\n");
|
||||
|
||||
#endif
|
||||
|
||||
// v,u,a,c,s,w
|
||||
|
||||
// BU_IntervalArithmeticPolynomialSolver iaSolver;
|
||||
// int numroots2 = iaSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
|
||||
|
||||
minTime = t;
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
|
||||
//C -S
|
||||
//S C
|
||||
|
||||
bool BU_EdgeEdge::Calc2DRotationPointPoint(const btPoint3& rotPt, btScalar rotRadius, btScalar rotW,const btPoint3& intersectPt,btScalar& minTime)
|
||||
{
|
||||
bool hit = false;
|
||||
|
||||
// now calculate the planeEquation for the vertex motion,
|
||||
// and check if the intersectionpoint is at the positive side
|
||||
btPoint3 rotPt1(btCos(rotW)*rotPt.x()-btSin(rotW)*rotPt.y(),
|
||||
btSin(rotW)*rotPt.x()+btCos(rotW)*rotPt.y(),
|
||||
0.f);
|
||||
|
||||
btVector3 rotVec = rotPt1-rotPt;
|
||||
|
||||
btVector3 planeNormal( -rotVec.y() , rotVec.x() ,0.f);
|
||||
|
||||
//btPoint3 pt(a.x(),a.y());//for sake of readability,could write dot directly
|
||||
btScalar planeD = planeNormal.dot(rotPt1);
|
||||
|
||||
btScalar dist = (planeNormal.dot(intersectPt)-planeD);
|
||||
hit = (dist >= -0.001);
|
||||
|
||||
//if (hit)
|
||||
{
|
||||
// minTime = 0;
|
||||
//calculate the time of impact, using the fact of
|
||||
//toi = alpha / screwAB.getW();
|
||||
// cos (alpha) = adjacent/hypothenuse;
|
||||
//adjacent = dotproduct(ipedge,point);
|
||||
//hypothenuse = sqrt(r2);
|
||||
btScalar adjacent = intersectPt.dot(rotPt)/rotRadius;
|
||||
btScalar hypo = rotRadius;
|
||||
btScalar alpha = btAcos(adjacent/hypo);
|
||||
btScalar t = alpha / rotW;
|
||||
if (t >= 0 && t < minTime)
|
||||
{
|
||||
hit = true;
|
||||
minTime = t;
|
||||
} else
|
||||
{
|
||||
hit = false;
|
||||
}
|
||||
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool BU_EdgeEdge::GetTimeOfImpactVertexEdge(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,//edge in object A
|
||||
const btVector3& u,
|
||||
const btPoint3& c,//edge in object B
|
||||
const btVector3& v,
|
||||
btScalar &minTime,
|
||||
btScalar &lamda,
|
||||
btScalar& mu
|
||||
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BU_EDGEEDGE
|
||||
#define BU_EDGEEDGE
|
||||
|
||||
class BU_Screwing;
|
||||
#include <LinearMath/btTransform.h>
|
||||
#include <LinearMath/btPoint3.h>
|
||||
#include <LinearMath/btVector3.h>
|
||||
|
||||
//class BUM_Point2;
|
||||
|
||||
#include <LinearMath/btScalar.h>
|
||||
|
||||
///BU_EdgeEdge implements algebraic time of impact calculation between two (angular + linear) moving edges.
|
||||
class BU_EdgeEdge
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
BU_EdgeEdge();
|
||||
bool GetTimeOfImpact(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,//edge in object A
|
||||
const btVector3& u,
|
||||
const btPoint3& c,//edge in object B
|
||||
const btVector3& v,
|
||||
btScalar &minTime,
|
||||
btScalar &lamda,
|
||||
btScalar& mu
|
||||
);
|
||||
private:
|
||||
|
||||
bool Calc2DRotationPointPoint(const btPoint3& rotPt, btScalar rotRadius, btScalar rotW,const btPoint3& intersectPt,btScalar& minTime);
|
||||
bool GetTimeOfImpactbteralCase(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,//edge in object A
|
||||
const btVector3& u,
|
||||
const btPoint3& c,//edge in object B
|
||||
const btVector3& v,
|
||||
btScalar &minTime,
|
||||
btScalar &lamda,
|
||||
btScalar& mu
|
||||
|
||||
);
|
||||
|
||||
|
||||
bool GetTimeOfImpactVertexEdge(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,//edge in object A
|
||||
const btVector3& u,
|
||||
const btPoint3& c,//edge in object B
|
||||
const btVector3& v,
|
||||
btScalar &minTime,
|
||||
btScalar &lamda,
|
||||
btScalar& mu
|
||||
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
#endif //BU_EDGEEDGE
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BU_MOTIONSTATE
|
||||
#define BU_MOTIONSTATE
|
||||
|
||||
|
||||
#include <LinearMath/btTransform.h>
|
||||
#include <LinearMath/btPoint3.h>
|
||||
#include <btQuaternion.h>
|
||||
|
||||
class BU_MotionStateInterface
|
||||
{
|
||||
public:
|
||||
virtual ~BU_MotionStateInterface(){};
|
||||
|
||||
virtual void SetTransform(const btTransform& trans) = 0;
|
||||
virtual void GetTransform(btTransform& trans) const = 0;
|
||||
|
||||
virtual void SetPosition(const btPoint3& position) = 0;
|
||||
virtual void GetPosition(btPoint3& position) const = 0;
|
||||
|
||||
virtual void SetOrientation(const btQuaternion& orientation) = 0;
|
||||
virtual void GetOrientation(btQuaternion& orientation) const = 0;
|
||||
|
||||
virtual void SetBasis(const btMatrix3x3& basis) = 0;
|
||||
virtual void GetBasis(btMatrix3x3& basis) const = 0;
|
||||
|
||||
virtual void SetLinearVelocity(const btVector3& linvel) = 0;
|
||||
virtual void GetLinearVelocity(btVector3& linvel) const = 0;
|
||||
|
||||
virtual void GetAngularVelocity(btVector3& angvel) const = 0;
|
||||
virtual void SetAngularVelocity(const btVector3& angvel) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif //BU_MOTIONSTATE
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef BUM_POLYNOMIAL_SOLVER_INTERFACE
|
||||
#define BUM_POLYNOMIAL_SOLVER_INTERFACE
|
||||
|
||||
#include <LinearMath/btScalar.h>
|
||||
//
|
||||
//BUM_PolynomialSolverInterface is interface class for polynomial root finding.
|
||||
//The number of roots is returned as a result, query GetRoot to get the actual solution.
|
||||
//
|
||||
class BUM_PolynomialSolverInterface
|
||||
{
|
||||
public:
|
||||
virtual ~BUM_PolynomialSolverInterface() {};
|
||||
|
||||
|
||||
// virtual int Solve2QuadraticFull(btScalar a,btScalar b, btScalar c) = 0;
|
||||
|
||||
virtual int Solve3Cubic(btScalar lead, btScalar a, btScalar b, btScalar c) = 0;
|
||||
|
||||
virtual int Solve4Quartic(btScalar lead, btScalar a, btScalar b, btScalar c, btScalar d) = 0;
|
||||
|
||||
virtual btScalar GetRoot(int i) const = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif //BUM_POLYNOMIAL_SOLVER_INTERFACE
|
||||
@@ -1,200 +0,0 @@
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Stephane Redon / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BU_Screwing.h"
|
||||
|
||||
|
||||
BU_Screwing::BU_Screwing(const btVector3& relLinVel,const btVector3& relAngVel) {
|
||||
|
||||
|
||||
const btScalar dx=relLinVel[0];
|
||||
const btScalar dy=relLinVel[1];
|
||||
const btScalar dz=relLinVel[2];
|
||||
const btScalar wx=relAngVel[0];
|
||||
const btScalar wy=relAngVel[1];
|
||||
const btScalar wz=relAngVel[2];
|
||||
|
||||
// Compute the screwing parameters :
|
||||
// w : total amount of rotation
|
||||
// s : total amount of translation
|
||||
// u : vector along the screwing axis (||u||=1)
|
||||
// o : point on the screwing axis
|
||||
|
||||
m_w=btSqrt(wx*wx+wy*wy+wz*wz);
|
||||
//if (!w) {
|
||||
if (fabs(m_w)<SCREWEPSILON ) {
|
||||
|
||||
assert(m_w == 0.f);
|
||||
|
||||
m_w=0.;
|
||||
m_s=btSqrt(dx*dx+dy*dy+dz*dz);
|
||||
if (fabs(m_s)<SCREWEPSILON ) {
|
||||
assert(m_s == 0.);
|
||||
|
||||
m_s=0.;
|
||||
m_u=btPoint3(0.,0.,1.);
|
||||
m_o=btPoint3(0.,0.,0.);
|
||||
}
|
||||
else {
|
||||
float t=1.f/m_s;
|
||||
m_u=btPoint3(dx*t,dy*t,dz*t);
|
||||
m_o=btPoint3(0.f,0.f,0.f);
|
||||
}
|
||||
}
|
||||
else { // there is some rotation
|
||||
|
||||
// we compute u
|
||||
|
||||
float v(1.f/m_w);
|
||||
m_u=btPoint3(wx*v,wy*v,wz*v); // normalization
|
||||
|
||||
// decomposition of the translation along u and one orthogonal vector
|
||||
|
||||
btPoint3 t(dx,dy,dz);
|
||||
m_s=t.dot(m_u); // component along u
|
||||
if (fabs(m_s)<SCREWEPSILON)
|
||||
{
|
||||
//printf("m_s component along u < SCREWEPSILION\n");
|
||||
m_s=0.f;
|
||||
}
|
||||
btPoint3 n1(t-(m_s*m_u)); // the remaining part (which is orthogonal to u)
|
||||
|
||||
// now we have to compute o
|
||||
|
||||
//btScalar len = n1.length2();
|
||||
//(len >= BUM_EPSILON2) {
|
||||
if (n1[0] || n1[1] || n1[2]) { // n1 is not the zero vector
|
||||
n1.normalize();
|
||||
btVector3 n1orth=m_u.cross(n1);
|
||||
|
||||
float n2x=btCos(0.5f*m_w);
|
||||
float n2y=btSin(0.5f*m_w);
|
||||
|
||||
m_o=0.5f*t.dot(n1)*(n1+n2x/n2y*n1orth);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_o=btPoint3(0.f,0.f,0.f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Then, I need to compute Pa, the matrix from the reference (global) frame to
|
||||
//the screwing frame :
|
||||
|
||||
|
||||
void BU_Screwing::LocalMatrix(btTransform &t) const {
|
||||
//So the whole computations do this : align the Oz axis along the
|
||||
// screwing axis (thanks to u), and then find two others orthogonal axes to
|
||||
// complete the basis.
|
||||
|
||||
if ((m_u[0]>SCREWEPSILON)||(m_u[0]<-SCREWEPSILON)||(m_u[1]>SCREWEPSILON)||(m_u[1]<-SCREWEPSILON))
|
||||
{
|
||||
// to avoid numerical problems
|
||||
float n=btSqrt(m_u[0]*m_u[0]+m_u[1]*m_u[1]);
|
||||
float invn=1.0f/n;
|
||||
btMatrix3x3 mat;
|
||||
|
||||
mat[0][0]=-m_u[1]*invn;
|
||||
mat[0][1]=m_u[0]*invn;
|
||||
mat[0][2]=0.f;
|
||||
|
||||
mat[1][0]=-m_u[0]*invn*m_u[2];
|
||||
mat[1][1]=-m_u[1]*invn*m_u[2];
|
||||
mat[1][2]=n;
|
||||
|
||||
mat[2][0]=m_u[0];
|
||||
mat[2][1]=m_u[1];
|
||||
mat[2][2]=m_u[2];
|
||||
|
||||
t.setOrigin(btPoint3(
|
||||
m_o[0]*m_u[1]*invn-m_o[1]*m_u[0]*invn,
|
||||
-(m_o[0]*mat[1][0]+m_o[1]*mat[1][1]+m_o[2]*n),
|
||||
-(m_o[0]*m_u[0]+m_o[1]*m_u[1]+m_o[2]*m_u[2])));
|
||||
|
||||
t.setBasis(mat);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
btMatrix3x3 m;
|
||||
|
||||
m[0][0]=1.;
|
||||
m[1][0]=0.;
|
||||
m[2][0]=0.;
|
||||
|
||||
m[0][1]=0.f;
|
||||
m[1][1]=float(btSign(m_u[2]));
|
||||
m[2][1]=0.f;
|
||||
|
||||
m[0][2]=0.f;
|
||||
m[1][2]=0.f;
|
||||
m[2][2]=float(btSign(m_u[2]));
|
||||
|
||||
t.setOrigin(btPoint3(
|
||||
-m_o[0],
|
||||
-btSign(m_u[2])*m_o[1],
|
||||
-btSign(m_u[2])*m_o[2]
|
||||
));
|
||||
t.setBasis(m);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//gives interpolated transform for time in [0..1] in screwing frame
|
||||
btTransform BU_Screwing::InBetweenTransform(const btTransform& tr,btScalar t) const
|
||||
{
|
||||
btPoint3 org = tr.getOrigin();
|
||||
|
||||
btPoint3 neworg (
|
||||
org.x()*btCos(m_w*t)-org.y()*btSin(m_w*t),
|
||||
org.x()*btSin(m_w*t)+org.y()*btCos(m_w*t),
|
||||
org.z()+m_s*CalculateF(t));
|
||||
|
||||
btTransform newtr;
|
||||
newtr.setOrigin(neworg);
|
||||
btMatrix3x3 basis = tr.getBasis();
|
||||
btMatrix3x3 basisorg = tr.getBasis();
|
||||
|
||||
btQuaternion rot(btVector3(0.,0.,1.),m_w*t);
|
||||
btQuaternion tmpOrn;
|
||||
tr.getBasis().getRotation(tmpOrn);
|
||||
rot = rot * tmpOrn;
|
||||
|
||||
//to avoid numerical drift, normalize quaternion
|
||||
rot.normalize();
|
||||
newtr.setBasis(btMatrix3x3(rot));
|
||||
return newtr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
btScalar BU_Screwing::CalculateF(btScalar t) const
|
||||
{
|
||||
btScalar result;
|
||||
if (!m_w)
|
||||
{
|
||||
result = t;
|
||||
} else
|
||||
{
|
||||
result = ( btTan((m_w*t)/2.f) / btTan(m_w/2.f));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B_SCREWING_H
|
||||
#define B_SCREWING_H
|
||||
|
||||
|
||||
#include <LinearMath/btVector3.h>
|
||||
#include <LinearMath/btPoint3.h>
|
||||
#include <LinearMath/btTransform.h>
|
||||
|
||||
|
||||
#define SCREWEPSILON 0.00001f
|
||||
|
||||
///BU_Screwing implements screwing motion interpolation.
|
||||
class BU_Screwing
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
BU_Screwing(const btVector3& relLinVel,const btVector3& relAngVel);
|
||||
|
||||
~BU_Screwing() {
|
||||
};
|
||||
|
||||
btScalar CalculateF(btScalar t) const;
|
||||
//gives interpolated position for time in [0..1] in screwing frame
|
||||
|
||||
inline btPoint3 InBetweenPosition(const btPoint3& pt,btScalar t) const
|
||||
{
|
||||
return btPoint3(
|
||||
pt.x()*btCos(m_w*t)-pt.y()*btSin(m_w*t),
|
||||
pt.x()*btSin(m_w*t)+pt.y()*btCos(m_w*t),
|
||||
pt.z()+m_s*CalculateF(t));
|
||||
}
|
||||
|
||||
inline btVector3 InBetweenVector(const btVector3& vec,btScalar t) const
|
||||
{
|
||||
return btVector3(
|
||||
vec.x()*btCos(m_w*t)-vec.y()*btSin(m_w*t),
|
||||
vec.x()*btSin(m_w*t)+vec.y()*btCos(m_w*t),
|
||||
vec.z());
|
||||
}
|
||||
|
||||
//gives interpolated transform for time in [0..1] in screwing frame
|
||||
btTransform InBetweenTransform(const btTransform& tr,btScalar t) const;
|
||||
|
||||
|
||||
//gives matrix from global frame into screwing frame
|
||||
void LocalMatrix(btTransform &t) const;
|
||||
|
||||
inline const btVector3& GetU() const { return m_u;}
|
||||
inline const btVector3& GetO() const {return m_o;}
|
||||
inline const btScalar GetS() const{ return m_s;}
|
||||
inline const btScalar GetW() const { return m_w;}
|
||||
|
||||
private:
|
||||
float m_w;
|
||||
float m_s;
|
||||
btVector3 m_u;
|
||||
btVector3 m_o;
|
||||
};
|
||||
|
||||
#endif //B_SCREWING_H
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BU_STATIC_MOTIONSTATE
|
||||
#define BU_STATIC_MOTIONSTATE
|
||||
|
||||
|
||||
#include <btCollisionShapes/BU_MotionStateInterface.h>
|
||||
|
||||
class BU_StaticMotionState :public BU_MotionStateInterface
|
||||
{
|
||||
public:
|
||||
virtual ~BU_StaticMotionState(){};
|
||||
|
||||
virtual void SetTransform(const btTransform& trans)
|
||||
{
|
||||
m_trans = trans;
|
||||
}
|
||||
virtual void GetTransform(btTransform& trans) const
|
||||
{
|
||||
trans = m_trans;
|
||||
}
|
||||
virtual void SetPosition(const btPoint3& position)
|
||||
{
|
||||
m_trans.setOrigin( position );
|
||||
}
|
||||
virtual void GetPosition(btPoint3& position) const
|
||||
{
|
||||
position = m_trans.getOrigin();
|
||||
}
|
||||
|
||||
virtual void SetOrientation(const btQuaternion& orientation)
|
||||
{
|
||||
m_trans.setRotation( orientation);
|
||||
}
|
||||
virtual void GetOrientation(btQuaternion& orientation) const
|
||||
{
|
||||
orientation = m_trans.getRotation();
|
||||
}
|
||||
|
||||
virtual void SetBasis(const btMatrix3x3& basis)
|
||||
{
|
||||
m_trans.setBasis( basis);
|
||||
}
|
||||
virtual void GetBasis(btMatrix3x3& basis) const
|
||||
{
|
||||
basis = m_trans.getBasis();
|
||||
}
|
||||
|
||||
virtual void SetLinearVelocity(const btVector3& linvel)
|
||||
{
|
||||
m_linearVelocity = linvel;
|
||||
}
|
||||
virtual void GetLinearVelocity(btVector3& linvel) const
|
||||
{
|
||||
linvel = m_linearVelocity;
|
||||
}
|
||||
|
||||
virtual void SetAngularVelocity(const btVector3& angvel)
|
||||
{
|
||||
m_angularVelocity = angvel;
|
||||
}
|
||||
virtual void GetAngularVelocity(btVector3& angvel) const
|
||||
{
|
||||
angvel = m_angularVelocity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
btTransform m_trans;
|
||||
btVector3 m_angularVelocity;
|
||||
btVector3 m_linearVelocity;
|
||||
|
||||
};
|
||||
|
||||
#endif //BU_STATIC_MOTIONSTATE
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "BU_VertexPoly.h"
|
||||
#include "BU_Screwing.h"
|
||||
#include <LinearMath/btTransform.h>
|
||||
#include <LinearMath/btPoint3.h>
|
||||
#include <LinearMath/btVector3.h>
|
||||
|
||||
#define USE_ALGEBRAIC
|
||||
#ifdef USE_ALGEBRAIC
|
||||
#include "BU_AlgebraicPolynomialSolver.h"
|
||||
#define BU_Polynomial BU_AlgebraicPolynomialSolver
|
||||
#else
|
||||
#include "BU_IntervalArithmeticPolynomialSolver.h"
|
||||
#define BU_Polynomial BU_IntervalArithmeticPolynomialSolver
|
||||
#endif
|
||||
|
||||
inline bool TestFuzzyZero(btScalar x) { return btFabs(x) < 0.0001f; }
|
||||
|
||||
|
||||
BU_VertexPoly::BU_VertexPoly()
|
||||
{
|
||||
|
||||
}
|
||||
//return true if a collision will occur between [0..1]
|
||||
//false otherwise. If true, minTime contains the time of impact
|
||||
bool BU_VertexPoly::GetTimeOfImpact(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& a,
|
||||
const btVector4& planeEq,
|
||||
btScalar &minTime,bool swapAB)
|
||||
{
|
||||
|
||||
bool hit = false;
|
||||
|
||||
// precondition: s=0 and w= 0 is catched by caller!
|
||||
if (TestFuzzyZero(screwAB.GetS()) &&
|
||||
TestFuzzyZero(screwAB.GetW()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//case w<>0 and s<> 0
|
||||
const btScalar w=screwAB.GetW();
|
||||
const btScalar s=screwAB.GetS();
|
||||
|
||||
btScalar coefs[4];
|
||||
const btScalar p=planeEq[0];
|
||||
const btScalar q=planeEq[1];
|
||||
const btScalar r=planeEq[2];
|
||||
const btScalar d=planeEq[3];
|
||||
|
||||
const btVector3 norm(p,q,r);
|
||||
BU_Polynomial polynomialSolver;
|
||||
int numroots = 0;
|
||||
|
||||
//btScalar eps=1e-80f;
|
||||
//btScalar eps2=1e-100f;
|
||||
|
||||
if (TestFuzzyZero(screwAB.GetS()) )
|
||||
{
|
||||
//S = 0 , W <> 0
|
||||
|
||||
//ax^3+bx^2+cx+d=0
|
||||
coefs[0]=0.;
|
||||
coefs[1]=(-p*a.x()-q*a.y()+r*a.z()-d);
|
||||
coefs[2]=-2*p*a.y()+2*q*a.x();
|
||||
coefs[3]=p*a.x()+q*a.y()+r*a.z()-d;
|
||||
|
||||
// numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
|
||||
numroots = polynomialSolver.Solve2QuadraticFull(coefs[1],coefs[2],coefs[3]);
|
||||
|
||||
} else
|
||||
{
|
||||
if (TestFuzzyZero(screwAB.GetW()))
|
||||
{
|
||||
// W = 0 , S <> 0
|
||||
//pax+qay+r(az+st)=d
|
||||
|
||||
btScalar dist = (d - a.dot(norm));
|
||||
|
||||
if (TestFuzzyZero(r))
|
||||
{
|
||||
if (TestFuzzyZero(dist))
|
||||
{
|
||||
// no hit
|
||||
} else
|
||||
{
|
||||
// todo a a' might hit sides of polygon T
|
||||
//printf("unhandled case, w=0,s<>0,r<>0, a a' might hit sides of polygon T \n");
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
btScalar etoi = (dist)/(r*screwAB.GetS());
|
||||
if (swapAB)
|
||||
etoi *= -1;
|
||||
|
||||
if (etoi >= 0. && etoi <= minTime)
|
||||
{
|
||||
minTime = etoi;
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
//ax^3+bx^2+cx+d=0
|
||||
|
||||
//degenerate coefficients mess things up :(
|
||||
btScalar ietsje = (r*s)/btTan(w/2.f);
|
||||
if (ietsje*ietsje < 0.01f)
|
||||
ietsje = 0.f;
|
||||
|
||||
coefs[0]=ietsje;//(r*s)/tan(w/2.);
|
||||
coefs[1]=(-p*a.x()-q*a.y()+r*a.z()-d);
|
||||
coefs[2]=-2.f*p*a.y()+2.f*q*a.x()+ietsje;//((r*s)/(tan(w/2.)));
|
||||
coefs[3]=p*a.x()+q*a.y()+r*a.z()-d;
|
||||
|
||||
numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<numroots;i++)
|
||||
{
|
||||
btScalar tau = polynomialSolver.GetRoot(i);
|
||||
|
||||
btScalar t = 2.f*btAtan(tau)/w;
|
||||
//tau = tan (wt/2) so 2*atan (tau)/w
|
||||
if (swapAB)
|
||||
{
|
||||
t *= -1.;
|
||||
}
|
||||
if (t>=0 && t<minTime)
|
||||
{
|
||||
minTime = t;
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VERTEX_POLY_H
|
||||
#define VERTEX_POLY_H
|
||||
|
||||
|
||||
class BU_Screwing;
|
||||
#include <LinearMath/btTransform.h>
|
||||
#include <LinearMath/btPoint3.h>
|
||||
#include <LinearMath/btScalar.h>
|
||||
|
||||
///BU_VertexPoly implements algebraic time of impact calculation between vertex and a plane.
|
||||
class BU_VertexPoly
|
||||
{
|
||||
public:
|
||||
BU_VertexPoly();
|
||||
bool GetTimeOfImpact(
|
||||
const BU_Screwing& screwAB,
|
||||
const btPoint3& vtx,
|
||||
const btVector4& planeEq,
|
||||
btScalar &minTime,
|
||||
bool swapAB);
|
||||
|
||||
private:
|
||||
|
||||
//cached data (frame coherency etc.) here
|
||||
|
||||
};
|
||||
#endif //VERTEX_POLY_H
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,228 +0,0 @@
|
||||
xof 0303txt 0032
|
||||
template Frame {
|
||||
<3d82ab46-62da-11cf-ab39-0020af71e433>
|
||||
[...]
|
||||
}
|
||||
|
||||
template Matrix4x4 {
|
||||
<f6f23f45-7686-11cf-8f52-0040333594a3>
|
||||
array FLOAT matrix[16];
|
||||
}
|
||||
|
||||
template FrameTransformMatrix {
|
||||
<f6f23f41-7686-11cf-8f52-0040333594a3>
|
||||
Matrix4x4 frameMatrix;
|
||||
}
|
||||
|
||||
template Vector {
|
||||
<3d82ab5e-62da-11cf-ab39-0020af71e433>
|
||||
FLOAT x;
|
||||
FLOAT y;
|
||||
FLOAT z;
|
||||
}
|
||||
|
||||
template MeshFace {
|
||||
<3d82ab5f-62da-11cf-ab39-0020af71e433>
|
||||
DWORD nFaceVertexIndices;
|
||||
array DWORD faceVertexIndices[nFaceVertexIndices];
|
||||
}
|
||||
|
||||
template Mesh {
|
||||
<3d82ab44-62da-11cf-ab39-0020af71e433>
|
||||
DWORD nVertices;
|
||||
array Vector vertices[nVertices];
|
||||
DWORD nFaces;
|
||||
array MeshFace faces[nFaces];
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshNormals {
|
||||
<f6f23f43-7686-11cf-8f52-0040333594a3>
|
||||
DWORD nNormals;
|
||||
array Vector normals[nNormals];
|
||||
DWORD nFaceNormals;
|
||||
array MeshFace faceNormals[nFaceNormals];
|
||||
}
|
||||
|
||||
template ColorRGBA {
|
||||
<35ff44e0-6c7c-11cf-8f52-0040333594a3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
FLOAT alpha;
|
||||
}
|
||||
|
||||
template ColorRGB {
|
||||
<d3e16e81-7835-11cf-8f52-0040333594a3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
}
|
||||
|
||||
template Material {
|
||||
<3d82ab4d-62da-11cf-ab39-0020af71e433>
|
||||
ColorRGBA faceColor;
|
||||
FLOAT power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshMaterialList {
|
||||
<f6f23f42-7686-11cf-8f52-0040333594a3>
|
||||
DWORD nMaterials;
|
||||
DWORD nFaceIndexes;
|
||||
array DWORD faceIndexes[nFaceIndexes];
|
||||
[Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]
|
||||
}
|
||||
|
||||
template VertexDuplicationIndices {
|
||||
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
|
||||
DWORD nIndices;
|
||||
DWORD nOriginalVertices;
|
||||
array DWORD indices[nIndices];
|
||||
}
|
||||
|
||||
|
||||
Frame {
|
||||
|
||||
|
||||
FrameTransformMatrix {
|
||||
1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
|
||||
}
|
||||
|
||||
Mesh {
|
||||
24;
|
||||
-0.500000;-0.500000;-0.500000;,
|
||||
-0.500000;-0.500000;0.500000;,
|
||||
-0.500000;0.500000;0.500000;,
|
||||
-0.500000;0.500000;-0.500000;,
|
||||
-0.500000;0.500000;-0.500000;,
|
||||
-0.500000;0.500000;0.500000;,
|
||||
0.500000;0.500000;0.500000;,
|
||||
0.500000;0.500000;-0.500000;,
|
||||
0.500000;0.500000;-0.500000;,
|
||||
0.500000;0.500000;0.500000;,
|
||||
0.500000;-0.500000;0.500000;,
|
||||
0.500000;-0.500000;-0.500000;,
|
||||
-0.500000;-0.500000;0.500000;,
|
||||
-0.500000;-0.500000;-0.500000;,
|
||||
0.500000;-0.500000;-0.500000;,
|
||||
0.500000;-0.500000;0.500000;,
|
||||
-0.500000;-0.500000;0.500000;,
|
||||
0.500000;-0.500000;0.500000;,
|
||||
0.500000;0.500000;0.500000;,
|
||||
-0.500000;0.500000;0.500000;,
|
||||
-0.500000;-0.500000;-0.500000;,
|
||||
-0.500000;0.500000;-0.500000;,
|
||||
0.500000;0.500000;-0.500000;,
|
||||
0.500000;-0.500000;-0.500000;;
|
||||
12;
|
||||
3;0,1,2;,
|
||||
3;2,3,0;,
|
||||
3;4,5,6;,
|
||||
3;6,7,4;,
|
||||
3;8,9,10;,
|
||||
3;10,11,8;,
|
||||
3;12,13,14;,
|
||||
3;14,15,12;,
|
||||
3;16,17,18;,
|
||||
3;18,19,16;,
|
||||
3;20,21,22;,
|
||||
3;22,23,20;;
|
||||
|
||||
MeshNormals {
|
||||
24;
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
1.000000;0.000000;0.000000;,
|
||||
1.000000;0.000000;0.000000;,
|
||||
1.000000;0.000000;0.000000;,
|
||||
1.000000;0.000000;0.000000;,
|
||||
0.000000;-1.000000;0.000000;,
|
||||
0.000000;-1.000000;0.000000;,
|
||||
0.000000;-1.000000;0.000000;,
|
||||
0.000000;-1.000000;0.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;;
|
||||
12;
|
||||
3;0,1,2;,
|
||||
3;2,3,0;,
|
||||
3;4,5,6;,
|
||||
3;6,7,4;,
|
||||
3;8,9,10;,
|
||||
3;10,11,8;,
|
||||
3;12,13,14;,
|
||||
3;14,15,12;,
|
||||
3;16,17,18;,
|
||||
3;18,19,16;,
|
||||
3;20,21,22;,
|
||||
3;22,23,20;;
|
||||
}
|
||||
|
||||
MeshMaterialList {
|
||||
1;
|
||||
12;
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0;
|
||||
|
||||
Material {
|
||||
0.500000;0.500000;0.500000;0.000000;;
|
||||
0.000000;
|
||||
0.500000;0.500000;0.500000;;
|
||||
0.000000;0.000000;0.000000;;
|
||||
}
|
||||
}
|
||||
|
||||
VertexDuplicationIndices {
|
||||
24;
|
||||
8;
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
6,
|
||||
7,
|
||||
7,
|
||||
6,
|
||||
10,
|
||||
11,
|
||||
1,
|
||||
0,
|
||||
11,
|
||||
10,
|
||||
1,
|
||||
10,
|
||||
6,
|
||||
2,
|
||||
0,
|
||||
3,
|
||||
7,
|
||||
11;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,786 +0,0 @@
|
||||
xof 0303txt 0032
|
||||
template Frame {
|
||||
<3d82ab46-62da-11cf-ab39-0020af71e433>
|
||||
[...]
|
||||
}
|
||||
|
||||
template Matrix4x4 {
|
||||
<f6f23f45-7686-11cf-8f52-0040333594a3>
|
||||
array FLOAT matrix[16];
|
||||
}
|
||||
|
||||
template FrameTransformMatrix {
|
||||
<f6f23f41-7686-11cf-8f52-0040333594a3>
|
||||
Matrix4x4 frameMatrix;
|
||||
}
|
||||
|
||||
template Vector {
|
||||
<3d82ab5e-62da-11cf-ab39-0020af71e433>
|
||||
FLOAT x;
|
||||
FLOAT y;
|
||||
FLOAT z;
|
||||
}
|
||||
|
||||
template MeshFace {
|
||||
<3d82ab5f-62da-11cf-ab39-0020af71e433>
|
||||
DWORD nFaceVertexIndices;
|
||||
array DWORD faceVertexIndices[nFaceVertexIndices];
|
||||
}
|
||||
|
||||
template Mesh {
|
||||
<3d82ab44-62da-11cf-ab39-0020af71e433>
|
||||
DWORD nVertices;
|
||||
array Vector vertices[nVertices];
|
||||
DWORD nFaces;
|
||||
array MeshFace faces[nFaces];
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshNormals {
|
||||
<f6f23f43-7686-11cf-8f52-0040333594a3>
|
||||
DWORD nNormals;
|
||||
array Vector normals[nNormals];
|
||||
DWORD nFaceNormals;
|
||||
array MeshFace faceNormals[nFaceNormals];
|
||||
}
|
||||
|
||||
template ColorRGBA {
|
||||
<35ff44e0-6c7c-11cf-8f52-0040333594a3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
FLOAT alpha;
|
||||
}
|
||||
|
||||
template ColorRGB {
|
||||
<d3e16e81-7835-11cf-8f52-0040333594a3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
}
|
||||
|
||||
template Material {
|
||||
<3d82ab4d-62da-11cf-ab39-0020af71e433>
|
||||
ColorRGBA faceColor;
|
||||
FLOAT power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshMaterialList {
|
||||
<f6f23f42-7686-11cf-8f52-0040333594a3>
|
||||
DWORD nMaterials;
|
||||
DWORD nFaceIndexes;
|
||||
array DWORD faceIndexes[nFaceIndexes];
|
||||
[Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]
|
||||
}
|
||||
|
||||
template VertexDuplicationIndices {
|
||||
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
|
||||
DWORD nIndices;
|
||||
DWORD nOriginalVertices;
|
||||
array DWORD indices[nIndices];
|
||||
}
|
||||
|
||||
|
||||
Frame {
|
||||
|
||||
|
||||
FrameTransformMatrix {
|
||||
1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
|
||||
}
|
||||
|
||||
Mesh {
|
||||
102;
|
||||
0.000000;0.000000;-1.500000;,
|
||||
0.000000;1.000000;-1.500000;,
|
||||
0.309017;0.951057;-1.500000;,
|
||||
0.587785;0.809017;-1.500000;,
|
||||
0.809017;0.587785;-1.500000;,
|
||||
0.951057;0.309017;-1.500000;,
|
||||
1.000000;-0.000000;-1.500000;,
|
||||
0.951057;-0.309017;-1.500000;,
|
||||
0.809017;-0.587785;-1.500000;,
|
||||
0.587785;-0.809017;-1.500000;,
|
||||
0.309017;-0.951057;-1.500000;,
|
||||
-0.000000;-1.000000;-1.500000;,
|
||||
-0.309017;-0.951056;-1.500000;,
|
||||
-0.587785;-0.809017;-1.500000;,
|
||||
-0.809017;-0.587785;-1.500000;,
|
||||
-0.951057;-0.309017;-1.500000;,
|
||||
-1.000000;0.000000;-1.500000;,
|
||||
-0.951057;0.309017;-1.500000;,
|
||||
-0.809017;0.587786;-1.500000;,
|
||||
-0.587785;0.809017;-1.500000;,
|
||||
-0.309017;0.951057;-1.500000;,
|
||||
0.000000;1.000000;-1.500000;,
|
||||
0.309017;0.951057;-1.500000;,
|
||||
0.587785;0.809017;-1.500000;,
|
||||
0.809017;0.587785;-1.500000;,
|
||||
0.951057;0.309017;-1.500000;,
|
||||
1.000000;-0.000000;-1.500000;,
|
||||
0.951057;-0.309017;-1.500000;,
|
||||
0.809017;-0.587785;-1.500000;,
|
||||
0.587785;-0.809017;-1.500000;,
|
||||
0.309017;-0.951057;-1.500000;,
|
||||
-0.000000;-1.000000;-1.500000;,
|
||||
-0.309017;-0.951056;-1.500000;,
|
||||
-0.587785;-0.809017;-1.500000;,
|
||||
-0.809017;-0.587785;-1.500000;,
|
||||
-0.951057;-0.309017;-1.500000;,
|
||||
-1.000000;0.000000;-1.500000;,
|
||||
-0.951057;0.309017;-1.500000;,
|
||||
-0.809017;0.587786;-1.500000;,
|
||||
-0.587785;0.809017;-1.500000;,
|
||||
-0.309017;0.951057;-1.500000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.309017;0.951057;0.000000;,
|
||||
0.587785;0.809017;0.000000;,
|
||||
0.809017;0.587785;0.000000;,
|
||||
0.951057;0.309017;0.000000;,
|
||||
1.000000;-0.000000;0.000000;,
|
||||
0.951057;-0.309017;0.000000;,
|
||||
0.809017;-0.587785;0.000000;,
|
||||
0.587785;-0.809017;0.000000;,
|
||||
0.309017;-0.951057;0.000000;,
|
||||
-0.000000;-1.000000;0.000000;,
|
||||
-0.309017;-0.951056;0.000000;,
|
||||
-0.587785;-0.809017;0.000000;,
|
||||
-0.809017;-0.587785;0.000000;,
|
||||
-0.951057;-0.309017;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-0.951057;0.309017;0.000000;,
|
||||
-0.809017;0.587786;0.000000;,
|
||||
-0.587785;0.809017;0.000000;,
|
||||
-0.309017;0.951057;0.000000;,
|
||||
0.000000;1.000000;1.500000;,
|
||||
0.309017;0.951057;1.500000;,
|
||||
0.587785;0.809017;1.500000;,
|
||||
0.809017;0.587785;1.500000;,
|
||||
0.951057;0.309017;1.500000;,
|
||||
1.000000;-0.000000;1.500000;,
|
||||
0.951057;-0.309017;1.500000;,
|
||||
0.809017;-0.587785;1.500000;,
|
||||
0.587785;-0.809017;1.500000;,
|
||||
0.309017;-0.951057;1.500000;,
|
||||
-0.000000;-1.000000;1.500000;,
|
||||
-0.309017;-0.951056;1.500000;,
|
||||
-0.587785;-0.809017;1.500000;,
|
||||
-0.809017;-0.587785;1.500000;,
|
||||
-0.951057;-0.309017;1.500000;,
|
||||
-1.000000;0.000000;1.500000;,
|
||||
-0.951057;0.309017;1.500000;,
|
||||
-0.809017;0.587786;1.500000;,
|
||||
-0.587785;0.809017;1.500000;,
|
||||
-0.309017;0.951057;1.500000;,
|
||||
0.000000;1.000000;1.500000;,
|
||||
0.309017;0.951057;1.500000;,
|
||||
0.587785;0.809017;1.500000;,
|
||||
0.809017;0.587785;1.500000;,
|
||||
0.951057;0.309017;1.500000;,
|
||||
1.000000;-0.000000;1.500000;,
|
||||
0.951057;-0.309017;1.500000;,
|
||||
0.809017;-0.587785;1.500000;,
|
||||
0.587785;-0.809017;1.500000;,
|
||||
0.309017;-0.951057;1.500000;,
|
||||
-0.000000;-1.000000;1.500000;,
|
||||
-0.309017;-0.951056;1.500000;,
|
||||
-0.587785;-0.809017;1.500000;,
|
||||
-0.809017;-0.587785;1.500000;,
|
||||
-0.951057;-0.309017;1.500000;,
|
||||
-1.000000;0.000000;1.500000;,
|
||||
-0.951057;0.309017;1.500000;,
|
||||
-0.809017;0.587786;1.500000;,
|
||||
-0.587785;0.809017;1.500000;,
|
||||
-0.309017;0.951057;1.500000;,
|
||||
0.000000;0.000000;1.500000;;
|
||||
120;
|
||||
3;0,1,2;,
|
||||
3;0,2,3;,
|
||||
3;0,3,4;,
|
||||
3;0,4,5;,
|
||||
3;0,5,6;,
|
||||
3;0,6,7;,
|
||||
3;0,7,8;,
|
||||
3;0,8,9;,
|
||||
3;0,9,10;,
|
||||
3;0,10,11;,
|
||||
3;0,11,12;,
|
||||
3;0,12,13;,
|
||||
3;0,13,14;,
|
||||
3;0,14,15;,
|
||||
3;0,15,16;,
|
||||
3;0,16,17;,
|
||||
3;0,17,18;,
|
||||
3;0,18,19;,
|
||||
3;0,19,20;,
|
||||
3;0,20,1;,
|
||||
3;21,41,22;,
|
||||
3;22,41,42;,
|
||||
3;22,42,23;,
|
||||
3;23,42,43;,
|
||||
3;23,43,24;,
|
||||
3;24,43,44;,
|
||||
3;24,44,25;,
|
||||
3;25,44,45;,
|
||||
3;25,45,26;,
|
||||
3;26,45,46;,
|
||||
3;26,46,27;,
|
||||
3;27,46,47;,
|
||||
3;27,47,28;,
|
||||
3;28,47,48;,
|
||||
3;28,48,29;,
|
||||
3;29,48,49;,
|
||||
3;29,49,30;,
|
||||
3;30,49,50;,
|
||||
3;30,50,31;,
|
||||
3;31,50,51;,
|
||||
3;31,51,32;,
|
||||
3;32,51,52;,
|
||||
3;32,52,33;,
|
||||
3;33,52,53;,
|
||||
3;33,53,34;,
|
||||
3;34,53,54;,
|
||||
3;34,54,35;,
|
||||
3;35,54,55;,
|
||||
3;35,55,36;,
|
||||
3;36,55,56;,
|
||||
3;36,56,37;,
|
||||
3;37,56,57;,
|
||||
3;37,57,38;,
|
||||
3;38,57,58;,
|
||||
3;38,58,39;,
|
||||
3;39,58,59;,
|
||||
3;39,59,40;,
|
||||
3;40,59,60;,
|
||||
3;40,60,21;,
|
||||
3;21,60,41;,
|
||||
3;41,61,42;,
|
||||
3;42,61,62;,
|
||||
3;42,62,43;,
|
||||
3;43,62,63;,
|
||||
3;43,63,44;,
|
||||
3;44,63,64;,
|
||||
3;44,64,45;,
|
||||
3;45,64,65;,
|
||||
3;45,65,46;,
|
||||
3;46,65,66;,
|
||||
3;46,66,47;,
|
||||
3;47,66,67;,
|
||||
3;47,67,48;,
|
||||
3;48,67,68;,
|
||||
3;48,68,49;,
|
||||
3;49,68,69;,
|
||||
3;49,69,50;,
|
||||
3;50,69,70;,
|
||||
3;50,70,51;,
|
||||
3;51,70,71;,
|
||||
3;51,71,52;,
|
||||
3;52,71,72;,
|
||||
3;52,72,53;,
|
||||
3;53,72,73;,
|
||||
3;53,73,54;,
|
||||
3;54,73,74;,
|
||||
3;54,74,55;,
|
||||
3;55,74,75;,
|
||||
3;55,75,56;,
|
||||
3;56,75,76;,
|
||||
3;56,76,57;,
|
||||
3;57,76,77;,
|
||||
3;57,77,58;,
|
||||
3;58,77,78;,
|
||||
3;58,78,59;,
|
||||
3;59,78,79;,
|
||||
3;59,79,60;,
|
||||
3;60,79,80;,
|
||||
3;60,80,41;,
|
||||
3;41,80,61;,
|
||||
3;81,101,82;,
|
||||
3;82,101,83;,
|
||||
3;83,101,84;,
|
||||
3;84,101,85;,
|
||||
3;85,101,86;,
|
||||
3;86,101,87;,
|
||||
3;87,101,88;,
|
||||
3;88,101,89;,
|
||||
3;89,101,90;,
|
||||
3;90,101,91;,
|
||||
3;91,101,92;,
|
||||
3;92,101,93;,
|
||||
3;93,101,94;,
|
||||
3;94,101,95;,
|
||||
3;95,101,96;,
|
||||
3;96,101,97;,
|
||||
3;97,101,98;,
|
||||
3;98,101,99;,
|
||||
3;99,101,100;,
|
||||
3;100,101,81;;
|
||||
|
||||
MeshNormals {
|
||||
102;
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;0.000000;-1.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.309017;0.951057;0.000000;,
|
||||
0.587785;0.809017;0.000000;,
|
||||
0.809017;0.587785;0.000000;,
|
||||
0.951057;0.309017;0.000000;,
|
||||
1.000000;-0.000000;0.000000;,
|
||||
0.951057;-0.309017;0.000000;,
|
||||
0.809017;-0.587785;0.000000;,
|
||||
0.587785;-0.809017;0.000000;,
|
||||
0.309017;-0.951057;0.000000;,
|
||||
-0.000000;-1.000000;0.000000;,
|
||||
-0.309017;-0.951056;0.000000;,
|
||||
-0.587785;-0.809017;0.000000;,
|
||||
-0.809017;-0.587785;0.000000;,
|
||||
-0.951057;-0.309017;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-0.951057;0.309017;0.000000;,
|
||||
-0.809017;0.587786;0.000000;,
|
||||
-0.587785;0.809017;0.000000;,
|
||||
-0.309017;0.951057;0.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.309017;0.951057;0.000000;,
|
||||
0.587785;0.809017;0.000000;,
|
||||
0.809017;0.587785;0.000000;,
|
||||
0.951057;0.309017;0.000000;,
|
||||
1.000000;-0.000000;0.000000;,
|
||||
0.951057;-0.309017;0.000000;,
|
||||
0.809017;-0.587785;0.000000;,
|
||||
0.587785;-0.809017;0.000000;,
|
||||
0.309017;-0.951057;0.000000;,
|
||||
-0.000000;-1.000000;0.000000;,
|
||||
-0.309017;-0.951056;0.000000;,
|
||||
-0.587785;-0.809017;0.000000;,
|
||||
-0.809017;-0.587785;0.000000;,
|
||||
-0.951057;-0.309017;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-0.951057;0.309017;0.000000;,
|
||||
-0.809017;0.587786;0.000000;,
|
||||
-0.587785;0.809017;0.000000;,
|
||||
-0.309017;0.951057;0.000000;,
|
||||
0.000000;1.000000;0.000000;,
|
||||
0.309017;0.951057;0.000000;,
|
||||
0.587785;0.809017;0.000000;,
|
||||
0.809017;0.587785;0.000000;,
|
||||
0.951057;0.309017;0.000000;,
|
||||
1.000000;-0.000000;0.000000;,
|
||||
0.951057;-0.309017;0.000000;,
|
||||
0.809017;-0.587785;0.000000;,
|
||||
0.587785;-0.809017;0.000000;,
|
||||
0.309017;-0.951057;0.000000;,
|
||||
-0.000000;-1.000000;0.000000;,
|
||||
-0.309017;-0.951056;0.000000;,
|
||||
-0.587785;-0.809017;0.000000;,
|
||||
-0.809017;-0.587785;0.000000;,
|
||||
-0.951057;-0.309017;0.000000;,
|
||||
-1.000000;0.000000;0.000000;,
|
||||
-0.951057;0.309017;0.000000;,
|
||||
-0.809017;0.587786;0.000000;,
|
||||
-0.587785;0.809017;0.000000;,
|
||||
-0.309017;0.951057;0.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.000000;1.000000;;
|
||||
120;
|
||||
3;0,1,2;,
|
||||
3;0,2,3;,
|
||||
3;0,3,4;,
|
||||
3;0,4,5;,
|
||||
3;0,5,6;,
|
||||
3;0,6,7;,
|
||||
3;0,7,8;,
|
||||
3;0,8,9;,
|
||||
3;0,9,10;,
|
||||
3;0,10,11;,
|
||||
3;0,11,12;,
|
||||
3;0,12,13;,
|
||||
3;0,13,14;,
|
||||
3;0,14,15;,
|
||||
3;0,15,16;,
|
||||
3;0,16,17;,
|
||||
3;0,17,18;,
|
||||
3;0,18,19;,
|
||||
3;0,19,20;,
|
||||
3;0,20,1;,
|
||||
3;21,41,22;,
|
||||
3;22,41,42;,
|
||||
3;22,42,23;,
|
||||
3;23,42,43;,
|
||||
3;23,43,24;,
|
||||
3;24,43,44;,
|
||||
3;24,44,25;,
|
||||
3;25,44,45;,
|
||||
3;25,45,26;,
|
||||
3;26,45,46;,
|
||||
3;26,46,27;,
|
||||
3;27,46,47;,
|
||||
3;27,47,28;,
|
||||
3;28,47,48;,
|
||||
3;28,48,29;,
|
||||
3;29,48,49;,
|
||||
3;29,49,30;,
|
||||
3;30,49,50;,
|
||||
3;30,50,31;,
|
||||
3;31,50,51;,
|
||||
3;31,51,32;,
|
||||
3;32,51,52;,
|
||||
3;32,52,33;,
|
||||
3;33,52,53;,
|
||||
3;33,53,34;,
|
||||
3;34,53,54;,
|
||||
3;34,54,35;,
|
||||
3;35,54,55;,
|
||||
3;35,55,36;,
|
||||
3;36,55,56;,
|
||||
3;36,56,37;,
|
||||
3;37,56,57;,
|
||||
3;37,57,38;,
|
||||
3;38,57,58;,
|
||||
3;38,58,39;,
|
||||
3;39,58,59;,
|
||||
3;39,59,40;,
|
||||
3;40,59,60;,
|
||||
3;40,60,21;,
|
||||
3;21,60,41;,
|
||||
3;41,61,42;,
|
||||
3;42,61,62;,
|
||||
3;42,62,43;,
|
||||
3;43,62,63;,
|
||||
3;43,63,44;,
|
||||
3;44,63,64;,
|
||||
3;44,64,45;,
|
||||
3;45,64,65;,
|
||||
3;45,65,46;,
|
||||
3;46,65,66;,
|
||||
3;46,66,47;,
|
||||
3;47,66,67;,
|
||||
3;47,67,48;,
|
||||
3;48,67,68;,
|
||||
3;48,68,49;,
|
||||
3;49,68,69;,
|
||||
3;49,69,50;,
|
||||
3;50,69,70;,
|
||||
3;50,70,51;,
|
||||
3;51,70,71;,
|
||||
3;51,71,52;,
|
||||
3;52,71,72;,
|
||||
3;52,72,53;,
|
||||
3;53,72,73;,
|
||||
3;53,73,54;,
|
||||
3;54,73,74;,
|
||||
3;54,74,55;,
|
||||
3;55,74,75;,
|
||||
3;55,75,56;,
|
||||
3;56,75,76;,
|
||||
3;56,76,57;,
|
||||
3;57,76,77;,
|
||||
3;57,77,58;,
|
||||
3;58,77,78;,
|
||||
3;58,78,59;,
|
||||
3;59,78,79;,
|
||||
3;59,79,60;,
|
||||
3;60,79,80;,
|
||||
3;60,80,41;,
|
||||
3;41,80,61;,
|
||||
3;81,101,82;,
|
||||
3;82,101,83;,
|
||||
3;83,101,84;,
|
||||
3;84,101,85;,
|
||||
3;85,101,86;,
|
||||
3;86,101,87;,
|
||||
3;87,101,88;,
|
||||
3;88,101,89;,
|
||||
3;89,101,90;,
|
||||
3;90,101,91;,
|
||||
3;91,101,92;,
|
||||
3;92,101,93;,
|
||||
3;93,101,94;,
|
||||
3;94,101,95;,
|
||||
3;95,101,96;,
|
||||
3;96,101,97;,
|
||||
3;97,101,98;,
|
||||
3;98,101,99;,
|
||||
3;99,101,100;,
|
||||
3;100,101,81;;
|
||||
}
|
||||
|
||||
MeshMaterialList {
|
||||
1;
|
||||
120;
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0;
|
||||
|
||||
Material {
|
||||
0.500000;0.500000;0.500000;0.000000;;
|
||||
0.000000;
|
||||
0.500000;0.500000;0.500000;;
|
||||
0.000000;0.000000;0.000000;;
|
||||
}
|
||||
}
|
||||
|
||||
VertexDuplicationIndices {
|
||||
102;
|
||||
62;
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
60,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
64,
|
||||
65,
|
||||
66,
|
||||
67,
|
||||
68,
|
||||
69,
|
||||
70,
|
||||
71,
|
||||
72,
|
||||
73,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
64,
|
||||
65,
|
||||
66,
|
||||
67,
|
||||
68,
|
||||
69,
|
||||
70,
|
||||
71,
|
||||
72,
|
||||
73,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
101;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,936 +0,0 @@
|
||||
xof 0303txt 0032
|
||||
template Frame {
|
||||
<3d82ab46-62da-11cf-ab39-0020af71e433>
|
||||
[...]
|
||||
}
|
||||
|
||||
template Matrix4x4 {
|
||||
<f6f23f45-7686-11cf-8f52-0040333594a3>
|
||||
array FLOAT matrix[16];
|
||||
}
|
||||
|
||||
template FrameTransformMatrix {
|
||||
<f6f23f41-7686-11cf-8f52-0040333594a3>
|
||||
Matrix4x4 frameMatrix;
|
||||
}
|
||||
|
||||
template Vector {
|
||||
<3d82ab5e-62da-11cf-ab39-0020af71e433>
|
||||
FLOAT x;
|
||||
FLOAT y;
|
||||
FLOAT z;
|
||||
}
|
||||
|
||||
template MeshFace {
|
||||
<3d82ab5f-62da-11cf-ab39-0020af71e433>
|
||||
DWORD nFaceVertexIndices;
|
||||
array DWORD faceVertexIndices[nFaceVertexIndices];
|
||||
}
|
||||
|
||||
template Mesh {
|
||||
<3d82ab44-62da-11cf-ab39-0020af71e433>
|
||||
DWORD nVertices;
|
||||
array Vector vertices[nVertices];
|
||||
DWORD nFaces;
|
||||
array MeshFace faces[nFaces];
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshNormals {
|
||||
<f6f23f43-7686-11cf-8f52-0040333594a3>
|
||||
DWORD nNormals;
|
||||
array Vector normals[nNormals];
|
||||
DWORD nFaceNormals;
|
||||
array MeshFace faceNormals[nFaceNormals];
|
||||
}
|
||||
|
||||
template ColorRGBA {
|
||||
<35ff44e0-6c7c-11cf-8f52-0040333594a3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
FLOAT alpha;
|
||||
}
|
||||
|
||||
template ColorRGB {
|
||||
<d3e16e81-7835-11cf-8f52-0040333594a3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
}
|
||||
|
||||
template Material {
|
||||
<3d82ab4d-62da-11cf-ab39-0020af71e433>
|
||||
ColorRGBA faceColor;
|
||||
FLOAT power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshMaterialList {
|
||||
<f6f23f42-7686-11cf-8f52-0040333594a3>
|
||||
DWORD nMaterials;
|
||||
DWORD nFaceIndexes;
|
||||
array DWORD faceIndexes[nFaceIndexes];
|
||||
[Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]
|
||||
}
|
||||
|
||||
template VertexDuplicationIndices {
|
||||
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
|
||||
DWORD nIndices;
|
||||
DWORD nOriginalVertices;
|
||||
array DWORD indices[nIndices];
|
||||
}
|
||||
|
||||
|
||||
Frame {
|
||||
|
||||
|
||||
FrameTransformMatrix {
|
||||
1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
|
||||
}
|
||||
|
||||
Mesh {
|
||||
92;
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.309017;0.951057;,
|
||||
0.181636;0.250000;0.951057;,
|
||||
0.293893;0.095491;0.951057;,
|
||||
0.293893;-0.095492;0.951057;,
|
||||
0.181636;-0.250000;0.951057;,
|
||||
-0.000000;-0.309017;0.951057;,
|
||||
-0.181636;-0.250000;0.951057;,
|
||||
-0.293893;-0.095491;0.951057;,
|
||||
-0.293893;0.095492;0.951057;,
|
||||
-0.181636;0.250000;0.951057;,
|
||||
0.000000;0.587785;0.809017;,
|
||||
0.345491;0.475528;0.809017;,
|
||||
0.559017;0.181636;0.809017;,
|
||||
0.559017;-0.181636;0.809017;,
|
||||
0.345491;-0.475528;0.809017;,
|
||||
-0.000000;-0.587785;0.809017;,
|
||||
-0.345492;-0.475528;0.809017;,
|
||||
-0.559017;-0.181635;0.809017;,
|
||||
-0.559017;0.181636;0.809017;,
|
||||
-0.345492;0.475528;0.809017;,
|
||||
0.000000;0.809017;0.587785;,
|
||||
0.475528;0.654509;0.587785;,
|
||||
0.769421;0.250000;0.587785;,
|
||||
0.769421;-0.250000;0.587785;,
|
||||
0.475528;-0.654509;0.587785;,
|
||||
-0.000000;-0.809017;0.587785;,
|
||||
-0.475528;-0.654508;0.587785;,
|
||||
-0.769421;-0.250000;0.587785;,
|
||||
-0.769421;0.250000;0.587785;,
|
||||
-0.475528;0.654508;0.587785;,
|
||||
0.000000;0.951057;0.309017;,
|
||||
0.559017;0.769421;0.309017;,
|
||||
0.904509;0.293893;0.309017;,
|
||||
0.904508;-0.293893;0.309017;,
|
||||
0.559017;-0.769421;0.309017;,
|
||||
-0.000000;-0.951057;0.309017;,
|
||||
-0.559017;-0.769421;0.309017;,
|
||||
-0.904509;-0.293892;0.309017;,
|
||||
-0.904508;0.293893;0.309017;,
|
||||
-0.559017;0.769421;0.309017;,
|
||||
0.000000;1.000000;-0.000000;,
|
||||
0.587785;0.809017;-0.000000;,
|
||||
0.951057;0.309017;-0.000000;,
|
||||
0.951056;-0.309017;-0.000000;,
|
||||
0.587785;-0.809017;-0.000000;,
|
||||
-0.000000;-1.000000;-0.000000;,
|
||||
-0.587785;-0.809017;-0.000000;,
|
||||
-0.951057;-0.309017;-0.000000;,
|
||||
-0.951056;0.309017;-0.000000;,
|
||||
-0.587785;0.809017;-0.000000;,
|
||||
0.000000;0.951056;-0.309017;,
|
||||
0.559017;0.769421;-0.309017;,
|
||||
0.904508;0.293893;-0.309017;,
|
||||
0.904508;-0.293893;-0.309017;,
|
||||
0.559017;-0.769421;-0.309017;,
|
||||
-0.000000;-0.951056;-0.309017;,
|
||||
-0.559017;-0.769421;-0.309017;,
|
||||
-0.904509;-0.293892;-0.309017;,
|
||||
-0.904508;0.293893;-0.309017;,
|
||||
-0.559017;0.769421;-0.309017;,
|
||||
0.000000;0.809017;-0.587785;,
|
||||
0.475528;0.654508;-0.587785;,
|
||||
0.769421;0.250000;-0.587785;,
|
||||
0.769421;-0.250000;-0.587785;,
|
||||
0.475528;-0.654508;-0.587785;,
|
||||
-0.000000;-0.809017;-0.587785;,
|
||||
-0.475528;-0.654508;-0.587785;,
|
||||
-0.769421;-0.250000;-0.587785;,
|
||||
-0.769421;0.250000;-0.587785;,
|
||||
-0.475528;0.654508;-0.587785;,
|
||||
0.000000;0.587785;-0.809017;,
|
||||
0.345491;0.475528;-0.809017;,
|
||||
0.559017;0.181636;-0.809017;,
|
||||
0.559017;-0.181636;-0.809017;,
|
||||
0.345491;-0.475528;-0.809017;,
|
||||
-0.000000;-0.587785;-0.809017;,
|
||||
-0.345492;-0.475528;-0.809017;,
|
||||
-0.559017;-0.181635;-0.809017;,
|
||||
-0.559017;0.181636;-0.809017;,
|
||||
-0.345491;0.475528;-0.809017;,
|
||||
0.000000;0.309017;-0.951056;,
|
||||
0.181636;0.250000;-0.951056;,
|
||||
0.293893;0.095492;-0.951056;,
|
||||
0.293893;-0.095492;-0.951056;,
|
||||
0.181636;-0.250000;-0.951056;,
|
||||
-0.000000;-0.309017;-0.951056;,
|
||||
-0.181636;-0.250000;-0.951056;,
|
||||
-0.293893;-0.095491;-0.951056;,
|
||||
-0.293893;0.095492;-0.951056;,
|
||||
-0.181636;0.250000;-0.951056;,
|
||||
0.000000;0.000000;-1.000000;;
|
||||
180;
|
||||
3;0,2,1;,
|
||||
3;0,3,2;,
|
||||
3;0,4,3;,
|
||||
3;0,5,4;,
|
||||
3;0,6,5;,
|
||||
3;0,7,6;,
|
||||
3;0,8,7;,
|
||||
3;0,9,8;,
|
||||
3;0,10,9;,
|
||||
3;0,1,10;,
|
||||
3;1,2,11;,
|
||||
3;2,12,11;,
|
||||
3;2,3,12;,
|
||||
3;3,13,12;,
|
||||
3;3,4,13;,
|
||||
3;4,14,13;,
|
||||
3;4,5,14;,
|
||||
3;5,15,14;,
|
||||
3;5,6,15;,
|
||||
3;6,16,15;,
|
||||
3;6,7,16;,
|
||||
3;7,17,16;,
|
||||
3;7,8,17;,
|
||||
3;8,18,17;,
|
||||
3;8,9,18;,
|
||||
3;9,19,18;,
|
||||
3;9,10,19;,
|
||||
3;10,20,19;,
|
||||
3;10,1,20;,
|
||||
3;1,11,20;,
|
||||
3;11,12,21;,
|
||||
3;12,22,21;,
|
||||
3;12,13,22;,
|
||||
3;13,23,22;,
|
||||
3;13,14,23;,
|
||||
3;14,24,23;,
|
||||
3;14,15,24;,
|
||||
3;15,25,24;,
|
||||
3;15,16,25;,
|
||||
3;16,26,25;,
|
||||
3;16,17,26;,
|
||||
3;17,27,26;,
|
||||
3;17,18,27;,
|
||||
3;18,28,27;,
|
||||
3;18,19,28;,
|
||||
3;19,29,28;,
|
||||
3;19,20,29;,
|
||||
3;20,30,29;,
|
||||
3;20,11,30;,
|
||||
3;11,21,30;,
|
||||
3;21,22,31;,
|
||||
3;22,32,31;,
|
||||
3;22,23,32;,
|
||||
3;23,33,32;,
|
||||
3;23,24,33;,
|
||||
3;24,34,33;,
|
||||
3;24,25,34;,
|
||||
3;25,35,34;,
|
||||
3;25,26,35;,
|
||||
3;26,36,35;,
|
||||
3;26,27,36;,
|
||||
3;27,37,36;,
|
||||
3;27,28,37;,
|
||||
3;28,38,37;,
|
||||
3;28,29,38;,
|
||||
3;29,39,38;,
|
||||
3;29,30,39;,
|
||||
3;30,40,39;,
|
||||
3;30,21,40;,
|
||||
3;21,31,40;,
|
||||
3;31,32,41;,
|
||||
3;32,42,41;,
|
||||
3;32,33,42;,
|
||||
3;33,43,42;,
|
||||
3;33,34,43;,
|
||||
3;34,44,43;,
|
||||
3;34,35,44;,
|
||||
3;35,45,44;,
|
||||
3;35,36,45;,
|
||||
3;36,46,45;,
|
||||
3;36,37,46;,
|
||||
3;37,47,46;,
|
||||
3;37,38,47;,
|
||||
3;38,48,47;,
|
||||
3;38,39,48;,
|
||||
3;39,49,48;,
|
||||
3;39,40,49;,
|
||||
3;40,50,49;,
|
||||
3;40,31,50;,
|
||||
3;31,41,50;,
|
||||
3;41,42,51;,
|
||||
3;42,52,51;,
|
||||
3;42,43,52;,
|
||||
3;43,53,52;,
|
||||
3;43,44,53;,
|
||||
3;44,54,53;,
|
||||
3;44,45,54;,
|
||||
3;45,55,54;,
|
||||
3;45,46,55;,
|
||||
3;46,56,55;,
|
||||
3;46,47,56;,
|
||||
3;47,57,56;,
|
||||
3;47,48,57;,
|
||||
3;48,58,57;,
|
||||
3;48,49,58;,
|
||||
3;49,59,58;,
|
||||
3;49,50,59;,
|
||||
3;50,60,59;,
|
||||
3;50,41,60;,
|
||||
3;41,51,60;,
|
||||
3;51,52,61;,
|
||||
3;52,62,61;,
|
||||
3;52,53,62;,
|
||||
3;53,63,62;,
|
||||
3;53,54,63;,
|
||||
3;54,64,63;,
|
||||
3;54,55,64;,
|
||||
3;55,65,64;,
|
||||
3;55,56,65;,
|
||||
3;56,66,65;,
|
||||
3;56,57,66;,
|
||||
3;57,67,66;,
|
||||
3;57,58,67;,
|
||||
3;58,68,67;,
|
||||
3;58,59,68;,
|
||||
3;59,69,68;,
|
||||
3;59,60,69;,
|
||||
3;60,70,69;,
|
||||
3;60,51,70;,
|
||||
3;51,61,70;,
|
||||
3;61,62,71;,
|
||||
3;62,72,71;,
|
||||
3;62,63,72;,
|
||||
3;63,73,72;,
|
||||
3;63,64,73;,
|
||||
3;64,74,73;,
|
||||
3;64,65,74;,
|
||||
3;65,75,74;,
|
||||
3;65,66,75;,
|
||||
3;66,76,75;,
|
||||
3;66,67,76;,
|
||||
3;67,77,76;,
|
||||
3;67,68,77;,
|
||||
3;68,78,77;,
|
||||
3;68,69,78;,
|
||||
3;69,79,78;,
|
||||
3;69,70,79;,
|
||||
3;70,80,79;,
|
||||
3;70,61,80;,
|
||||
3;61,71,80;,
|
||||
3;71,72,81;,
|
||||
3;72,82,81;,
|
||||
3;72,73,82;,
|
||||
3;73,83,82;,
|
||||
3;73,74,83;,
|
||||
3;74,84,83;,
|
||||
3;74,75,84;,
|
||||
3;75,85,84;,
|
||||
3;75,76,85;,
|
||||
3;76,86,85;,
|
||||
3;76,77,86;,
|
||||
3;77,87,86;,
|
||||
3;77,78,87;,
|
||||
3;78,88,87;,
|
||||
3;78,79,88;,
|
||||
3;79,89,88;,
|
||||
3;79,80,89;,
|
||||
3;80,90,89;,
|
||||
3;80,71,90;,
|
||||
3;71,81,90;,
|
||||
3;81,82,91;,
|
||||
3;82,83,91;,
|
||||
3;83,84,91;,
|
||||
3;84,85,91;,
|
||||
3;85,86,91;,
|
||||
3;86,87,91;,
|
||||
3;87,88,91;,
|
||||
3;88,89,91;,
|
||||
3;89,90,91;,
|
||||
3;90,81,91;;
|
||||
|
||||
MeshNormals {
|
||||
92;
|
||||
0.000000;0.000000;1.000000;,
|
||||
0.000000;0.309017;0.951057;,
|
||||
0.181636;0.250000;0.951057;,
|
||||
0.293893;0.095491;0.951057;,
|
||||
0.293893;-0.095492;0.951057;,
|
||||
0.181636;-0.250000;0.951057;,
|
||||
-0.000000;-0.309017;0.951057;,
|
||||
-0.181636;-0.250000;0.951057;,
|
||||
-0.293893;-0.095491;0.951057;,
|
||||
-0.293893;0.095492;0.951057;,
|
||||
-0.181636;0.250000;0.951057;,
|
||||
0.000000;0.587785;0.809017;,
|
||||
0.345491;0.475528;0.809017;,
|
||||
0.559017;0.181636;0.809017;,
|
||||
0.559017;-0.181636;0.809017;,
|
||||
0.345491;-0.475528;0.809017;,
|
||||
-0.000000;-0.587785;0.809017;,
|
||||
-0.345492;-0.475528;0.809017;,
|
||||
-0.559017;-0.181635;0.809017;,
|
||||
-0.559017;0.181636;0.809017;,
|
||||
-0.345492;0.475528;0.809017;,
|
||||
0.000000;0.809017;0.587785;,
|
||||
0.475528;0.654509;0.587785;,
|
||||
0.769421;0.250000;0.587785;,
|
||||
0.769421;-0.250000;0.587785;,
|
||||
0.475528;-0.654509;0.587785;,
|
||||
-0.000000;-0.809017;0.587785;,
|
||||
-0.475528;-0.654508;0.587785;,
|
||||
-0.769421;-0.250000;0.587785;,
|
||||
-0.769421;0.250000;0.587785;,
|
||||
-0.475528;0.654508;0.587785;,
|
||||
0.000000;0.951057;0.309017;,
|
||||
0.559017;0.769421;0.309017;,
|
||||
0.904509;0.293893;0.309017;,
|
||||
0.904508;-0.293893;0.309017;,
|
||||
0.559017;-0.769421;0.309017;,
|
||||
-0.000000;-0.951057;0.309017;,
|
||||
-0.559017;-0.769421;0.309017;,
|
||||
-0.904509;-0.293892;0.309017;,
|
||||
-0.904508;0.293893;0.309017;,
|
||||
-0.559017;0.769421;0.309017;,
|
||||
0.000000;1.000000;-0.000000;,
|
||||
0.587785;0.809017;-0.000000;,
|
||||
0.951057;0.309017;-0.000000;,
|
||||
0.951056;-0.309017;-0.000000;,
|
||||
0.587785;-0.809017;-0.000000;,
|
||||
-0.000000;-1.000000;-0.000000;,
|
||||
-0.587785;-0.809017;-0.000000;,
|
||||
-0.951057;-0.309017;-0.000000;,
|
||||
-0.951056;0.309017;-0.000000;,
|
||||
-0.587785;0.809017;-0.000000;,
|
||||
0.000000;0.951056;-0.309017;,
|
||||
0.559017;0.769421;-0.309017;,
|
||||
0.904508;0.293893;-0.309017;,
|
||||
0.904508;-0.293893;-0.309017;,
|
||||
0.559017;-0.769421;-0.309017;,
|
||||
-0.000000;-0.951056;-0.309017;,
|
||||
-0.559017;-0.769421;-0.309017;,
|
||||
-0.904509;-0.293892;-0.309017;,
|
||||
-0.904508;0.293893;-0.309017;,
|
||||
-0.559017;0.769421;-0.309017;,
|
||||
0.000000;0.809017;-0.587785;,
|
||||
0.475528;0.654508;-0.587785;,
|
||||
0.769421;0.250000;-0.587785;,
|
||||
0.769421;-0.250000;-0.587785;,
|
||||
0.475528;-0.654508;-0.587785;,
|
||||
-0.000000;-0.809017;-0.587785;,
|
||||
-0.475528;-0.654508;-0.587785;,
|
||||
-0.769421;-0.250000;-0.587785;,
|
||||
-0.769421;0.250000;-0.587785;,
|
||||
-0.475528;0.654508;-0.587785;,
|
||||
0.000000;0.587785;-0.809017;,
|
||||
0.345491;0.475528;-0.809017;,
|
||||
0.559017;0.181636;-0.809017;,
|
||||
0.559017;-0.181636;-0.809017;,
|
||||
0.345491;-0.475528;-0.809017;,
|
||||
-0.000000;-0.587785;-0.809017;,
|
||||
-0.345492;-0.475528;-0.809017;,
|
||||
-0.559017;-0.181635;-0.809017;,
|
||||
-0.559017;0.181636;-0.809017;,
|
||||
-0.345491;0.475528;-0.809017;,
|
||||
0.000000;0.309017;-0.951056;,
|
||||
0.181636;0.250000;-0.951056;,
|
||||
0.293893;0.095492;-0.951056;,
|
||||
0.293893;-0.095492;-0.951056;,
|
||||
0.181636;-0.250000;-0.951056;,
|
||||
-0.000000;-0.309017;-0.951056;,
|
||||
-0.181636;-0.250000;-0.951056;,
|
||||
-0.293893;-0.095491;-0.951056;,
|
||||
-0.293893;0.095492;-0.951056;,
|
||||
-0.181636;0.250000;-0.951056;,
|
||||
0.000000;0.000000;-1.000000;;
|
||||
180;
|
||||
3;0,2,1;,
|
||||
3;0,3,2;,
|
||||
3;0,4,3;,
|
||||
3;0,5,4;,
|
||||
3;0,6,5;,
|
||||
3;0,7,6;,
|
||||
3;0,8,7;,
|
||||
3;0,9,8;,
|
||||
3;0,10,9;,
|
||||
3;0,1,10;,
|
||||
3;1,2,11;,
|
||||
3;2,12,11;,
|
||||
3;2,3,12;,
|
||||
3;3,13,12;,
|
||||
3;3,4,13;,
|
||||
3;4,14,13;,
|
||||
3;4,5,14;,
|
||||
3;5,15,14;,
|
||||
3;5,6,15;,
|
||||
3;6,16,15;,
|
||||
3;6,7,16;,
|
||||
3;7,17,16;,
|
||||
3;7,8,17;,
|
||||
3;8,18,17;,
|
||||
3;8,9,18;,
|
||||
3;9,19,18;,
|
||||
3;9,10,19;,
|
||||
3;10,20,19;,
|
||||
3;10,1,20;,
|
||||
3;1,11,20;,
|
||||
3;11,12,21;,
|
||||
3;12,22,21;,
|
||||
3;12,13,22;,
|
||||
3;13,23,22;,
|
||||
3;13,14,23;,
|
||||
3;14,24,23;,
|
||||
3;14,15,24;,
|
||||
3;15,25,24;,
|
||||
3;15,16,25;,
|
||||
3;16,26,25;,
|
||||
3;16,17,26;,
|
||||
3;17,27,26;,
|
||||
3;17,18,27;,
|
||||
3;18,28,27;,
|
||||
3;18,19,28;,
|
||||
3;19,29,28;,
|
||||
3;19,20,29;,
|
||||
3;20,30,29;,
|
||||
3;20,11,30;,
|
||||
3;11,21,30;,
|
||||
3;21,22,31;,
|
||||
3;22,32,31;,
|
||||
3;22,23,32;,
|
||||
3;23,33,32;,
|
||||
3;23,24,33;,
|
||||
3;24,34,33;,
|
||||
3;24,25,34;,
|
||||
3;25,35,34;,
|
||||
3;25,26,35;,
|
||||
3;26,36,35;,
|
||||
3;26,27,36;,
|
||||
3;27,37,36;,
|
||||
3;27,28,37;,
|
||||
3;28,38,37;,
|
||||
3;28,29,38;,
|
||||
3;29,39,38;,
|
||||
3;29,30,39;,
|
||||
3;30,40,39;,
|
||||
3;30,21,40;,
|
||||
3;21,31,40;,
|
||||
3;31,32,41;,
|
||||
3;32,42,41;,
|
||||
3;32,33,42;,
|
||||
3;33,43,42;,
|
||||
3;33,34,43;,
|
||||
3;34,44,43;,
|
||||
3;34,35,44;,
|
||||
3;35,45,44;,
|
||||
3;35,36,45;,
|
||||
3;36,46,45;,
|
||||
3;36,37,46;,
|
||||
3;37,47,46;,
|
||||
3;37,38,47;,
|
||||
3;38,48,47;,
|
||||
3;38,39,48;,
|
||||
3;39,49,48;,
|
||||
3;39,40,49;,
|
||||
3;40,50,49;,
|
||||
3;40,31,50;,
|
||||
3;31,41,50;,
|
||||
3;41,42,51;,
|
||||
3;42,52,51;,
|
||||
3;42,43,52;,
|
||||
3;43,53,52;,
|
||||
3;43,44,53;,
|
||||
3;44,54,53;,
|
||||
3;44,45,54;,
|
||||
3;45,55,54;,
|
||||
3;45,46,55;,
|
||||
3;46,56,55;,
|
||||
3;46,47,56;,
|
||||
3;47,57,56;,
|
||||
3;47,48,57;,
|
||||
3;48,58,57;,
|
||||
3;48,49,58;,
|
||||
3;49,59,58;,
|
||||
3;49,50,59;,
|
||||
3;50,60,59;,
|
||||
3;50,41,60;,
|
||||
3;41,51,60;,
|
||||
3;51,52,61;,
|
||||
3;52,62,61;,
|
||||
3;52,53,62;,
|
||||
3;53,63,62;,
|
||||
3;53,54,63;,
|
||||
3;54,64,63;,
|
||||
3;54,55,64;,
|
||||
3;55,65,64;,
|
||||
3;55,56,65;,
|
||||
3;56,66,65;,
|
||||
3;56,57,66;,
|
||||
3;57,67,66;,
|
||||
3;57,58,67;,
|
||||
3;58,68,67;,
|
||||
3;58,59,68;,
|
||||
3;59,69,68;,
|
||||
3;59,60,69;,
|
||||
3;60,70,69;,
|
||||
3;60,51,70;,
|
||||
3;51,61,70;,
|
||||
3;61,62,71;,
|
||||
3;62,72,71;,
|
||||
3;62,63,72;,
|
||||
3;63,73,72;,
|
||||
3;63,64,73;,
|
||||
3;64,74,73;,
|
||||
3;64,65,74;,
|
||||
3;65,75,74;,
|
||||
3;65,66,75;,
|
||||
3;66,76,75;,
|
||||
3;66,67,76;,
|
||||
3;67,77,76;,
|
||||
3;67,68,77;,
|
||||
3;68,78,77;,
|
||||
3;68,69,78;,
|
||||
3;69,79,78;,
|
||||
3;69,70,79;,
|
||||
3;70,80,79;,
|
||||
3;70,61,80;,
|
||||
3;61,71,80;,
|
||||
3;71,72,81;,
|
||||
3;72,82,81;,
|
||||
3;72,73,82;,
|
||||
3;73,83,82;,
|
||||
3;73,74,83;,
|
||||
3;74,84,83;,
|
||||
3;74,75,84;,
|
||||
3;75,85,84;,
|
||||
3;75,76,85;,
|
||||
3;76,86,85;,
|
||||
3;76,77,86;,
|
||||
3;77,87,86;,
|
||||
3;77,78,87;,
|
||||
3;78,88,87;,
|
||||
3;78,79,88;,
|
||||
3;79,89,88;,
|
||||
3;79,80,89;,
|
||||
3;80,90,89;,
|
||||
3;80,71,90;,
|
||||
3;71,81,90;,
|
||||
3;81,82,91;,
|
||||
3;82,83,91;,
|
||||
3;83,84,91;,
|
||||
3;84,85,91;,
|
||||
3;85,86,91;,
|
||||
3;86,87,91;,
|
||||
3;87,88,91;,
|
||||
3;88,89,91;,
|
||||
3;89,90,91;,
|
||||
3;90,81,91;;
|
||||
}
|
||||
|
||||
MeshMaterialList {
|
||||
1;
|
||||
180;
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0;
|
||||
|
||||
Material {
|
||||
0.500000;0.500000;0.500000;0.000000;;
|
||||
0.000000;
|
||||
0.500000;0.500000;0.500000;;
|
||||
0.000000;0.000000;0.000000;;
|
||||
}
|
||||
}
|
||||
|
||||
VertexDuplicationIndices {
|
||||
92;
|
||||
92;
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
60,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
64,
|
||||
65,
|
||||
66,
|
||||
67,
|
||||
68,
|
||||
69,
|
||||
70,
|
||||
71,
|
||||
72,
|
||||
73,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
82,
|
||||
83,
|
||||
84,
|
||||
85,
|
||||
86,
|
||||
87,
|
||||
88,
|
||||
89,
|
||||
90,
|
||||
91;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Storage;
|
||||
#endregion
|
||||
using XnaDevRu.BulletX;
|
||||
using XnaDevRu.BulletX.Dynamics;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos.Basic
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the main type for your game
|
||||
/// </summary>
|
||||
public class BasicDemo : XnaDevRu.BulletX.Demos.DemoGame
|
||||
{
|
||||
public BasicDemo()
|
||||
{
|
||||
SphereBoxCollisionAlgorithm.CreateFunc boxAlgo = new SphereBoxCollisionAlgorithm.CreateFunc();
|
||||
boxAlgo.IsSwapped = true;
|
||||
CollisionDispatcher.RegisterCollisionCreateFunc(BroadphaseNativeTypes.Sphere, BroadphaseNativeTypes.Sphere, new SphereSphereCollisionAlgorithm.CreateFunc());
|
||||
CollisionDispatcher.RegisterCollisionCreateFunc(BroadphaseNativeTypes.Sphere, BroadphaseNativeTypes.Box, new SphereBoxCollisionAlgorithm.CreateFunc());
|
||||
CollisionDispatcher.RegisterCollisionCreateFunc(BroadphaseNativeTypes.Box, BroadphaseNativeTypes.Sphere, boxAlgo);
|
||||
|
||||
Shapes[0] = new SphereShape(50);
|
||||
Shapes[2] = new SphereShape(HalfExtents - CollisionMargin);
|
||||
|
||||
Matrix tr = Matrix.Identity;
|
||||
tr.Translation = new Vector3(0, -50, 0);
|
||||
CreateRigidBody(0, tr, Shapes[0]);
|
||||
|
||||
for (int i = 0; i < NumObjects; i++)
|
||||
{
|
||||
Shapes[2].Margin = CollisionMargin;
|
||||
int colsize = 2;
|
||||
int row = (int)((i * HalfExtents * 2) / (colsize * 2 * HalfExtents));
|
||||
int row2 = row;
|
||||
int col = i % colsize - colsize / 2;
|
||||
tr.Translation = new Vector3(col * 2 * HalfExtents + (row2 % 2) * HalfExtents,
|
||||
row * 2 * HalfExtents + HalfExtents, 0);
|
||||
|
||||
CreateRigidBody(1, tr, Shapes[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos.Basic
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
static void Main(string[] args)
|
||||
{
|
||||
using (BasicDemo game = new BasicDemo())
|
||||
{
|
||||
game.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos.Basic")]
|
||||
[assembly: AssemblyProduct("Bullet for XNA")]
|
||||
[assembly: AssemblyDescription("Bullet for XNA Basic Demo")]
|
||||
[assembly: AssemblyCompany("XNADev.ru")]
|
||||
|
||||
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("dd847e80-8cf8-4c43-91cd-524301838768")]
|
||||
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.149.21894")]
|
||||
@@ -1,97 +0,0 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{72384342-889C-47B0-B98E-C855D1CE0F41}</ProjectGuid>
|
||||
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>XnaDevRu.BulletX.Demos.Basic</RootNamespace>
|
||||
<AssemblyName>Basic</AssemblyName>
|
||||
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
|
||||
<XnaPlatform>Windows</XnaPlatform>
|
||||
<ApplicationIcon>..\..\..\SharedContent\bullet_ico.ico</ApplicationIcon>
|
||||
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
|
||||
<XNAProjectContentPipelineAssemblies>
|
||||
</XNAProjectContentPipelineAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Debug\Demos\BulletX\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Release\Demos\BulletX\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Xna.Framework">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Game">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Program.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>Program</Name>
|
||||
</Compile>
|
||||
<Compile Include="BasicDemo.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>BasicDemo</Name>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\..\SharedContent\bullet_ico.ico">
|
||||
<Link>bullet_ico.ico</Link>
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>bullet_ico</Name>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX.Demos\XnaDevRu.BulletX.Demos.csproj">
|
||||
<Project>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</Project>
|
||||
<Name>XnaDevRu.BulletX.Demos</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
|
||||
<Project>{5BEE189F-47A1-42A8-A297-1960221BE20D}</Project>
|
||||
<Name>XnaDevRu.BulletX</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Storage;
|
||||
#endregion
|
||||
using XnaDevRu.BulletX;
|
||||
using XnaDevRu.BulletX.Dynamics;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos.Ccd
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the main type for your game
|
||||
/// </summary>
|
||||
public class CcdDemo : XnaDevRu.BulletX.Demos.DemoGame
|
||||
{
|
||||
public CcdDemo()
|
||||
{
|
||||
NumObjects = 120;
|
||||
|
||||
Shapes[0] = new BoxShape(new Vector3(200, 10, 200));
|
||||
|
||||
for (int i = 0; i < NumObjects; i++)
|
||||
{
|
||||
CollisionShape shape = Shapes[ShapeIndex[i]];
|
||||
shape.Margin = CollisionMargin;
|
||||
|
||||
bool isDynamic = i > 0;
|
||||
|
||||
Matrix trans = Matrix.Identity;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
//stack them
|
||||
int colsize = 10;
|
||||
int row = (i * HalfExtents * 2) / (colsize * 2 * HalfExtents);
|
||||
int row2 = row;
|
||||
int col = (i) % (colsize) - colsize / 2;
|
||||
|
||||
if (col > 3)
|
||||
{
|
||||
col = 11;
|
||||
row2 |= 1;
|
||||
}
|
||||
|
||||
Vector3 pos;
|
||||
if (NumObjects > 2)
|
||||
{
|
||||
pos = new Vector3(col * 2 * HalfExtents + (row2 % 2) * HalfExtents,
|
||||
row * 2 * HalfExtents + HalfExtents + ExtraHeight, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = new Vector3(0, -30, 0);
|
||||
}
|
||||
|
||||
if (shape is BoxShape)
|
||||
{
|
||||
trans.Right = new Vector3(0, -1, 0);
|
||||
trans.Up = new Vector3(1, 0, 0);
|
||||
trans.Backward = new Vector3(0, 0, 1);
|
||||
}
|
||||
|
||||
trans *= Matrix.CreateRotationZ(Microsoft.Xna.Framework.MathHelper.PiOver2);
|
||||
trans.Translation = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
trans.Translation = new Vector3(0, -30, 0);
|
||||
}
|
||||
|
||||
float mass = 1.0f;
|
||||
if (!isDynamic)
|
||||
mass = 0.0f;
|
||||
|
||||
RigidBody body = CreateRigidBody(mass, trans, shape);
|
||||
|
||||
body.CcdSquareMotionThreshold = HalfExtents;
|
||||
body.CcdSweptSphereRadius = 0.2f * HalfExtents;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos.Ccd
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
static void Main(string[] args)
|
||||
{
|
||||
using (CcdDemo game = new CcdDemo())
|
||||
{
|
||||
game.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos.Ccd")]
|
||||
[assembly: AssemblyProduct("Bullet for XNA")]
|
||||
[assembly: AssemblyDescription("Bullet for XNA CCD Demo")]
|
||||
[assembly: AssemblyCompany("XNADev.ru")]
|
||||
|
||||
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("58969560-d588-4200-a57e-2f312cdf6a18")]
|
||||
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.149.21894")]
|
||||
@@ -1,93 +0,0 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{705FCCF1-44C8-430E-92A9-9987CD3D6A64}</ProjectGuid>
|
||||
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>XnaDevRu.BulletX.Demos.Ccd</RootNamespace>
|
||||
<AssemblyName>Ccd</AssemblyName>
|
||||
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
|
||||
<XnaPlatform>Windows</XnaPlatform>
|
||||
<ApplicationIcon>..\..\..\SharedContent\bullet_ico.ico</ApplicationIcon>
|
||||
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
|
||||
<XNAProjectContentPipelineAssemblies>
|
||||
</XNAProjectContentPipelineAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Debug\Demos\BulletX\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Release\Demos\BulletX\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Xna.Framework">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Game">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CcdDemo.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>CcdDemo</Name>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Program.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>Program</Name>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX.Demos\XnaDevRu.BulletX.Demos.csproj">
|
||||
<Project>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</Project>
|
||||
<Name>XnaDevRu.BulletX.Demos</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
|
||||
<Project>{EBC5D108-65E5-4F8E-B3F2-BF7EE56C27F3}</Project>
|
||||
<Name>XnaDevRu.BulletX</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\..\SharedContent\bullet_ico.ico">
|
||||
<Link>bullet_ico.ico</Link>
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>bullet_ico</Name>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Storage;
|
||||
#endregion
|
||||
using XnaDevRu.BulletX;
|
||||
using XnaDevRu.BulletX.Dynamics;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos.Constraints
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the main type for your game
|
||||
/// </summary>
|
||||
public class ConstraintDemo : XnaDevRu.BulletX.Demos.DemoGame
|
||||
{
|
||||
Matrix _sliderTransform;
|
||||
Vector3 _lowerSliderLimit = new Vector3(-10, 0, 0);
|
||||
Vector3 _hiSliderLimit = new Vector3(10, 0, 0);
|
||||
|
||||
RigidBody _d6BodyA = null;
|
||||
|
||||
public ConstraintDemo()
|
||||
{
|
||||
CollisionShape shape = new BoxShape(new Vector3(HalfExtents, HalfExtents, HalfExtents));
|
||||
Matrix trans = Matrix.Identity;
|
||||
trans.Translation = new Vector3(0, 20, 0);
|
||||
|
||||
float mass = 1f;
|
||||
//Point to Point constraint (ball socket)
|
||||
{
|
||||
RigidBody bodyA = CreateRigidBody(mass, trans, shape);
|
||||
trans.Translation = new Vector3(2 * HalfExtents, 20, 0);
|
||||
|
||||
mass = 1f;
|
||||
RigidBody bodyB = null;
|
||||
//RigidBody bodyB = CreateRigidBody(mass, trans, shape);
|
||||
//bodyB.ActivationState = ActivationState.DisableDeactivation;
|
||||
//bodyB.SetDamping(0.3f, 0.3f);
|
||||
|
||||
Vector3 pivotInA = new Vector3(HalfExtents, -HalfExtents, -HalfExtents);
|
||||
Vector3 axisInA = new Vector3(0, 0, 1);
|
||||
|
||||
Vector3 pivotInB = bodyB != null ? MathHelper.MatrixToVector(MathHelper.InvertMatrix(bodyB.CenterOfMassTransform), MathHelper.MatrixToVector(bodyA.CenterOfMassTransform, pivotInA)) : pivotInA;
|
||||
Vector3 axisInB = bodyB != null ?
|
||||
Vector3.TransformNormal(Vector3.TransformNormal(axisInA, bodyB.CenterOfMassTransform), MathHelper.InvertMatrix(bodyB.CenterOfMassTransform)) :
|
||||
Vector3.TransformNormal(axisInA, bodyA.CenterOfMassTransform);
|
||||
|
||||
//TypedConstraint p2p = new Point2PointConstraint(bodyA, bodyB, pivotInA, pivotInB);
|
||||
//TypedConstraint hinge = new HingeConstraint(bodyA, bodyB, pivotInA, pivotInB, axisInA, axisInB);
|
||||
HingeConstraint hinge = new HingeConstraint(bodyA, pivotInA, axisInA);
|
||||
|
||||
//use zero targetVelocity and a small maxMotorImpulse to simulate joint friction
|
||||
//float targetVelocity = 0.0f;
|
||||
//float maxMotorImpulse = 0.01;
|
||||
float targetVelocity = 1.0f;
|
||||
float maxMotorImpulse = 1.0f;
|
||||
hinge.EnableAngularMotor(true, targetVelocity, maxMotorImpulse);
|
||||
|
||||
PhysicsWorld.AddConstraint(hinge);
|
||||
}
|
||||
|
||||
// create a slider, using the generic D6 constraint
|
||||
{
|
||||
mass = 1f;
|
||||
Vector3 sliderWorldPos = new Vector3(0, 10, 0);
|
||||
Vector3 sliderAxis = new Vector3(1, 0, 0);
|
||||
float angle = 0;
|
||||
Matrix sliderOrientation = Matrix.CreateFromQuaternion(new Quaternion(sliderAxis, angle));
|
||||
|
||||
trans = Matrix.Identity;
|
||||
trans.Translation = sliderWorldPos;
|
||||
//trans.setBasis(sliderOrientation);
|
||||
_sliderTransform = trans;
|
||||
|
||||
_d6BodyA = CreateRigidBody(mass, trans, shape);
|
||||
_d6BodyA.ActivationState = ActivationState.DisableDeactivation;
|
||||
RigidBody fixedBody1 = CreateRigidBody(0, trans, null);
|
||||
|
||||
Matrix frameInA, frameInB;
|
||||
frameInA = Matrix.Identity;
|
||||
frameInB = Matrix.Identity;
|
||||
|
||||
Generic6DofConstraint slider = new Generic6DofConstraint(_d6BodyA, fixedBody1, frameInA, frameInB);
|
||||
slider.SetLinearLowerLimit(_lowerSliderLimit);
|
||||
slider.SetLinearUpperLimit(_hiSliderLimit);
|
||||
|
||||
//range should be small, otherwise singularities will 'explode' the constraint
|
||||
slider.SetAngularLowerLimit(new Vector3(10, 0, 0));
|
||||
slider.SetAngularUpperLimit(new Vector3(0, 0, 0));
|
||||
|
||||
PhysicsWorld.AddConstraint(slider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos.Constraints
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
static void Main(string[] args)
|
||||
{
|
||||
using (ConstraintDemo game = new ConstraintDemo())
|
||||
{
|
||||
game.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos.Constraints")]
|
||||
[assembly: AssemblyProduct("Bullet for XNA")]
|
||||
[assembly: AssemblyDescription("Bullet for XNA Constraint Demo")]
|
||||
[assembly: AssemblyCompany("XNADev.ru")]
|
||||
|
||||
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("1c75580e-8bd8-47cd-8124-0e0054125840")]
|
||||
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.149.21894")]
|
||||
@@ -1,93 +0,0 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{77ABF9BD-E838-4EF0-BD76-C656C62BC517}</ProjectGuid>
|
||||
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>XnaDevRu.BulletX.Demos.Constraints</RootNamespace>
|
||||
<AssemblyName>Constraints</AssemblyName>
|
||||
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
|
||||
<XnaPlatform>Windows</XnaPlatform>
|
||||
<ApplicationIcon>..\..\..\SharedContent\bullet_ico.ico</ApplicationIcon>
|
||||
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
|
||||
<XNAProjectContentPipelineAssemblies>
|
||||
</XNAProjectContentPipelineAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Debug\Demos\BulletX\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Release\Demos\BulletX\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Xna.Framework">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Game">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ConstraintDemo.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>ConstraintDemo</Name>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Program.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>Program</Name>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX.Demos\XnaDevRu.BulletX.Demos.csproj">
|
||||
<Project>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</Project>
|
||||
<Name>XnaDevRu.BulletX.Demos</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
|
||||
<Project>{EBC5D108-65E5-4F8E-B3F2-BF7EE56C27F3}</Project>
|
||||
<Name>XnaDevRu.BulletX</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\..\SharedContent\bullet_ico.ico">
|
||||
<Link>bullet_ico.ico</Link>
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>bullet_ico</Name>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
Binary file not shown.
@@ -1,589 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#region Using Statements
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Storage;
|
||||
#endregion
|
||||
using XnaDevRu.Demos;
|
||||
using XnaDevRu.BulletX;
|
||||
using XnaDevRu.BulletX.Dynamics;
|
||||
|
||||
namespace XnaDevRu.BulletX.Demos
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the main type for your BulletX Demo.
|
||||
/// </summary>
|
||||
public class DemoGame : Microsoft.Xna.Framework.Game
|
||||
{
|
||||
// Main elements
|
||||
private GraphicsDeviceManager _graphics;
|
||||
private ContentManager _content;
|
||||
|
||||
// Components
|
||||
private Camera _camera;
|
||||
private Framerate _fps;
|
||||
|
||||
private MouseState _prevMouseState;
|
||||
|
||||
// Picking
|
||||
private TypedConstraint _pickConstraint;
|
||||
private Vector3 _oldPickingPos;
|
||||
private float _oldPickingDist = 0f;
|
||||
private RigidBody _pickedBody = null; //for deactivation state
|
||||
|
||||
//Physics
|
||||
private CollisionDispatcher _collisionDispatcher;
|
||||
private OverlappingPairCache _broadphase;
|
||||
private SequentialImpulseConstraintSolver _solver;
|
||||
private DiscreteDynamicsWorld _world;
|
||||
private CollisionShape[] _shapePtr;
|
||||
|
||||
private const int _maxNumObjects = 32760;
|
||||
private int _numObjects = 120;
|
||||
private const int _cubeHalfExtent = 1;
|
||||
private const int _extraHeight = -20;
|
||||
private const float _collisionMargin = 0.05f;
|
||||
private float _shootBoxInitialSpeed = 50f;
|
||||
private int[] _shapeIndex;
|
||||
private Model _modelBox;
|
||||
private Model _modelSphere;
|
||||
private Model _modelCylinder;
|
||||
|
||||
private bool _useDebugDrawer;
|
||||
private bool _useSweepAndPrune = true;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes new Demo testbed.
|
||||
/// </summary>
|
||||
public DemoGame()
|
||||
{
|
||||
_graphics = new GraphicsDeviceManager(this);
|
||||
_content = new ContentManager(Services);
|
||||
//graphics.SynchronizeWithVerticalRetrace = false;
|
||||
|
||||
IsMouseVisible = true;
|
||||
_camera = new Camera(this);
|
||||
_fps = new Framerate(this);
|
||||
_fps.UpdateFrequency = 100;
|
||||
Components.Add(_camera);
|
||||
Components.Add(_fps);
|
||||
|
||||
ResetPhysics();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets graphics device manager associated with this demo.
|
||||
/// </summary>
|
||||
public GraphicsDeviceManager Graphics { get { return _graphics; } }
|
||||
/// <summary>
|
||||
/// Gets content manager associated with this demo.
|
||||
/// </summary>
|
||||
public ContentManager Content { get { return _content; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets camera component associated with this demo.
|
||||
/// </summary>
|
||||
public Camera Camera { get { return _camera; } }
|
||||
/// <summary>
|
||||
/// Gets framerate component associated with this demo.
|
||||
/// </summary>
|
||||
public Framerate Fps { get { return _fps; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current collision dispatcher.
|
||||
/// </summary>
|
||||
public CollisionDispatcher CollisionDispatcher { get { return _collisionDispatcher; } set { _collisionDispatcher = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets current overlapping pair cache.
|
||||
/// </summary>
|
||||
public OverlappingPairCache Broadphase { get { return _broadphase; } set { _broadphase = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets current sequential impulse constraint solver.
|
||||
/// </summary>
|
||||
public SequentialImpulseConstraintSolver Solver { get { return _solver; } set { _solver = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets current dynamics world.
|
||||
/// </summary>
|
||||
public DiscreteDynamicsWorld PhysicsWorld { get { return _world; } set { _world = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets predefined shape array.
|
||||
/// </summary>
|
||||
public CollisionShape[] Shapes { get { return _shapePtr; } set { _shapePtr = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets max number of objects in the simulation.
|
||||
/// </summary>
|
||||
public int MaxNumObjects { get { return _maxNumObjects; } }
|
||||
/// <summary>
|
||||
/// Gets or sets starting objects count in simulation.
|
||||
/// </summary>
|
||||
public int NumObjects { get { return _numObjects; } set { _numObjects = value; } }
|
||||
/// <summary>
|
||||
/// Gets half extents.
|
||||
/// </summary>
|
||||
public int HalfExtents { get { return _cubeHalfExtent; } }
|
||||
/// <summary>
|
||||
/// Gets extra height.
|
||||
/// </summary>
|
||||
public int ExtraHeight { get { return _extraHeight; } }
|
||||
/// <summary>
|
||||
/// Gets collision margin.
|
||||
/// </summary>
|
||||
public float CollisionMargin { get { return _collisionMargin; } }
|
||||
/// <summary>
|
||||
/// Gets or sets initial box speed when shot.
|
||||
/// </summary>
|
||||
public float ShootBoxInitialSpeed { get { return _shootBoxInitialSpeed; } set { _shootBoxInitialSpeed = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets predefined shape index reference for simulated objects.
|
||||
/// </summary>
|
||||
public int[] ShapeIndex { get { return _shapeIndex; } set { _shapeIndex = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets box model.
|
||||
/// </summary>
|
||||
public Model ModelBox { get { return _modelBox; } set { _modelBox = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets sphere model.
|
||||
/// </summary>
|
||||
public Model ModelSphere { get { return _modelSphere; } set { _modelSphere = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets cylinder model.
|
||||
/// </summary>
|
||||
public Model ModelCylinder { get { return _modelCylinder; } set { _modelCylinder = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ability to draw debug information.
|
||||
/// </summary>
|
||||
public bool UseDebugDrawer { get { return _useDebugDrawer; } set { _useDebugDrawer = value; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the sweep and prune for broadphase.
|
||||
/// </summary>
|
||||
public bool UseSweepAndPrune { get { return _useSweepAndPrune; } set { _useSweepAndPrune = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Reinitializes physics.
|
||||
/// </summary>
|
||||
public void ResetPhysics()
|
||||
{
|
||||
_collisionDispatcher = new CollisionDispatcher();
|
||||
|
||||
if (_useSweepAndPrune)
|
||||
{
|
||||
Vector3 worldAabbMin = new Vector3(-10000, -10000, -10000);
|
||||
Vector3 worldAabbMax = new Vector3(10000, 10000, 10000);
|
||||
const int maxProxies = 32766;
|
||||
_broadphase = new AxisSweep3(worldAabbMin, worldAabbMax, maxProxies);
|
||||
}
|
||||
else
|
||||
_broadphase = new SimpleBroadphase();
|
||||
|
||||
_solver = new SequentialImpulseConstraintSolver();
|
||||
_world = new DiscreteDynamicsWorld(_collisionDispatcher, _broadphase, _solver);
|
||||
|
||||
//world.setConstraintSolver(solver);
|
||||
_world.Gravity = new Vector3(0, -10, 0);
|
||||
|
||||
_shapePtr = new CollisionShape[4];
|
||||
_shapePtr[0] = new BoxShape(new Vector3(50, 10, 50));
|
||||
_shapePtr[1] = new CylinderShape(new Vector3(_cubeHalfExtent - _collisionMargin, _cubeHalfExtent - _collisionMargin, _cubeHalfExtent - _collisionMargin));
|
||||
_shapePtr[2] = new SphereShape(_cubeHalfExtent);
|
||||
_shapePtr[3] = new BoxShape(new Vector3(_cubeHalfExtent, _cubeHalfExtent, _cubeHalfExtent));
|
||||
|
||||
_shapeIndex = new int[_maxNumObjects];
|
||||
Matrix tr = Matrix.Identity;
|
||||
|
||||
for (int i = 0; i < _numObjects; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
// set shape
|
||||
_shapeIndex[i] = 1;
|
||||
else
|
||||
_shapeIndex[i] = 0;
|
||||
}
|
||||
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new rigid body and adds it to the world.
|
||||
/// </summary>
|
||||
/// <param name="mass">Body mass, if 0 body is static.</param>
|
||||
/// <param name="startTransform">Starting body transform.</param>
|
||||
/// <param name="shape">Body shape.</param>
|
||||
/// <returns>Created rigid body.</returns>
|
||||
public RigidBody CreateRigidBody(float mass, Matrix startTransform, CollisionShape shape)
|
||||
{
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.0f);
|
||||
|
||||
Vector3 localInertia = new Vector3();
|
||||
if (isDynamic)
|
||||
shape.CalculateLocalInertia(mass, out localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
|
||||
DefaultMotionState myMotionState = new DefaultMotionState(startTransform, Matrix.Identity);
|
||||
RigidBody body = new RigidBody(mass, myMotionState, shape, localInertia, 0.0f, 0.0f, 0.5f, 0.0f);
|
||||
|
||||
_world.AddRigidBody(body);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after the Game and Graphics.GraphicsDevice are created, but before Game.LoadGraphicsContent.
|
||||
/// </summary>
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_camera.Position = new Vector3(0, 3, 75);
|
||||
_camera.Target = new Vector3(0, 0, 0);
|
||||
|
||||
if (_useDebugDrawer)
|
||||
{
|
||||
XnaDebugDraw dbg = new XnaDebugDraw(_graphics.GraphicsDevice);
|
||||
dbg.DebugMode = DebugDrawModes.DrawAabb | DebugDrawModes.DrawContactPoints;
|
||||
_world.DebugDrawer = dbg;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads graphics content needed by this demo.
|
||||
/// </summary>
|
||||
/// <param name="loadAllContent">If need to reload all content.</param>
|
||||
protected override void LoadGraphicsContent(bool loadAllContent)
|
||||
{
|
||||
if (loadAllContent)
|
||||
{
|
||||
_modelBox = _content.Load<Model>("content\\box");
|
||||
_modelSphere = _content.Load<Model>("content\\sphere");
|
||||
_modelCylinder = _content.Load<Model>("content\\cylinder");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads graphics content needed by this demo.
|
||||
/// </summary>
|
||||
/// <param name="unloadAllContent">If need to unload all content.</param>
|
||||
protected override void UnloadGraphicsContent(bool unloadAllContent)
|
||||
{
|
||||
if (unloadAllContent == true)
|
||||
{
|
||||
_content.Unload();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the game has determined that game logic needs to be processed.
|
||||
/// </summary>
|
||||
/// <param name="gameTime">Time passed since the last call to this function.</param>
|
||||
protected override void Update(GameTime gameTime)
|
||||
{
|
||||
MouseState mouseState = Mouse.GetState();
|
||||
Vector3 rayTo = getRayTo(mouseState.X, mouseState.Y);
|
||||
|
||||
if (mouseState.LeftButton == ButtonState.Pressed && _prevMouseState.LeftButton == ButtonState.Released)
|
||||
{
|
||||
shootBox(rayTo);
|
||||
}
|
||||
if (mouseState.MiddleButton == ButtonState.Pressed && _prevMouseState.MiddleButton == ButtonState.Released)
|
||||
{
|
||||
if (_world != null)
|
||||
{
|
||||
CollisionWorld.ClosestRayResultCallback rayCallback = new CollisionWorld.ClosestRayResultCallback(_camera.Position, rayTo);
|
||||
_world.RayTest(_camera.Position, rayTo, rayCallback);
|
||||
if (rayCallback.HasHit)
|
||||
{
|
||||
RigidBody body = RigidBody.Upcast(rayCallback.CollisionObject);
|
||||
if (body != null)
|
||||
{
|
||||
//other exclusions?
|
||||
if (!(body.IsStaticObject || body.IsKinematicObject))
|
||||
{
|
||||
_pickedBody = body;
|
||||
_pickedBody.ActivationState = ActivationState.DisableDeactivation;
|
||||
|
||||
Vector3 pickPos = rayCallback.HitPointWorld;
|
||||
|
||||
Vector3 localPivot = Vector3.Transform(pickPos, XnaDevRu.BulletX.MathHelper.InvertMatrix(body.CenterOfMassTransform));
|
||||
|
||||
Point2PointConstraint p2p = new Point2PointConstraint(body, localPivot);
|
||||
_world.AddConstraint(p2p);
|
||||
_pickConstraint = p2p;
|
||||
|
||||
//save mouse position for dragging
|
||||
_oldPickingPos = rayTo;
|
||||
|
||||
Vector3 eyePos = new Vector3(_camera.Position.X, _camera.Position.Y, _camera.Position.Z);
|
||||
|
||||
_oldPickingDist = (eyePos - pickPos).Length();
|
||||
|
||||
//very weak constraint for picking
|
||||
p2p.Settings.Tau = 1.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mouseState.MiddleButton == ButtonState.Released && _prevMouseState.MiddleButton == ButtonState.Pressed)
|
||||
{
|
||||
if (_pickConstraint != null && _world != null)
|
||||
{
|
||||
_world.RemoveConstraint(_pickConstraint);
|
||||
_pickConstraint = null;
|
||||
_pickedBody.ForceActivationState(ActivationState.Active);
|
||||
_pickedBody.DeactivationTime = 0f;
|
||||
_pickedBody = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (_pickConstraint != null)
|
||||
{
|
||||
//move the constraint pivot
|
||||
Point2PointConstraint p2p = _pickConstraint as Point2PointConstraint;
|
||||
if (p2p != null)
|
||||
{
|
||||
//keep it at the same picking distance
|
||||
Vector3 dir = rayTo - _camera.Position;
|
||||
dir.Normalize();
|
||||
dir *= _oldPickingDist;
|
||||
|
||||
Vector3 newPos = _camera.Position + dir;
|
||||
p2p.PivotInB = newPos;
|
||||
}
|
||||
}
|
||||
|
||||
_prevMouseState = mouseState;
|
||||
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.Space))
|
||||
{
|
||||
//world.stepSimulation(1.0f/60.0f,0);
|
||||
int numObjects = _world.CollisionObjectsCount;
|
||||
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
CollisionObject colObj = _world.CollisionObjects[i];
|
||||
RigidBody body = RigidBody.Upcast(colObj);
|
||||
if (body != null)
|
||||
{
|
||||
if (body.MotionState != null)
|
||||
{
|
||||
DefaultMotionState myMotionState = (DefaultMotionState)body.MotionState;
|
||||
myMotionState.GraphicsWorldTransform = myMotionState.StartWorldTransform;
|
||||
colObj.WorldTransform = myMotionState.GraphicsWorldTransform;
|
||||
colObj.InterpolationWorldTransform = myMotionState.StartWorldTransform;
|
||||
colObj.Activate();
|
||||
}
|
||||
|
||||
//removed cached contact points
|
||||
_world.Broadphase.CleanProxyFromPairs(colObj.Broadphase);
|
||||
|
||||
if (body != null && !body.IsStaticObject)
|
||||
{
|
||||
RigidBody.Upcast(colObj).LinearVelocity = new Vector3(0, 0, 0);
|
||||
RigidBody.Upcast(colObj).AngularVelocity = new Vector3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Keyboard.GetState().IsKeyDown(Keys.Escape) || GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
//world.stepSimulation(1.0f / 60.0f, 1);
|
||||
}
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the gamedetermines it is time to draw a frame.
|
||||
/// </summary>
|
||||
/// <param name="gameTime">Time passed since the last call to this function.</param>
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
_graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||
|
||||
if (_useDebugDrawer)
|
||||
((XnaDebugDraw)_world.DebugDrawer).Update(_camera.View, _camera.Projection);
|
||||
|
||||
_world.StepSimulation(1.0f / 60.0f, 1);
|
||||
|
||||
Matrix objMatrix;
|
||||
|
||||
if (_world != null)
|
||||
{
|
||||
int numObjects = _world.CollisionObjectsCount;
|
||||
Vector3 wireColor = Vector3.UnitX;
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
CollisionObject colObj = _world.CollisionObjects[i];
|
||||
RigidBody body = RigidBody.Upcast(colObj);
|
||||
|
||||
if (body != null && body.MotionState != null)
|
||||
{
|
||||
DefaultMotionState myMotionState = (DefaultMotionState)body.MotionState;
|
||||
objMatrix = myMotionState.GraphicsWorldTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
objMatrix = colObj.WorldTransform;
|
||||
}
|
||||
|
||||
wireColor = new Vector3(1.0f, 1.0f, 0.5f); //wants deactivation
|
||||
if ((i & 1) == 1)
|
||||
{
|
||||
wireColor = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
//color differently for active, sleeping, wantsdeactivation states
|
||||
if (colObj.ActivationState == ActivationState.Active)
|
||||
{
|
||||
if ((i & 1) == 1)
|
||||
{
|
||||
wireColor += new Vector3(1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
wireColor += new Vector3(0.5f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (colObj.ActivationState == ActivationState.IslandSleeping)
|
||||
{
|
||||
if ((i & 1) == 1)
|
||||
{
|
||||
wireColor += new Vector3(0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
wireColor += new Vector3(0.0f, 0.5f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// draw box
|
||||
objMatrix = XnaDevRu.BulletX.MathHelper.GetDisplayMatrix(objMatrix);
|
||||
|
||||
if (i == 0)
|
||||
wireColor = Vector3.Zero;
|
||||
|
||||
DrawModel(objMatrix, wireColor, colObj);
|
||||
}
|
||||
}
|
||||
|
||||
base.Draw(gameTime);
|
||||
}
|
||||
|
||||
private void DrawModel(Matrix modelTransform, Vector3 color, CollisionObject obj)
|
||||
{
|
||||
Model model = _modelBox;
|
||||
Matrix scale = Matrix.Identity;
|
||||
|
||||
if (obj.CollisionShape is CylinderShape)
|
||||
{
|
||||
CylinderShape cylinderShape = (CylinderShape)obj.CollisionShape;
|
||||
Vector3 halfExtent = cylinderShape.HalfExtents;
|
||||
scale = Matrix.CreateScale(halfExtent.X + _collisionMargin, halfExtent.Y + _collisionMargin, halfExtent.Z / 2 + _collisionMargin * 3.5f) * Matrix.CreateRotationX((float)Math.PI / 2);
|
||||
model = _modelCylinder;
|
||||
}
|
||||
else if (obj.CollisionShape is BoxShape)
|
||||
{
|
||||
BoxShape boxShape = (BoxShape)obj.CollisionShape;
|
||||
Vector3 halfExtent = boxShape.HalfExtents;
|
||||
scale = Matrix.CreateScale(2 * halfExtent.X, 2 * halfExtent.Y, 2 * halfExtent.Z);
|
||||
model = _modelBox;
|
||||
}
|
||||
else if (obj.CollisionShape is SphereShape)
|
||||
{
|
||||
SphereShape sphereShape = (SphereShape)obj.CollisionShape;
|
||||
float radius = sphereShape.Radius;
|
||||
scale = Matrix.CreateScale(radius, radius, radius);
|
||||
model = _modelSphere;
|
||||
}
|
||||
|
||||
Matrix[] transforms = new Matrix[model.Bones.Count];
|
||||
model.CopyAbsoluteBoneTransformsTo(transforms);
|
||||
|
||||
foreach (ModelMesh mesh in model.Meshes)
|
||||
{
|
||||
foreach (BasicEffect effect in mesh.Effects)
|
||||
{
|
||||
effect.EnableDefaultLighting();
|
||||
effect.PreferPerPixelLighting = true;
|
||||
effect.AmbientLightColor = color;
|
||||
|
||||
effect.View = _camera.View;
|
||||
effect.Projection = _camera.Projection;
|
||||
effect.World = transforms[mesh.ParentBone.Index] * scale * modelTransform;
|
||||
}
|
||||
mesh.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
private void shootBox(Vector3 destination)
|
||||
{
|
||||
if (_world != null)
|
||||
{
|
||||
float mass = 1f;
|
||||
Matrix startTransform = Matrix.Identity;
|
||||
Vector3 camPos = _camera.Position;
|
||||
startTransform.Translation = camPos;
|
||||
//CollisionShape boxShape = new SphereShape(1);
|
||||
CollisionShape boxShape = new BoxShape(Vector3.One);
|
||||
RigidBody body = CreateRigidBody(mass, startTransform, boxShape);
|
||||
|
||||
Vector3 linVel = new Vector3(destination.X - camPos.X, destination.Y - camPos.Y, destination.Z - camPos.Z);
|
||||
linVel.Normalize();
|
||||
linVel *= _shootBoxInitialSpeed;
|
||||
|
||||
//body.getWorldTransform().setOrigin(camPos);
|
||||
//body.getWorldTransform().setRotation(btQuaternion(0, 0, 0, 1));
|
||||
body.LinearVelocity = linVel;
|
||||
body.AngularVelocity = Vector3.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 getRayTo(int x, int y)
|
||||
{
|
||||
Vector3 nearSource = new Vector3(x, y, 0);
|
||||
Vector3 farSource = new Vector3(x, y, 1);
|
||||
|
||||
Matrix world = Matrix.CreateTranslation(0, 0, 0);
|
||||
|
||||
Vector3 nearPoint = Graphics.GraphicsDevice.Viewport.Unproject(nearSource, Camera.Projection, Camera.View, world);
|
||||
Vector3 farPoint = Graphics.GraphicsDevice.Viewport.Unproject(farSource, Camera.Projection, Camera.View, world);
|
||||
|
||||
Vector3 direction = farPoint - nearPoint;
|
||||
//direction.Normalize();
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos")]
|
||||
[assembly: AssemblyProduct("Bullet for XNA")]
|
||||
[assembly: AssemblyDescription("BulletX Common Demo Code")]
|
||||
[assembly: AssemblyCompany("XNADev.ru")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("49577e4d-b699-4933-972d-7734f73b02ba")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.149.21894")]
|
||||
@@ -1,115 +0,0 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</ProjectGuid>
|
||||
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>XnaDevRu.BulletX.Demos</RootNamespace>
|
||||
<AssemblyName>XnaDevRu.BulletX.Demos</AssemblyName>
|
||||
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
|
||||
<XnaPlatform>Windows</XnaPlatform>
|
||||
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
|
||||
<XNAProjectContentPipelineAssemblies>
|
||||
</XNAProjectContentPipelineAssemblies>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>BulletXDemos.snk</AssemblyOriginatorKeyFile>
|
||||
<DelaySign>true</DelaySign>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DocumentationFile>..\..\..\..\Build\x86\Debug\XnaDevRu.BulletX.Demos.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\..\Build\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DocumentationFile>..\..\..\..\Build\x86\Release\XnaDevRu.BulletX.Demos.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Xna.Framework">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Game">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DemoGame.cs">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>DemoGame</Name>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\XnaDevRu.Demos\Source\XnaDevRu.Demos\XnaDevRu.Demos.csproj">
|
||||
<Project>{C54AF66D-0C55-4A84-9E7C-FC6346C78681}</Project>
|
||||
<Name>XnaDevRu.Demos</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
|
||||
<Project>{5BEE189F-47A1-42A8-A297-1960221BE20D}</Project>
|
||||
<Name>XnaDevRu.BulletX</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\..\SharedContent\Models\box.x">
|
||||
<Link>Content\box.x</Link>
|
||||
<XNAUseContentPipeline>true</XNAUseContentPipeline>
|
||||
<Importer>XImporter</Importer>
|
||||
<Processor>ModelProcessor</Processor>
|
||||
<Name>box</Name>
|
||||
</Content>
|
||||
<Content Include="..\..\..\SharedContent\Models\cylinder.x">
|
||||
<Link>Content\cylinder.x</Link>
|
||||
<XNAUseContentPipeline>true</XNAUseContentPipeline>
|
||||
<Importer>XImporter</Importer>
|
||||
<Processor>ModelProcessor</Processor>
|
||||
<Name>cylinder</Name>
|
||||
</Content>
|
||||
<Content Include="..\..\..\SharedContent\Models\sphere.x">
|
||||
<Link>Content\sphere.x</Link>
|
||||
<XNAUseContentPipeline>true</XNAUseContentPipeline>
|
||||
<Importer>XImporter</Importer>
|
||||
<Processor>ModelProcessor</Processor>
|
||||
<Name>sphere</Name>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="BulletXDemos.snk">
|
||||
<XNAUseContentPipeline>false</XNAUseContentPipeline>
|
||||
<Name>BulletXDemos</Name>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
internal static class BulletDebug
|
||||
{
|
||||
[Conditional("DEBUG")]
|
||||
public static void Assert(Boolean condition)
|
||||
{
|
||||
//if (!condition)
|
||||
//{
|
||||
// Throw("No info available");
|
||||
//}
|
||||
Debug.Assert(condition);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void Assert(Boolean condition, String message)
|
||||
{
|
||||
//if (!condition)
|
||||
//{
|
||||
// Throw(message);
|
||||
//}
|
||||
Debug.Assert(condition, message);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void Assert(Boolean condition, String message, String detailMessage)
|
||||
{
|
||||
//if (!condition)
|
||||
//{
|
||||
// Throw(message);
|
||||
//}
|
||||
Debug.Assert(condition, message, detailMessage);
|
||||
}
|
||||
|
||||
private static void Throw(String message)
|
||||
{
|
||||
String msg = String.Format("Assertion Error: {0}", message);
|
||||
|
||||
throw new BulletException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,623 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class AxisSweep3: OverlappingPairCache
|
||||
{
|
||||
Vector3 _worldAabbMin;
|
||||
Vector3 _worldAabbMax;
|
||||
|
||||
Vector3 _quantize;
|
||||
|
||||
int _numHandles;
|
||||
int _maxHandles;
|
||||
|
||||
Handle[] _handles;
|
||||
Edge[][] _edges = new Edge[3][];
|
||||
|
||||
ushort _firstFreeHandle;
|
||||
|
||||
int _invalidPair;
|
||||
|
||||
public AxisSweep3(Vector3 worldAabbMin, Vector3 worldAabbMax, int maxHandles)
|
||||
: base()
|
||||
{
|
||||
BulletDebug.Assert(maxHandles > 1 && maxHandles < 32767);
|
||||
|
||||
// init bounds
|
||||
_worldAabbMin = worldAabbMin;
|
||||
_worldAabbMax = worldAabbMax;
|
||||
|
||||
Vector3 aabbSize = _worldAabbMax - _worldAabbMin;
|
||||
_quantize = new Vector3(65535.0f, 65535.0f, 65535.0f) / aabbSize;
|
||||
|
||||
// allocate handles buffer and put all handles on free list
|
||||
_handles = new Handle[maxHandles];
|
||||
for (int i = 0; i < maxHandles; i++)
|
||||
_handles[i] = new Handle();
|
||||
_maxHandles = maxHandles;
|
||||
_numHandles = 0;
|
||||
|
||||
// handle 0 is reserved as the null index, and is also used as the sentinel
|
||||
_firstFreeHandle = 1;
|
||||
{
|
||||
for (int i = _firstFreeHandle; i < maxHandles; i++)
|
||||
{
|
||||
_handles[i].NextFree = (ushort)(i + 1);
|
||||
}
|
||||
_handles[maxHandles - 1].NextFree = 0;
|
||||
}
|
||||
|
||||
{
|
||||
// allocate edge buffers
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
_edges[i] = new Edge[maxHandles * 2];
|
||||
for (int j = 0; j < maxHandles * 2; j++)
|
||||
{
|
||||
_edges[i][j] = new Edge();
|
||||
}
|
||||
}
|
||||
}
|
||||
//removed overlap management
|
||||
|
||||
// make boundary sentinels
|
||||
|
||||
_handles[0].ClientData = 0;
|
||||
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
_handles[0].MinEdges[axis] = 0;
|
||||
_handles[0].MaxEdges[axis] = 1;
|
||||
|
||||
_edges[axis][0].Position = 0;
|
||||
_edges[axis][0].Handle = 0;
|
||||
_edges[axis][1].Position = 0xffff;
|
||||
_edges[axis][1].Handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort AddHandle(Vector3 aabbMin, Vector3 aabbMax, object owner, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
|
||||
{
|
||||
ushort[] min = new ushort[3], max = new ushort[3];
|
||||
Quantize(out min, aabbMin, 0);
|
||||
Quantize(out max, aabbMax, 1);
|
||||
|
||||
ushort handle = AllocateHandle();
|
||||
Handle oHandle = GetHandle(handle);
|
||||
|
||||
oHandle.HandleID = handle;
|
||||
oHandle.ClientData = owner;
|
||||
oHandle.CollisionFilterGroup = collisionFilterGroup;
|
||||
oHandle.CollisionFilterMask = collisionFilterMask;
|
||||
|
||||
int limit = _numHandles * 2;
|
||||
|
||||
// (Gluk )
|
||||
// ( Inside )
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
_handles[0].MaxEdges[axis] += 2;
|
||||
|
||||
_edges[axis][limit + 1].Position = _edges[axis][limit - 1].Position;
|
||||
_edges[axis][limit + 1].Handle = _edges[axis][limit - 1].Handle;
|
||||
|
||||
_edges[axis][limit - 1].Position = min[axis];
|
||||
_edges[axis][limit - 1].Handle = handle;
|
||||
|
||||
_edges[axis][limit].Position = max[axis];
|
||||
_edges[axis][limit].Handle = handle;
|
||||
|
||||
oHandle.MinEdges[axis] = (ushort)(limit - 1);
|
||||
oHandle.MaxEdges[axis] = (ushort)limit;
|
||||
}
|
||||
|
||||
SortMinDown(0, oHandle.MinEdges[0], false);
|
||||
SortMaxDown(0, oHandle.MaxEdges[0], false);
|
||||
SortMinDown(1, oHandle.MinEdges[1], false);
|
||||
SortMaxDown(1, oHandle.MaxEdges[1], false);
|
||||
SortMinDown(2, oHandle.MinEdges[2], true);
|
||||
SortMaxDown(2, oHandle.MaxEdges[2], true);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
public void RemoveHandle(ushort handle)
|
||||
{
|
||||
Handle pHandle = GetHandle(handle);
|
||||
|
||||
//explicitly remove the pairs containing the proxy
|
||||
//we could do it also in the sortMinUp (passing true)
|
||||
//todo: compare performance
|
||||
RemoveOverlappingPairsContainingProxy(pHandle);
|
||||
|
||||
|
||||
// compute current limit of edge arrays
|
||||
int limit = _numHandles * 2;
|
||||
int axis;
|
||||
|
||||
for (axis = 0; axis < 3; axis++)
|
||||
{
|
||||
_handles[0].MaxEdges[axis] -= 2;
|
||||
}
|
||||
|
||||
// remove the edges by sorting them up to the end of the list
|
||||
for (axis = 0; axis < 3; axis++)
|
||||
{
|
||||
Edge[] pEdges = _edges[axis];
|
||||
ushort max = pHandle.MaxEdges[axis];
|
||||
pEdges[max].Position = 0xffff;
|
||||
|
||||
SortMaxUp(axis, max, false);
|
||||
|
||||
ushort i = pHandle.MinEdges[axis];
|
||||
pEdges[i].Position = 0xffff;
|
||||
|
||||
SortMinUp(axis, i, false);
|
||||
|
||||
pEdges[limit - 1].Handle = 0;
|
||||
pEdges[limit - 1].Position = 0xffff;
|
||||
}
|
||||
|
||||
// free the handle
|
||||
FreeHandle(handle);
|
||||
}
|
||||
|
||||
public override void ProcessAllOverlappingPairs(IOverlapCallback callback)
|
||||
{
|
||||
OverlappingPairs.Sort(new Comparison<BroadphasePair>(BroadphasePair.ComparisonSort));
|
||||
|
||||
if (_invalidPair != 0)
|
||||
OverlappingPairs.RemoveRange(OverlappingPairs.Count - _invalidPair, _invalidPair);
|
||||
_invalidPair = 0;
|
||||
|
||||
BroadphasePair previousPair = new BroadphasePair();
|
||||
previousPair.ProxyA = null;
|
||||
previousPair.ProxyB = null;
|
||||
previousPair.CollisionAlgorithm = null;
|
||||
|
||||
List<BroadphasePair> removal = new List<BroadphasePair>();
|
||||
|
||||
for (int i = 0; i < OverlappingPairs.Count; i++)
|
||||
{
|
||||
bool isDuplicate = (OverlappingPairs[i] == previousPair);
|
||||
previousPair = OverlappingPairs[i];
|
||||
bool needsRemoval;
|
||||
if (!isDuplicate)
|
||||
{
|
||||
bool hasOverlap = TestOverlap(previousPair.ProxyA, previousPair.ProxyB);
|
||||
if (hasOverlap)
|
||||
{
|
||||
needsRemoval = callback.ProcessOverlap(ref previousPair);
|
||||
}
|
||||
else
|
||||
{
|
||||
needsRemoval = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needsRemoval = true;
|
||||
BulletDebug.Assert(previousPair.CollisionAlgorithm == null);
|
||||
}
|
||||
|
||||
if (needsRemoval)
|
||||
{
|
||||
removal.Add(previousPair);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < removal.Count; i++)
|
||||
{
|
||||
BroadphasePair pair = removal[i];
|
||||
CleanOverlappingPair(ref pair);
|
||||
pair.ProxyA = null;
|
||||
pair.ProxyB = null;
|
||||
_invalidPair++;
|
||||
OverlappingPairCount--;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TestOverlap(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
|
||||
{
|
||||
if (proxyA == null || proxyB == null)
|
||||
return false;
|
||||
|
||||
Handle handleA = proxyA as Handle;
|
||||
Handle handleB = proxyB as Handle;
|
||||
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
if (handleA.MaxEdges[axis] < handleB.MinEdges[axis] ||
|
||||
handleB.MaxEdges[axis] < handleA.MinEdges[axis])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TestOverlap(int ignoreAxis, Handle pHandleA, Handle pHandleB)
|
||||
{
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
if (axis != ignoreAxis)
|
||||
{
|
||||
if (pHandleA.MaxEdges[axis] < pHandleB.MinEdges[axis] ||
|
||||
pHandleB.MaxEdges[axis] < pHandleA.MinEdges[axis])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ushort AllocateHandle()
|
||||
{
|
||||
ushort handle = _firstFreeHandle;
|
||||
_firstFreeHandle = GetHandle(handle).NextFree;
|
||||
_numHandles++;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
private void FreeHandle(ushort handle)
|
||||
{
|
||||
BulletDebug.Assert(handle > 0 && handle < _maxHandles);
|
||||
|
||||
GetHandle(handle).NextFree = _firstFreeHandle;
|
||||
_firstFreeHandle = handle;
|
||||
|
||||
_numHandles--;
|
||||
}
|
||||
|
||||
private Handle GetHandle(ushort handle)
|
||||
{
|
||||
return _handles[handle];
|
||||
}
|
||||
|
||||
private void UpdateHandle(ushort handle, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
Handle pHandle = GetHandle(handle);
|
||||
|
||||
// quantize the new bounds
|
||||
ushort[] min = new ushort[3];
|
||||
ushort[] max = new ushort[3];
|
||||
Quantize(out min, aabbMin, 0);
|
||||
Quantize(out max, aabbMax, 1);
|
||||
|
||||
// update changed edges
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
ushort emin = pHandle.MinEdges[axis];
|
||||
ushort emax = pHandle.MaxEdges[axis];
|
||||
|
||||
int dmin = (int)min[axis] - (int)_edges[axis][emin].Position;
|
||||
int dmax = (int)max[axis] - (int)_edges[axis][emax].Position;
|
||||
|
||||
_edges[axis][emin].Position = min[axis];
|
||||
_edges[axis][emax].Position = max[axis];
|
||||
|
||||
// expand (only adds overlaps)
|
||||
if (dmin < 0)
|
||||
SortMinDown(axis, emin, true);
|
||||
|
||||
if (dmax > 0)
|
||||
SortMaxUp(axis, emax, true);
|
||||
|
||||
// shrink (only removes overlaps)
|
||||
if (dmin > 0)
|
||||
SortMinUp(axis, emin, true);
|
||||
|
||||
if (dmax < 0)
|
||||
SortMaxDown(axis, emax, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void Quantize(out ushort[] result, Vector3 point, int isMax)
|
||||
{
|
||||
Vector3 clampedPoint = new Vector3(
|
||||
point.X,
|
||||
point.Y,
|
||||
point.Z
|
||||
);
|
||||
|
||||
MathHelper.SetMax(ref clampedPoint, _worldAabbMin);
|
||||
MathHelper.SetMin(ref clampedPoint, _worldAabbMax);
|
||||
|
||||
Vector3 v = (clampedPoint - _worldAabbMin) * _quantize;
|
||||
|
||||
result = new ushort[3];
|
||||
result[0] = (ushort)(((int)v.X & 0xfffe) | isMax);
|
||||
result[1] = (ushort)(((int)v.Y & 0xfffe) | isMax);
|
||||
result[2] = (ushort)(((int)v.Z & 0xfffe) | isMax);
|
||||
}
|
||||
|
||||
private void SortMinDown(int axis, ushort edge, bool updateOverlaps)
|
||||
{
|
||||
Edge pEdge = _edges[axis][edge];
|
||||
Edge pPrev = _edges[axis][edge - 1];
|
||||
Handle pHandleEdge = GetHandle(pEdge.Handle);
|
||||
|
||||
while (pEdge.Position < pPrev.Position)
|
||||
{
|
||||
Handle pHandlePrev = GetHandle(pPrev.Handle);
|
||||
|
||||
if (pPrev.IsMax())
|
||||
{
|
||||
// if previous edge is a maximum check the bounds and add an overlap if necessary
|
||||
if (updateOverlaps && TestOverlap(axis, pHandleEdge, pHandlePrev))
|
||||
{
|
||||
AddOverlappingPair(pHandleEdge, pHandlePrev);
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandlePrev.MaxEdges[axis]++;
|
||||
}
|
||||
else
|
||||
pHandlePrev.MinEdges[axis]++;
|
||||
|
||||
pHandleEdge.MinEdges[axis]--;
|
||||
|
||||
// swap the edges
|
||||
pEdge.Swap(ref pPrev);
|
||||
|
||||
// decrement
|
||||
edge--;
|
||||
pEdge = _edges[axis][edge];
|
||||
pPrev = _edges[axis][edge - 1];
|
||||
}
|
||||
}
|
||||
|
||||
private void SortMinUp(int axis, ushort edge, bool updateOverlaps)
|
||||
{
|
||||
Edge pEdge = _edges[axis][edge];
|
||||
Edge pNext = _edges[axis][edge + 1];
|
||||
Handle pHandleEdge = GetHandle(pEdge.Handle);
|
||||
|
||||
while ((pNext.Handle != 0) && (pEdge.Position >= pNext.Position))
|
||||
{
|
||||
Handle pHandleNext = GetHandle(pNext.Handle);
|
||||
|
||||
if (pNext.IsMax())
|
||||
{
|
||||
// if next edge is maximum remove any overlap between the two handles
|
||||
if (updateOverlaps)
|
||||
{
|
||||
//Handle handle0 = GetHandle(pEdge.Handle);
|
||||
//Handle handle1 = GetHandle(pNext.Handle);
|
||||
//BroadphasePair tmpPair = new BroadphasePair(handle0, handle1);
|
||||
//RemoveOverlappingPair(tmpPair);
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandleNext.MaxEdges[axis]--;
|
||||
}
|
||||
else
|
||||
pHandleNext.MinEdges[axis]--;
|
||||
|
||||
pHandleEdge.MinEdges[axis]++;
|
||||
|
||||
// swap the edges
|
||||
pEdge.Swap(ref pNext);
|
||||
|
||||
// increment
|
||||
edge++;
|
||||
pEdge = _edges[axis][edge];
|
||||
pNext = _edges[axis][edge + 1];
|
||||
}
|
||||
}
|
||||
|
||||
private void SortMaxDown(int axis, ushort edge, bool updateOverlaps)
|
||||
{
|
||||
Edge pEdge = _edges[axis][edge];
|
||||
Edge pPrev = _edges[axis][edge - 1];
|
||||
Handle pHandleEdge = GetHandle(pEdge.Handle);
|
||||
|
||||
while (pEdge.Position < pPrev.Position)
|
||||
{
|
||||
Handle pHandlePrev = GetHandle(pPrev.Handle);
|
||||
|
||||
if (!pPrev.IsMax())
|
||||
{
|
||||
// if previous edge was a minimum remove any overlap between the two handles
|
||||
if (updateOverlaps)
|
||||
{
|
||||
//this is done during the overlappingpairarray iteration/narrowphase collision
|
||||
//Handle handle0 = GetHandle(pEdge.Handle);
|
||||
//Handle handle1 = GetHandle(pPrev.Handle);
|
||||
//BroadphasePair pair = FindPair(handle0, handle1);
|
||||
|
||||
//if (pair != null)
|
||||
//{
|
||||
// RemoveOverlappingPair(pair);
|
||||
//}
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandlePrev.MinEdges[axis]++; ;
|
||||
}
|
||||
else
|
||||
pHandlePrev.MaxEdges[axis]++;
|
||||
|
||||
pHandleEdge.MaxEdges[axis]--;
|
||||
|
||||
// swap the edges
|
||||
pEdge.Swap(ref pPrev);
|
||||
|
||||
// decrement
|
||||
edge--;
|
||||
pEdge = _edges[axis][edge];
|
||||
pPrev = _edges[axis][edge - 1];
|
||||
}
|
||||
}
|
||||
|
||||
private void SortMaxUp(int axis, ushort edge, bool updateOverlaps)
|
||||
{
|
||||
Edge pEdge = _edges[axis][edge];
|
||||
Edge pNext = _edges[axis][edge + 1];
|
||||
Handle pHandleEdge = GetHandle(pEdge.Handle);
|
||||
|
||||
while ((pNext.Handle!=0) && (pEdge.Position >= pNext.Position))
|
||||
{
|
||||
Handle pHandleNext = GetHandle(pNext.Handle);
|
||||
|
||||
if (!pNext.IsMax())
|
||||
{
|
||||
// if next edge is a minimum check the bounds and add an overlap if necessary
|
||||
if (updateOverlaps && TestOverlap(axis, pHandleEdge, pHandleNext))
|
||||
{
|
||||
Handle handle0 = GetHandle(pEdge.Handle);
|
||||
Handle handle1 = GetHandle(pNext.Handle);
|
||||
AddOverlappingPair(handle0, handle1);
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandleNext.MinEdges[axis]--;
|
||||
}
|
||||
else
|
||||
pHandleNext.MaxEdges[axis]--;
|
||||
|
||||
pHandleEdge.MaxEdges[axis]++;
|
||||
|
||||
// swap the edges
|
||||
pEdge.Swap(ref pNext);
|
||||
|
||||
// increment
|
||||
edge++;
|
||||
pEdge = _edges[axis][edge];
|
||||
pNext = _edges[axis][edge + 1];
|
||||
}
|
||||
}
|
||||
|
||||
#region Abstract
|
||||
|
||||
public override void RefreshOverlappingPairs()
|
||||
{
|
||||
}
|
||||
|
||||
public override BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
|
||||
{
|
||||
ushort handleId = AddHandle(min, max, userData, collisionFilterGroup, collisionFilterMask);
|
||||
|
||||
Handle handle = GetHandle(handleId);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
public override void DestroyProxy(BroadphaseProxy proxy)
|
||||
{
|
||||
Handle handle = proxy as Handle;
|
||||
RemoveHandle(handle.HandleID);
|
||||
}
|
||||
|
||||
public override void SetAabb(BroadphaseProxy proxy, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
Handle handle = proxy as Handle;
|
||||
UpdateHandle(handle.HandleID, aabbMin, aabbMax);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class Edge
|
||||
{
|
||||
ushort position;
|
||||
ushort handle;
|
||||
|
||||
public ushort Position
|
||||
{
|
||||
get { return position; }
|
||||
set { position = value; }
|
||||
}
|
||||
|
||||
public ushort Handle
|
||||
{
|
||||
get { return handle; }
|
||||
set { handle = value; }
|
||||
}
|
||||
|
||||
public bool IsMax()
|
||||
{
|
||||
return (position & (ushort)1) == 1;
|
||||
}
|
||||
|
||||
public void Swap(ref Edge e)
|
||||
{
|
||||
ushort tmpPosition = this.position;
|
||||
ushort tmpHandle = this.handle;
|
||||
this.position = e.position;
|
||||
this.handle = e.handle;
|
||||
e.position = tmpPosition;
|
||||
e.handle = tmpHandle;
|
||||
}
|
||||
}
|
||||
|
||||
public class Handle: BroadphaseProxy
|
||||
{
|
||||
ushort[] minEdges, maxEdges;
|
||||
ushort pad;
|
||||
ushort handleID;
|
||||
|
||||
public ushort[] MinEdges
|
||||
{
|
||||
get { return minEdges; }
|
||||
set { minEdges = value; }
|
||||
}
|
||||
|
||||
public ushort[] MaxEdges
|
||||
{
|
||||
get { return maxEdges; }
|
||||
set { maxEdges = value; }
|
||||
}
|
||||
|
||||
public ushort HandleID
|
||||
{
|
||||
get { return handleID; }
|
||||
set { handleID = value; }
|
||||
}
|
||||
|
||||
public ushort Pad
|
||||
{
|
||||
get { return pad; }
|
||||
set { pad = value; }
|
||||
}
|
||||
|
||||
public ushort NextFree
|
||||
{
|
||||
get { return minEdges[0]; }
|
||||
set { minEdges[0] = value;}
|
||||
}
|
||||
|
||||
public Handle()
|
||||
{
|
||||
minEdges = new ushort[3];
|
||||
maxEdges = new ushort[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// Dispatcher uses these types
|
||||
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
|
||||
/// to facilitate type checking
|
||||
public enum BroadphaseNativeTypes
|
||||
{
|
||||
// polyhedral convex shapes
|
||||
Box,
|
||||
Triangle,
|
||||
Tetrahedral,
|
||||
ConvexTriangleMesh,
|
||||
ConvexHull,
|
||||
//implicit convex shapes
|
||||
ImplicitConvexShapes,
|
||||
Sphere,
|
||||
MultiSphere,
|
||||
Capsule,
|
||||
Cone,
|
||||
Convex,
|
||||
Cylinder,
|
||||
MinkowskiSum,
|
||||
MinkowskiDifference,
|
||||
//concave shapes
|
||||
ConcaveShapesStart,
|
||||
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
|
||||
TriangleMesh,
|
||||
//used for demo integration FAST/Swift collision library and Bullet
|
||||
FastConcaveMesh,
|
||||
//terrain
|
||||
Terrain,
|
||||
//Used for GIMPACT Trimesh integration
|
||||
Gimpact,
|
||||
|
||||
Empty,
|
||||
StaticPlane,
|
||||
ConcaveShapesEnd,
|
||||
|
||||
Compound,
|
||||
|
||||
MaxBroadphaseCollisionTypes,
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class BroadphasePair
|
||||
{
|
||||
private BroadphaseProxy _proxyA;
|
||||
private BroadphaseProxy _proxyB;
|
||||
|
||||
private CollisionAlgorithm _algorithm;
|
||||
private object _userInfo;
|
||||
|
||||
public BroadphasePair()
|
||||
{
|
||||
}
|
||||
|
||||
public BroadphasePair(BroadphasePair other)
|
||||
{
|
||||
_proxyA = other._proxyA;
|
||||
_proxyB = other._proxyB;
|
||||
|
||||
_algorithm = other._algorithm;
|
||||
_userInfo = null;
|
||||
}
|
||||
|
||||
public BroadphasePair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
|
||||
{
|
||||
_proxyA = proxyA;
|
||||
_proxyB = proxyB;
|
||||
|
||||
_algorithm = null;
|
||||
_userInfo = null;
|
||||
}
|
||||
|
||||
public BroadphaseProxy ProxyA { get { return _proxyA; } set { _proxyA = value; } }
|
||||
public BroadphaseProxy ProxyB { get { return _proxyB; } set { _proxyB = value; } }
|
||||
|
||||
public CollisionAlgorithm CollisionAlgorithm { get { return _algorithm; } set { _algorithm = value; } }
|
||||
public object UserInfo { get { return _userInfo; } set { _userInfo = value; } }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _proxyA.GetHashCode() ^ _proxyB.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is BroadphasePair)
|
||||
return this == (BroadphasePair)obj;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int ComparisonSort(BroadphasePair a, BroadphasePair b)
|
||||
{
|
||||
int aAId = a.ProxyA != null ? a.ProxyA.ComparisonID : -1;
|
||||
int aBId = a.ProxyB != null ? a.ProxyB.ComparisonID : -1;
|
||||
int aCId = a.CollisionAlgorithm != null ? a.CollisionAlgorithm.ComparisonID : -1;
|
||||
int bAId = b.ProxyA != null ? b.ProxyA.ComparisonID : -1;
|
||||
int bBId = b.ProxyB != null ? b.ProxyB.ComparisonID : -1;
|
||||
int bCId = b.CollisionAlgorithm != null ? b.CollisionAlgorithm.ComparisonID : -1;
|
||||
|
||||
if (aAId > bAId ||
|
||||
(a.ProxyA == b.ProxyA && aBId > bBId) ||
|
||||
(a.ProxyA == b.ProxyA && a.ProxyB == b.ProxyB && aCId > bCId))
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static bool operator ==(BroadphasePair a, BroadphasePair b)
|
||||
{
|
||||
if (object.Equals(a, null) && object.Equals(b, null))
|
||||
return true;
|
||||
if (object.Equals(a, null) || object.Equals(b, null))
|
||||
return false;
|
||||
|
||||
return (a.ProxyA == b.ProxyA) && (a.ProxyB == b.ProxyB);
|
||||
}
|
||||
|
||||
public static bool operator !=(BroadphasePair a, BroadphasePair b)
|
||||
{
|
||||
if (object.Equals(a, null) && object.Equals(b, null))
|
||||
return true;
|
||||
if (object.Equals(a, null) || object.Equals(b, null))
|
||||
return false;
|
||||
|
||||
return (a.ProxyA != b.ProxyA) || (a.ProxyB != b.ProxyB);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class BroadphaseProxy
|
||||
{
|
||||
//Usually the client CollisionObject or Rigidbody class
|
||||
private object _clientObject;
|
||||
private CollisionFilterGroups _collisionFilterGroup;
|
||||
private CollisionFilterGroups _collisionFilterMask;
|
||||
private readonly int _comparisonID;
|
||||
|
||||
private static int _globalCount = 0;
|
||||
|
||||
public BroadphaseProxy()
|
||||
{
|
||||
_comparisonID = _globalCount++;
|
||||
}
|
||||
|
||||
public BroadphaseProxy(object userData, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask)
|
||||
: this()
|
||||
{
|
||||
_clientObject = userData;
|
||||
_collisionFilterGroup = collisionFilterGroup;
|
||||
_collisionFilterMask = collisionFilterMask;
|
||||
}
|
||||
|
||||
public object ClientData { get { return _clientObject; } set { _clientObject = value; } }
|
||||
public CollisionFilterGroups CollisionFilterGroup { get { return _collisionFilterGroup; } set { _collisionFilterGroup = value; } }
|
||||
public CollisionFilterGroups CollisionFilterMask { get { return _collisionFilterMask; } set { _collisionFilterMask = value; } }
|
||||
internal int ComparisonID { get { return _comparisonID; } }
|
||||
|
||||
public static bool IsPolyhedral(BroadphaseNativeTypes proxyType)
|
||||
{
|
||||
return (proxyType < BroadphaseNativeTypes.ImplicitConvexShapes);
|
||||
}
|
||||
|
||||
public static bool IsConvex(BroadphaseNativeTypes proxyType)
|
||||
{
|
||||
return (proxyType < BroadphaseNativeTypes.ConcaveShapesStart);
|
||||
}
|
||||
|
||||
public static bool IsConcave(BroadphaseNativeTypes proxyType)
|
||||
{
|
||||
return ((proxyType > BroadphaseNativeTypes.ConcaveShapesStart) &&
|
||||
(proxyType < BroadphaseNativeTypes.ConcaveShapesEnd));
|
||||
}
|
||||
public static bool IsCompound(BroadphaseNativeTypes proxyType)
|
||||
{
|
||||
return (proxyType == BroadphaseNativeTypes.Compound);
|
||||
}
|
||||
public static bool IsInfinite(BroadphaseNativeTypes proxyType)
|
||||
{
|
||||
return (proxyType == BroadphaseNativeTypes.StaticPlane);
|
||||
}
|
||||
|
||||
//optional filtering to cull potential collisions
|
||||
public enum CollisionFilterGroups
|
||||
{
|
||||
Default = 1,
|
||||
Static = 2,
|
||||
Kinematic = 4,
|
||||
Debris = 8,
|
||||
Sensor = 16,
|
||||
All = Default | Static | Kinematic | Debris | Sensor,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// CollisionAlgorithm is an collision interface that is compatible with the Broadphase and Dispatcher.
|
||||
/// It is persistent over frames
|
||||
/// </summary>
|
||||
public abstract class CollisionAlgorithm
|
||||
{
|
||||
private IDispatcher _dispatcher;
|
||||
private readonly int _comparisonID = 0;
|
||||
|
||||
private static int _globalCount = 0;
|
||||
|
||||
public CollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
_comparisonID = _globalCount++;
|
||||
_dispatcher = collisionAlgorithmConstructionInfo.Dispatcher;
|
||||
}
|
||||
|
||||
protected IDispatcher Dispatcher { get { return _dispatcher; } set { _dispatcher = value; } }
|
||||
internal int ComparisonID { get { return _comparisonID; } }
|
||||
|
||||
public abstract void ProcessCollision(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut);
|
||||
public abstract float CalculateTimeOfImpact(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public struct CollisionAlgorithmConstructionInfo
|
||||
{
|
||||
private IDispatcher _dispatcher;
|
||||
private PersistentManifold _manifold;
|
||||
|
||||
public CollisionAlgorithmConstructionInfo(IDispatcher dispatcher)
|
||||
{
|
||||
_dispatcher = dispatcher;
|
||||
_manifold = null;
|
||||
}
|
||||
|
||||
public IDispatcher Dispatcher { get { return _dispatcher; } set { _dispatcher = value; } }
|
||||
public PersistentManifold Manifold { get { return _manifold; } set { _manifold = value; } }
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public enum DispatchFunction
|
||||
{
|
||||
Discrete = 1,
|
||||
Continuous,
|
||||
}
|
||||
|
||||
public class DispatcherInfo
|
||||
{
|
||||
private float _timeStep;
|
||||
private int _stepCount;
|
||||
private DispatchFunction _dispatchFunc = DispatchFunction.Discrete;
|
||||
private float _timeOfImpact = 1;
|
||||
private bool _useContinuous;
|
||||
private bool _enableSatConvex;
|
||||
private bool _enableSpu;
|
||||
private IDebugDraw _debugDraw;
|
||||
|
||||
public float TimeStep { get { return _timeStep; } set { _timeStep = value; } }
|
||||
public int StepCount { get { return _stepCount; } set { _stepCount = value; } }
|
||||
public DispatchFunction DispatchFunction { get { return _dispatchFunc; } set { _dispatchFunc = value; } }
|
||||
public float TimeOfImpact { get { return _timeOfImpact; } set { _timeOfImpact = value; } }
|
||||
public bool UseContinuous { get { return _useContinuous; } set { _useContinuous = value; } }
|
||||
public bool EnableSatConvex { get { return _enableSatConvex; } set { _enableSatConvex = value; } }
|
||||
public bool enableSpu { get { return _enableSpu; } set { _enableSpu = value; } }
|
||||
public IDebugDraw DebugDraw { get { return _debugDraw; } set { _debugDraw = value; } }
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public interface IBroadphase
|
||||
{
|
||||
BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask);
|
||||
void DestroyProxy(BroadphaseProxy proxy);
|
||||
void SetAabb(BroadphaseProxy proxy, Vector3 aabbMin, Vector3 aabbMax);
|
||||
void CleanProxyFromPairs(BroadphaseProxy proxy);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public interface IDispatcher
|
||||
{
|
||||
CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB, PersistentManifold sharedManifold);
|
||||
CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB);
|
||||
PersistentManifold GetNewManifold(object bodyA, object bodyB);
|
||||
void ReleaseManifold(PersistentManifold manifold);
|
||||
void ClearManifold(PersistentManifold manifold);
|
||||
bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB);
|
||||
bool NeedsResponse(CollisionObject bodyA, CollisionObject bodyB);
|
||||
void DispatchAllCollisionPairs(OverlappingPairCache pairCache, DispatcherInfo dispatchInfo);
|
||||
PersistentManifold GetManifoldByIndex(int index);
|
||||
|
||||
int ManifoldCount { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public interface IOverlapCallback
|
||||
{
|
||||
//return true for deletion of the pair
|
||||
bool ProcessOverlap(ref BroadphasePair pair);
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public abstract class OverlappingPairCache : IBroadphase
|
||||
{
|
||||
private static int _overlappingPairCount = 0;
|
||||
private List<BroadphasePair> _overlappingPairs = new List<BroadphasePair>();
|
||||
//during the dispatch, check that user doesn't destroy/create proxy
|
||||
private bool _blockedForChanges;
|
||||
|
||||
public List<BroadphasePair> OverlappingPairs { get { return _overlappingPairs; } set { _overlappingPairs = value; } }
|
||||
public bool BlockedForChanges { get { return _blockedForChanges; } set { _blockedForChanges = value; } }
|
||||
|
||||
public static int OverlappingPairCount { get { return _overlappingPairCount; } set { _overlappingPairCount = value; } }
|
||||
|
||||
public void RemoveOverlappingPair(BroadphasePair pair)
|
||||
{
|
||||
if (!_overlappingPairs.Contains(pair))
|
||||
return;
|
||||
|
||||
CleanOverlappingPair(ref pair);
|
||||
_overlappingPairs.Remove(pair);
|
||||
}
|
||||
|
||||
public void AddOverlappingPair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
|
||||
{
|
||||
//don't add overlap with own
|
||||
bool test = proxyA != proxyB;
|
||||
BulletDebug.Assert(proxyA != proxyB);
|
||||
|
||||
if (!NeedsBroadphaseCollision(proxyA, proxyB))
|
||||
return;
|
||||
|
||||
BroadphasePair pair = new BroadphasePair(proxyA, proxyB);
|
||||
_overlappingPairs.Add(pair);
|
||||
_overlappingPairCount++;
|
||||
}
|
||||
|
||||
//this FindPair becomes really slow. Either sort the list to speedup the query, or
|
||||
//use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
|
||||
//we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
|
||||
//Also we can use a 2D bitmap, which can be useful for a future GPU implementation
|
||||
public BroadphasePair FindPair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
|
||||
{
|
||||
if (!NeedsBroadphaseCollision(proxyA, proxyB))
|
||||
return null;
|
||||
|
||||
BroadphasePair pair = new BroadphasePair(proxyA, proxyB);
|
||||
for (int i = 0; i < _overlappingPairs.Count; i++)
|
||||
{
|
||||
if (_overlappingPairs[i] == pair)
|
||||
{
|
||||
return _overlappingPairs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CleanProxyFromPairs(BroadphaseProxy proxy)
|
||||
{
|
||||
for (int i = 0; i < _overlappingPairs.Count; i++)
|
||||
{
|
||||
BroadphasePair pair = _overlappingPairs[i];
|
||||
if (pair.ProxyA == proxy ||
|
||||
pair.ProxyB == proxy)
|
||||
{
|
||||
CleanOverlappingPair(ref pair);
|
||||
_overlappingPairs[i] = pair;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveOverlappingPairsContainingProxy(BroadphaseProxy proxy)
|
||||
{
|
||||
for (int i = _overlappingPairs.Count - 1; i >= 0; i--)
|
||||
{
|
||||
BroadphasePair pair = _overlappingPairs[i];
|
||||
if (pair.ProxyA == proxy ||
|
||||
pair.ProxyB == proxy)
|
||||
{
|
||||
RemoveOverlappingPair(pair);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool NeedsBroadphaseCollision(BroadphaseProxy proxy0, BroadphaseProxy proxy1)
|
||||
{
|
||||
bool collides = (proxy0.CollisionFilterGroup & proxy1.CollisionFilterMask) != 0;
|
||||
collides = collides && ((proxy1.CollisionFilterGroup & proxy0.CollisionFilterMask) != 0);
|
||||
|
||||
return collides;
|
||||
}
|
||||
|
||||
public virtual void ProcessAllOverlappingPairs(IOverlapCallback callback)
|
||||
{
|
||||
List<BroadphasePair> deleting = new List<BroadphasePair>();
|
||||
for (int i = 0; i < _overlappingPairs.Count; i++)
|
||||
{
|
||||
BroadphasePair p = _overlappingPairs[i];
|
||||
if (callback.ProcessOverlap(ref p))
|
||||
{
|
||||
CleanOverlappingPair(ref p);
|
||||
deleting.Add(p);
|
||||
_overlappingPairCount--;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < deleting.Count; i++)
|
||||
_overlappingPairs.Remove(deleting[i]);
|
||||
}
|
||||
|
||||
public void CleanOverlappingPair(ref BroadphasePair pair)
|
||||
{
|
||||
if (pair.CollisionAlgorithm != null)
|
||||
{
|
||||
if (pair.CollisionAlgorithm is IDisposable)
|
||||
(pair.CollisionAlgorithm as IDisposable).Dispose();
|
||||
pair.CollisionAlgorithm = null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void RefreshOverlappingPairs();
|
||||
|
||||
#region IBroadphase Members
|
||||
public abstract BroadphaseProxy CreateProxy(Microsoft.Xna.Framework.Vector3 min, Microsoft.Xna.Framework.Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask);
|
||||
|
||||
public abstract void DestroyProxy(BroadphaseProxy proxy);
|
||||
|
||||
public abstract void SetAabb(BroadphaseProxy proxy, Microsoft.Xna.Framework.Vector3 aabbMin, Microsoft.Xna.Framework.Vector3 aabbMax);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class SimpleBroadphase : OverlappingPairCache
|
||||
{
|
||||
private int _maxProxies;
|
||||
private List<SimpleBroadphaseProxy> _proxies = new List<SimpleBroadphaseProxy>();
|
||||
|
||||
public SimpleBroadphase()
|
||||
: this(16384) { }
|
||||
|
||||
public SimpleBroadphase(int maxProxies)
|
||||
: base()
|
||||
{
|
||||
_maxProxies = maxProxies;
|
||||
}
|
||||
|
||||
public override BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
|
||||
{
|
||||
if (_proxies.Count >= _maxProxies)
|
||||
{
|
||||
BulletDebug.Assert(false);
|
||||
return null; //should never happen, but don't let the game crash ;-)
|
||||
}
|
||||
BulletDebug.Assert(min.X <= max.X && min.Y <= max.Y && min.Z <= max.Z);
|
||||
|
||||
SimpleBroadphaseProxy proxy = new SimpleBroadphaseProxy(min, max, shapeType, userData, collisionFilterGroup, collisionFilterMask);
|
||||
_proxies.Add(proxy);
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
|
||||
public override void DestroyProxy(BroadphaseProxy proxy)
|
||||
{
|
||||
RemoveOverlappingPairsContainingProxy(proxy);
|
||||
_proxies.Remove(proxy as SimpleBroadphaseProxy);
|
||||
}
|
||||
|
||||
public override void SetAabb(BroadphaseProxy proxy, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
SimpleBroadphaseProxy simpleProxy = GetSimpleProxyFromProxy(proxy);
|
||||
simpleProxy.Minimum = aabbMin;
|
||||
simpleProxy.Maximum = aabbMax;
|
||||
}
|
||||
|
||||
private SimpleBroadphaseProxy GetSimpleProxyFromProxy(BroadphaseProxy proxy)
|
||||
{
|
||||
return proxy as SimpleBroadphaseProxy;
|
||||
}
|
||||
|
||||
public override void RefreshOverlappingPairs()
|
||||
{
|
||||
for (int i = 0; i < _proxies.Count; i++)
|
||||
{
|
||||
SimpleBroadphaseProxy proxyA = _proxies[i];
|
||||
|
||||
for (int j = i + 1; j < _proxies.Count; j++)
|
||||
{
|
||||
SimpleBroadphaseProxy proxyB = _proxies[j];
|
||||
|
||||
if (AabbOverlap(proxyA, proxyB))
|
||||
{
|
||||
if (FindPair(proxyA, proxyB) == null)
|
||||
{
|
||||
AddOverlappingPair(proxyA, proxyB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckOverlapCallback check = new CheckOverlapCallback();
|
||||
ProcessAllOverlappingPairs(check);
|
||||
}
|
||||
|
||||
public static bool AabbOverlap(SimpleBroadphaseProxy proxyA, SimpleBroadphaseProxy proxyB)
|
||||
{
|
||||
return proxyA.Minimum.X <= proxyB.Maximum.X && proxyB.Minimum.X <= proxyA.Maximum.X &&
|
||||
proxyA.Minimum.Y <= proxyB.Maximum.Y && proxyB.Minimum.Y <= proxyA.Maximum.Y &&
|
||||
proxyA.Minimum.Z <= proxyB.Maximum.Z && proxyB.Minimum.Z <= proxyA.Maximum.Z;
|
||||
}
|
||||
|
||||
private void Validate()
|
||||
{
|
||||
for (int i = 0; i < _proxies.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < _proxies.Count; j++)
|
||||
{
|
||||
if (_proxies[i] == _proxies[j])
|
||||
throw new BulletException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CheckOverlapCallback : IOverlapCallback
|
||||
{
|
||||
public bool ProcessOverlap(ref BroadphasePair pair)
|
||||
{
|
||||
return (!SimpleBroadphase.AabbOverlap(pair.ProxyA as SimpleBroadphaseProxy, pair.ProxyB as SimpleBroadphaseProxy));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class SimpleBroadphaseProxy : BroadphaseProxy
|
||||
{
|
||||
private Vector3 _min;
|
||||
private Vector3 _max;
|
||||
|
||||
public SimpleBroadphaseProxy() { }
|
||||
|
||||
public SimpleBroadphaseProxy(Vector3 minPoint, Vector3 maxPoint, BroadphaseNativeTypes shapeType, object userData, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask)
|
||||
: base(userData, collisionFilterGroup, collisionFilterMask)
|
||||
{
|
||||
_min = minPoint;
|
||||
_max = maxPoint;
|
||||
}
|
||||
|
||||
public Vector3 Minimum { get { return _min; } set { _min = value; } }
|
||||
public Vector3 Maximum { get { return _max; } set { _max = value; } }
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
internal class BridgeTriangleRaycastCallback : TriangleRaycastCallback
|
||||
{
|
||||
CollisionWorld.RayResultCallback _resultCallback;
|
||||
CollisionObject _collisionObject;
|
||||
TriangleMeshShape _triangleMesh;
|
||||
|
||||
public BridgeTriangleRaycastCallback(Vector3 from, Vector3 to,
|
||||
CollisionWorld.RayResultCallback resultCallback, CollisionObject collisionObject, TriangleMeshShape triangleMesh)
|
||||
: base(from, to)
|
||||
{
|
||||
_resultCallback = resultCallback;
|
||||
_collisionObject = collisionObject;
|
||||
_triangleMesh = triangleMesh;
|
||||
}
|
||||
|
||||
public override float ReportHit(Vector3 hitNormalLocal, float hitFraction, int partId, int triangleIndex)
|
||||
{
|
||||
CollisionWorld.LocalShapeInfo shapeInfo = new CollisionWorld.LocalShapeInfo();
|
||||
shapeInfo.ShapePart = partId;
|
||||
shapeInfo.TriangleIndex = triangleIndex;
|
||||
|
||||
CollisionWorld.LocalRayResult rayResult = new CollisionWorld.LocalRayResult
|
||||
(_collisionObject,
|
||||
shapeInfo,
|
||||
hitNormalLocal,
|
||||
hitFraction);
|
||||
|
||||
return _resultCallback.AddSingleResult(rayResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class CollisionAlgorithmCreateFunction
|
||||
{
|
||||
private bool _swapped;
|
||||
|
||||
public bool IsSwapped { get { return _swapped; } set { _swapped = value; } }
|
||||
|
||||
public virtual CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public delegate void NearCallback(ref BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo);
|
||||
|
||||
public class CollisionDispatcher : IDispatcher
|
||||
{
|
||||
private List<PersistentManifold> _manifolds = new List<PersistentManifold>();
|
||||
|
||||
//private bool _useIslands;
|
||||
private NearCallback _nearCallback;
|
||||
|
||||
//private ManifoldResult _defaultManifoldResult;
|
||||
|
||||
private CollisionAlgorithmCreateFunction[,] _doubleDispatch = new CollisionAlgorithmCreateFunction[(int)BroadphaseNativeTypes.MaxBroadphaseCollisionTypes, (int)BroadphaseNativeTypes.MaxBroadphaseCollisionTypes];
|
||||
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
private CollisionAlgorithmCreateFunction _convexConvexCreateFunc;
|
||||
private CollisionAlgorithmCreateFunction _convexConcaveCreateFunc;
|
||||
private CollisionAlgorithmCreateFunction _swappedConvexConcaveCreateFunc;
|
||||
private CollisionAlgorithmCreateFunction _compoundCreateFunc;
|
||||
private CollisionAlgorithmCreateFunction _swappedCompoundCreateFunc;
|
||||
private CollisionAlgorithmCreateFunction _emptyCreateFunc;
|
||||
|
||||
private int _count;
|
||||
private static int _manifoldCount = 0;
|
||||
|
||||
public CollisionDispatcher()
|
||||
{
|
||||
NearCallback = DefaultNearCallback;
|
||||
//_useIslands = true;
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
_convexConvexCreateFunc = new ConvexConvexAlgorithm.CreateFunc();
|
||||
_convexConcaveCreateFunc = new ConvexConcaveCollisionAlgorithm.CreateFunc();
|
||||
_swappedConvexConcaveCreateFunc = new ConvexConcaveCollisionAlgorithm.SwappedCreateFunc();
|
||||
_compoundCreateFunc = new CompoundCollisionAlgorithm.CreateFunc();
|
||||
_swappedCompoundCreateFunc = new CompoundCollisionAlgorithm.SwappedCreateFunc();
|
||||
_emptyCreateFunc = new EmptyAlgorithm.CreateFunc();
|
||||
|
||||
for (BroadphaseNativeTypes i = BroadphaseNativeTypes.Box; i < BroadphaseNativeTypes.MaxBroadphaseCollisionTypes; i++)
|
||||
{
|
||||
for (BroadphaseNativeTypes j = BroadphaseNativeTypes.Box; j < BroadphaseNativeTypes.MaxBroadphaseCollisionTypes; j++)
|
||||
{
|
||||
_doubleDispatch[(int)i, (int)j] = FindCreateFunction(i, j);
|
||||
if (_doubleDispatch[(int)i, (int)j] == null)
|
||||
throw new BulletException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Count { get { return _count; } set { _count = value; } }
|
||||
public int ManifoldCount { get { return _manifolds.Count; } }
|
||||
public List<PersistentManifold> Manifolds { get { return _manifolds; } }
|
||||
|
||||
public static int GlobalManifoldCount { get { return _manifoldCount; } set { _manifoldCount = value; } }
|
||||
|
||||
public PersistentManifold GetManifoldByIndex(int index)
|
||||
{
|
||||
return _manifolds[index];
|
||||
}
|
||||
|
||||
//registerCollisionCreateFunc allows registration of custom/alternative collision create functions
|
||||
public void RegisterCollisionCreateFunc(BroadphaseNativeTypes proxyTypeA, BroadphaseNativeTypes proxyTypeB, CollisionAlgorithmCreateFunction createFunc)
|
||||
{
|
||||
_doubleDispatch[(int)proxyTypeA, (int)proxyTypeB] = createFunc;
|
||||
}
|
||||
|
||||
public virtual PersistentManifold GetNewManifold(object bodyA, object bodyB)
|
||||
{
|
||||
_manifoldCount++;
|
||||
|
||||
CollisionObject body0 = bodyA as CollisionObject;
|
||||
CollisionObject body1 = bodyB as CollisionObject;
|
||||
|
||||
PersistentManifold manifold = new PersistentManifold(body0, body1);
|
||||
_manifolds.Add(manifold);
|
||||
|
||||
return manifold;
|
||||
}
|
||||
|
||||
public virtual void ReleaseManifold(PersistentManifold manifold)
|
||||
{
|
||||
_manifoldCount--;
|
||||
|
||||
ClearManifold(manifold);
|
||||
_manifolds.Remove(manifold);
|
||||
}
|
||||
|
||||
|
||||
public virtual void ClearManifold(PersistentManifold manifold)
|
||||
{
|
||||
manifold.ClearManifold();
|
||||
}
|
||||
|
||||
public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return FindAlgorithm(bodyA, bodyB, null);
|
||||
}
|
||||
|
||||
public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB, PersistentManifold sharedManifold)
|
||||
{
|
||||
CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo = new CollisionAlgorithmConstructionInfo();
|
||||
collisionAlgorithmConstructionInfo.Dispatcher = this;
|
||||
collisionAlgorithmConstructionInfo.Manifold = sharedManifold;
|
||||
CollisionAlgorithm collisionAlgorithm = _doubleDispatch[(int)bodyA.CollisionShape.ShapeType, (int)bodyB.CollisionShape.ShapeType].CreateCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB);
|
||||
return collisionAlgorithm;
|
||||
}
|
||||
|
||||
/*public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1)
|
||||
{
|
||||
return internalFindAlgorithm(body0, body1, null);
|
||||
}
|
||||
|
||||
public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1, PersistentManifold sharedManifold)
|
||||
{
|
||||
m_count++;
|
||||
|
||||
CollisionAlgorithmConstructionInfo ci = new CollisionAlgorithmConstructionInfo();
|
||||
ci.m_dispatcher = this;
|
||||
|
||||
if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConvex())
|
||||
{
|
||||
return new ConvexConvexAlgorithm(sharedManifold, ci, body0, body1);
|
||||
}
|
||||
|
||||
if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConcave())
|
||||
{
|
||||
return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, false);
|
||||
}
|
||||
|
||||
if (body1.getCollisionShape().isConvex() && body0.getCollisionShape().isConcave())
|
||||
{
|
||||
return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, true);
|
||||
}
|
||||
|
||||
if (body0.getCollisionShape().isCompound())
|
||||
{
|
||||
return new CompoundCollisionAlgorithm(ci, body0, body1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (body1.getCollisionShape().isCompound())
|
||||
{
|
||||
return new CompoundCollisionAlgorithm(ci, body0, body1, true);
|
||||
}
|
||||
}
|
||||
|
||||
//failed to find an algorithm
|
||||
return new EmptyAlgorithm(ci);
|
||||
}*/
|
||||
|
||||
public virtual bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
if (bodyA == null || bodyB == null)
|
||||
throw new BulletException();
|
||||
|
||||
bool needsCollision = true;
|
||||
|
||||
//broadphase filtering already deals with this
|
||||
/*if ((body0.isStaticObject() || body0.isKinematicObject()) &&
|
||||
(body1.isStaticObject() || body1.isKinematicObject()))
|
||||
{
|
||||
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
|
||||
}*/
|
||||
|
||||
if ((!bodyA.IsActive) && (!bodyB.IsActive))
|
||||
needsCollision = false;
|
||||
|
||||
return needsCollision;
|
||||
}
|
||||
|
||||
public virtual bool NeedsResponse(CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
//here you can do filtering
|
||||
bool hasResponse = bodyA.HasContactResponse && bodyB.HasContactResponse;
|
||||
hasResponse = hasResponse && (!bodyA.IsStaticOrKinematicObject || !bodyB.IsStaticOrKinematicObject);
|
||||
return hasResponse;
|
||||
}
|
||||
|
||||
public virtual void DispatchAllCollisionPairs(OverlappingPairCache pairCache, DispatcherInfo dispatchInfo)
|
||||
{
|
||||
CollisionPairCallback collisionCallback = new CollisionPairCallback(dispatchInfo, this);
|
||||
pairCache.ProcessAllOverlappingPairs(collisionCallback);
|
||||
}
|
||||
|
||||
private CollisionAlgorithmCreateFunction FindCreateFunction(BroadphaseNativeTypes proxyTypeA, BroadphaseNativeTypes proxyTypeB)
|
||||
{
|
||||
if (BroadphaseProxy.IsConvex(proxyTypeA) && BroadphaseProxy.IsConvex(proxyTypeB))
|
||||
{
|
||||
return _convexConvexCreateFunc;
|
||||
}
|
||||
|
||||
if (BroadphaseProxy.IsConvex(proxyTypeA) && BroadphaseProxy.IsConcave(proxyTypeB))
|
||||
{
|
||||
return _convexConcaveCreateFunc;
|
||||
}
|
||||
|
||||
if (BroadphaseProxy.IsConvex(proxyTypeB) && BroadphaseProxy.IsConcave(proxyTypeA))
|
||||
{
|
||||
return _swappedConvexConcaveCreateFunc;
|
||||
}
|
||||
|
||||
if (BroadphaseProxy.IsCompound(proxyTypeA))
|
||||
{
|
||||
return _compoundCreateFunc;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BroadphaseProxy.IsCompound(proxyTypeB))
|
||||
{
|
||||
return _swappedCompoundCreateFunc;
|
||||
}
|
||||
}
|
||||
|
||||
//failed to find an algorithm
|
||||
return _emptyCreateFunc;
|
||||
}
|
||||
|
||||
public NearCallback NearCallback { get { return _nearCallback; } set { _nearCallback = value; } }
|
||||
|
||||
//by default, Bullet will use this near callback
|
||||
public static void DefaultNearCallback(ref BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo)
|
||||
{
|
||||
CollisionObject collisionObjectA = collisionPair.ProxyA.ClientData as CollisionObject;
|
||||
CollisionObject collisionObjectB = collisionPair.ProxyB.ClientData as CollisionObject;
|
||||
|
||||
if (dispatcher.NeedsCollision(collisionObjectA, collisionObjectB))
|
||||
{
|
||||
//dispatcher will keep algorithms persistent in the collision pair
|
||||
if (collisionPair.CollisionAlgorithm == null)
|
||||
{
|
||||
collisionPair.CollisionAlgorithm = dispatcher.FindAlgorithm(collisionObjectA, collisionObjectB);
|
||||
}
|
||||
|
||||
if (collisionPair.CollisionAlgorithm != null)
|
||||
{
|
||||
ManifoldResult contactPointResult = new ManifoldResult(collisionObjectA, collisionObjectB);
|
||||
|
||||
if (dispatchInfo.DispatchFunction == DispatchFunction.Discrete)
|
||||
{
|
||||
//discrete collision detection query
|
||||
collisionPair.CollisionAlgorithm.ProcessCollision(collisionObjectA, collisionObjectB, dispatchInfo, contactPointResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
//continuous collision detection query, time of impact (toi)
|
||||
float timeOfImpact = collisionPair.CollisionAlgorithm.CalculateTimeOfImpact(collisionObjectA, collisionObjectB, dispatchInfo, contactPointResult);
|
||||
if (dispatchInfo.TimeOfImpact > timeOfImpact)
|
||||
dispatchInfo.TimeOfImpact = timeOfImpact;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public enum ActivationState
|
||||
{
|
||||
Nothing = 0,
|
||||
Active,
|
||||
IslandSleeping,
|
||||
WantsDeactivation,
|
||||
DisableDeactivation,
|
||||
DisableSimulation,
|
||||
}
|
||||
|
||||
public enum CollisionOptions
|
||||
{
|
||||
StaticObject = 1,
|
||||
KinematicObject = 2,
|
||||
NoContactResponse = 4,
|
||||
CustomMaterialCallback = 8,//this allows per-triangle material (friction/restitution)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// btCollisionObject can be used to manage collision detection objects.
|
||||
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
|
||||
/// They can be added to the btCollisionWorld.
|
||||
/// </summary>
|
||||
public class CollisionObject
|
||||
{
|
||||
protected Matrix _worldTransform;
|
||||
private BroadphaseProxy _broadphase;
|
||||
private CollisionShape _collisionShape;
|
||||
|
||||
//m_interpolationWorldTransform is used for CCD and interpolation
|
||||
//it can be either previous or future (predicted) transform
|
||||
private Matrix _interpolationWorldTransform;
|
||||
|
||||
private CollisionOptions _collisionFlags;
|
||||
|
||||
private int _islandTag;
|
||||
private ActivationState _activationState;
|
||||
private float _deactivationTime;
|
||||
|
||||
private float _friction;
|
||||
private float _restitution;
|
||||
|
||||
//users can point to their objects, m_userPointer is not used by Bullet
|
||||
private object _userData;
|
||||
|
||||
//m_internalOwner one is used by optional Bullet high level interface
|
||||
private object _internalOwner;
|
||||
|
||||
//time of impact calculation
|
||||
private float _hitFraction;
|
||||
|
||||
//Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
|
||||
private float _ccdSweptSphereRadius;
|
||||
|
||||
// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionTreshold
|
||||
private float _ccdSquareMotionThreshold;
|
||||
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
|
||||
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
|
||||
private Vector3 _interpolationLinearVelocity;
|
||||
private Vector3 _interpolationAngularVelocity;
|
||||
|
||||
private int _companionID;
|
||||
|
||||
public CollisionObject()
|
||||
{
|
||||
_activationState = ActivationState.Active;
|
||||
_hitFraction = 1;
|
||||
}
|
||||
|
||||
public bool IsStaticObject { get { return (_collisionFlags & CollisionOptions.StaticObject) != 0; } }
|
||||
public bool IsKinematicObject { get { return (_collisionFlags & CollisionOptions.KinematicObject) != 0; } }
|
||||
public bool IsStaticOrKinematicObject { get { return (_collisionFlags & (CollisionOptions.KinematicObject | CollisionOptions.StaticObject)) != 0; } }
|
||||
|
||||
public bool HasContactResponse { get { return (_collisionFlags & CollisionOptions.NoContactResponse) == 0; } }
|
||||
public bool MergesSimulationIslands
|
||||
{
|
||||
get
|
||||
{
|
||||
//static objects, kinematic and object without contact response don't merge islands
|
||||
return (_collisionFlags & (CollisionOptions.StaticObject | CollisionOptions.KinematicObject | CollisionOptions.NoContactResponse)) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
public ActivationState ActivationState
|
||||
{
|
||||
get { return _activationState; }
|
||||
set
|
||||
{
|
||||
if ((_activationState != ActivationState.DisableDeactivation) && (_activationState != ActivationState.DisableSimulation))
|
||||
_activationState = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsActive { get { return ((ActivationState != ActivationState.IslandSleeping) && (ActivationState != ActivationState.DisableSimulation)); } }
|
||||
public float Restitution { get { return _restitution; } set { _restitution = value; } }
|
||||
public float Friction { get { return _friction; } set { _friction = value; } }
|
||||
public CollisionShape CollisionShape { get { return _collisionShape; } set { _collisionShape = value; } }
|
||||
public float DeactivationTime { get { return _deactivationTime; } set { _deactivationTime = value; } }
|
||||
public object Owner { get { return _internalOwner; } protected set { _internalOwner = value; } }
|
||||
public Matrix WorldTransform { get { return _worldTransform; } set { _worldTransform = value; } }
|
||||
public BroadphaseProxy Broadphase { get { return _broadphase; } set { _broadphase = value; } }
|
||||
public Matrix InterpolationWorldTransform { get { return _interpolationWorldTransform; } set { _interpolationWorldTransform = value; } }
|
||||
public Vector3 InterpolationLinearVelocity { get { return _interpolationLinearVelocity; } protected set { _interpolationLinearVelocity = value; } }
|
||||
public Vector3 InterpolationAngularVelocity { get { return _interpolationAngularVelocity; } protected set { _interpolationAngularVelocity = value; } }
|
||||
public int IslandTag { get { return _islandTag; } set { _islandTag = value; } }
|
||||
public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
|
||||
public CollisionOptions CollisionFlags { get { return _collisionFlags; } set { _collisionFlags = value; } }
|
||||
//Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm
|
||||
public float CcdSweptSphereRadius { get { return _ccdSweptSphereRadius; } set { _ccdSweptSphereRadius = value; } }
|
||||
// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
|
||||
public float CcdSquareMotionThreshold { get { return _ccdSquareMotionThreshold; } set { _ccdSquareMotionThreshold = value; } }
|
||||
//users can point to their objects, userPointer is not used by Bullet
|
||||
public object UserData { get { return _userData; } set { _userData = value; } }
|
||||
public int CompanionID { get { return _companionID; } set { _companionID = value; } }
|
||||
|
||||
public void ForceActivationState(ActivationState newState)
|
||||
{
|
||||
_activationState = newState;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
Activate(false);
|
||||
}
|
||||
|
||||
public void Activate(bool forceActivation)
|
||||
{
|
||||
if (forceActivation || (_collisionFlags & (CollisionOptions.StaticObject | CollisionOptions.KinematicObject)) == 0)
|
||||
{
|
||||
ActivationState = ActivationState.Active;
|
||||
_deactivationTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class CollisionPairCallback : IOverlapCallback
|
||||
{
|
||||
private DispatcherInfo _dispatchInfo;
|
||||
private CollisionDispatcher _dispatcher;
|
||||
|
||||
public CollisionPairCallback(DispatcherInfo dispatchInfo, CollisionDispatcher dispatcher)
|
||||
{
|
||||
_dispatchInfo = dispatchInfo;
|
||||
_dispatcher = dispatcher;
|
||||
}
|
||||
|
||||
#region IOverlapCallback Members
|
||||
public bool ProcessOverlap(ref BroadphasePair pair)
|
||||
{
|
||||
_dispatcher.NearCallback(ref pair, _dispatcher, _dispatchInfo);
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,358 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class CollisionWorld
|
||||
{
|
||||
private List<CollisionObject> _collisionObjects = new List<CollisionObject>();
|
||||
private IDispatcher _dispatcher;
|
||||
private OverlappingPairCache _broadphasePairCache;
|
||||
private bool _ownsDispatcher;
|
||||
private bool _ownsBroadphasePairCache;
|
||||
private DispatcherInfo _dispatchInfo = new DispatcherInfo();
|
||||
|
||||
/// <summary>
|
||||
/// this constructor doesn't own the dispatcher and paircache/broadphase
|
||||
/// </summary>
|
||||
/// <param name="dispatcher"></param>
|
||||
/// <param name="pairCache"></param>
|
||||
public CollisionWorld(IDispatcher dispatcher, OverlappingPairCache pairCache)
|
||||
{
|
||||
_dispatcher = dispatcher;
|
||||
_broadphasePairCache = pairCache;
|
||||
_ownsDispatcher = false;
|
||||
_ownsBroadphasePairCache = false;
|
||||
}
|
||||
|
||||
public DispatcherInfo DispatchInfo { get { return _dispatchInfo; } protected set { _dispatchInfo = value; } }
|
||||
public List<CollisionObject> CollisionObjects { get { return _collisionObjects; } protected set { _collisionObjects = value; } }
|
||||
public IBroadphase Broadphase { get { return _broadphasePairCache; } }
|
||||
public OverlappingPairCache BroadphasePairCache { get { return _broadphasePairCache; } protected set { _broadphasePairCache = value; } }
|
||||
public IDispatcher Dispatcher { get { return _dispatcher; } protected set { _dispatcher = value; } }
|
||||
public int CollisionObjectsCount { get { return _collisionObjects.Count; } }
|
||||
protected bool OwnsDispatcher { get { return _ownsDispatcher; } set { _ownsDispatcher = value; } }
|
||||
protected bool OwnsBroadphasePairCache { get { return _ownsBroadphasePairCache; } set { _ownsBroadphasePairCache = value; } }
|
||||
|
||||
// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
|
||||
// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
|
||||
public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback)
|
||||
{
|
||||
Matrix rayFromTrans, rayToTrans;
|
||||
|
||||
rayFromTrans = Matrix.Identity;
|
||||
rayFromTrans.Translation = rayFromWorld;
|
||||
|
||||
rayToTrans = Matrix.Identity;
|
||||
rayToTrans.Translation = rayToWorld;
|
||||
|
||||
// brute force go over all objects. Once there is a broadphase, use that, or
|
||||
// add a raycast against aabb first.
|
||||
|
||||
foreach (CollisionObject collisionObject in _collisionObjects)
|
||||
{
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
Vector3 collisionObjectAabbMin, collisionObjectAabbMax;
|
||||
collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax);
|
||||
|
||||
float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing
|
||||
Vector3 hitNormal = new Vector3();
|
||||
|
||||
//if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax))
|
||||
if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal))
|
||||
{
|
||||
RayTestSingle(rayFromTrans, rayToTrans,
|
||||
collisionObject, collisionObject.CollisionShape,
|
||||
collisionObject.WorldTransform, resultCallback);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
|
||||
// In a future implementation, we consider moving the ray test as a virtual method in CollisionShape.
|
||||
// This allows more customization.
|
||||
public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans,
|
||||
CollisionObject collisionObject,
|
||||
CollisionShape collisionShape,
|
||||
Matrix colObjWorldTransform,
|
||||
RayResultCallback resultCallback)
|
||||
{
|
||||
SphereShape pointShape=new SphereShape(0.0f);
|
||||
|
||||
if (collisionShape.IsConvex)
|
||||
{
|
||||
CastResult castResult = new CastResult();
|
||||
castResult.Fraction = 1f;//??
|
||||
|
||||
ConvexShape convexShape = collisionShape as ConvexShape;
|
||||
VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
|
||||
SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver);
|
||||
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
|
||||
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
|
||||
|
||||
if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult))
|
||||
{
|
||||
//add hit
|
||||
if (castResult.Normal.LengthSquared() > 0.0001f)
|
||||
{
|
||||
castResult.Normal.Normalize();
|
||||
if (castResult.Fraction < resultCallback.ClosestHitFraction)
|
||||
{
|
||||
|
||||
CollisionWorld.LocalRayResult localRayResult = new LocalRayResult
|
||||
(
|
||||
collisionObject,
|
||||
new LocalShapeInfo(),
|
||||
castResult.Normal,
|
||||
castResult.Fraction
|
||||
);
|
||||
|
||||
resultCallback.AddSingleResult(localRayResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (collisionShape.IsConcave)
|
||||
{
|
||||
|
||||
TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape;
|
||||
|
||||
Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform);
|
||||
|
||||
Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject);
|
||||
Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject);
|
||||
|
||||
BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh);
|
||||
rcb.HitFraction = resultCallback.ClosestHitFraction;
|
||||
|
||||
Vector3 rayAabbMinLocal = rayFromLocal;
|
||||
MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal);
|
||||
Vector3 rayAabbMaxLocal = rayFromLocal;
|
||||
MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal);
|
||||
|
||||
triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
//todo: use AABB tree or other BVH acceleration structure!
|
||||
if (collisionShape.IsCompound)
|
||||
{
|
||||
CompoundShape compoundShape = collisionShape as CompoundShape;
|
||||
for (int i = 0; i < compoundShape.ChildShapeCount; i++)
|
||||
{
|
||||
Matrix childTrans = compoundShape.GetChildTransform(i);
|
||||
CollisionShape childCollisionShape = compoundShape.GetChildShape(i);
|
||||
Matrix childWorldTrans = colObjWorldTransform * childTrans;
|
||||
RayTestSingle(rayFromTrans, rayToTrans,
|
||||
collisionObject,
|
||||
childCollisionShape,
|
||||
childWorldTrans,
|
||||
resultCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollisionObject(CollisionObject collisionObject, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
|
||||
{
|
||||
//check that the object isn't already added
|
||||
if (!_collisionObjects.Contains(collisionObject))
|
||||
{
|
||||
_collisionObjects.Add(collisionObject);
|
||||
|
||||
//calculate new AABB
|
||||
Matrix trans = collisionObject.WorldTransform;
|
||||
|
||||
Vector3 minAabb;
|
||||
Vector3 maxAabb;
|
||||
collisionObject.CollisionShape.GetAabb(trans, out minAabb, out maxAabb);
|
||||
|
||||
BroadphaseNativeTypes type = collisionObject.CollisionShape.ShapeType;
|
||||
collisionObject.Broadphase = Broadphase.CreateProxy(
|
||||
minAabb,
|
||||
maxAabb,
|
||||
type,
|
||||
collisionObject,
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollisionObject(CollisionObject collisionObject)
|
||||
{
|
||||
AddCollisionObject(collisionObject, BroadphaseProxy.CollisionFilterGroups.Default, BroadphaseProxy.CollisionFilterGroups.Default);
|
||||
}
|
||||
|
||||
public void RemoveCollisionObject(CollisionObject collisionObject)
|
||||
{
|
||||
BroadphaseProxy bp = collisionObject.Broadphase;
|
||||
if (bp != null)
|
||||
{
|
||||
//
|
||||
// only clear the cached algorithms
|
||||
//
|
||||
Broadphase.CleanProxyFromPairs(bp);
|
||||
Broadphase.DestroyProxy(bp);
|
||||
collisionObject.Broadphase = null;
|
||||
}
|
||||
|
||||
_collisionObjects.Remove(collisionObject);
|
||||
}
|
||||
|
||||
public virtual void PerformDiscreteCollisionDetection()
|
||||
{
|
||||
DispatcherInfo dispatchInfo = DispatchInfo;
|
||||
//update aabb (of all moved objects)
|
||||
|
||||
Vector3 aabbMin, aabbMax;
|
||||
for (int i = 0; i < _collisionObjects.Count; i++)
|
||||
{
|
||||
_collisionObjects[i].CollisionShape.GetAabb(_collisionObjects[i].WorldTransform, out aabbMin, out aabbMax);
|
||||
_broadphasePairCache.SetAabb(_collisionObjects[i].Broadphase, aabbMin, aabbMax);
|
||||
}
|
||||
|
||||
_broadphasePairCache.RefreshOverlappingPairs();
|
||||
|
||||
IDispatcher dispatcher = Dispatcher;
|
||||
if (dispatcher != null)
|
||||
dispatcher.DispatchAllCollisionPairs(_broadphasePairCache, dispatchInfo);
|
||||
}
|
||||
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
//clean up remaining objects
|
||||
foreach (CollisionObject collisionObject in _collisionObjects)
|
||||
{
|
||||
BroadphaseProxy bp = collisionObject.Broadphase;
|
||||
if (bp != null)
|
||||
{
|
||||
//
|
||||
// only clear the cached algorithms
|
||||
//
|
||||
Broadphase.CleanProxyFromPairs(bp);
|
||||
Broadphase.DestroyProxy(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LocalShapeInfo gives extra information for complex shapes
|
||||
/// Currently, only TriangleMeshShape is available, so it just contains triangleIndex and subpart
|
||||
/// </summary>
|
||||
public struct LocalShapeInfo
|
||||
{
|
||||
private int _shapePart;
|
||||
private int _triangleIndex;
|
||||
|
||||
public int ShapePart { get { return _shapePart; } set { _shapePart = value; } }
|
||||
public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } }
|
||||
}
|
||||
|
||||
public struct LocalRayResult
|
||||
{
|
||||
private CollisionObject _collisionObject;
|
||||
private LocalShapeInfo _localShapeInfo;
|
||||
private Vector3 _hitNormalLocal;
|
||||
private float _hitFraction;
|
||||
|
||||
public LocalRayResult(CollisionObject collisionObject,
|
||||
LocalShapeInfo localShapeInfo,
|
||||
Vector3 hitNormalLocal,
|
||||
float hitFraction)
|
||||
{
|
||||
_collisionObject = collisionObject;
|
||||
_localShapeInfo = localShapeInfo;
|
||||
_hitNormalLocal = hitNormalLocal;
|
||||
_hitFraction = hitFraction;
|
||||
}
|
||||
|
||||
public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } }
|
||||
public LocalShapeInfo LocalShapeInfo { get { return _localShapeInfo; } set { _localShapeInfo = value; } }
|
||||
public Vector3 HitNormalLocal { get { return _hitNormalLocal; } set { _hitNormalLocal = value; } }
|
||||
public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RayResultCallback is used to report new raycast results
|
||||
/// </summary>
|
||||
public abstract class RayResultCallback
|
||||
{
|
||||
private float _closestHitFraction;
|
||||
|
||||
public RayResultCallback()
|
||||
{
|
||||
_closestHitFraction = 1;
|
||||
}
|
||||
|
||||
public float ClosestHitFraction { get { return _closestHitFraction; } set { _closestHitFraction = value; } }
|
||||
public bool HasHit { get { return _closestHitFraction < 1; } }
|
||||
|
||||
public abstract float AddSingleResult(LocalRayResult rayResult);
|
||||
}
|
||||
|
||||
public class ClosestRayResultCallback : RayResultCallback
|
||||
{
|
||||
private Vector3 _rayFromWorld;//used to calculate hitPointWorld from hitFraction
|
||||
private Vector3 _rayToWorld;
|
||||
|
||||
private Vector3 _hitNormalWorld;
|
||||
private Vector3 _hitPointWorld;
|
||||
private CollisionObject _collisionObject;
|
||||
|
||||
public ClosestRayResultCallback(Vector3 rayFromWorld, Vector3 rayToWorld)
|
||||
{
|
||||
_rayFromWorld = rayFromWorld;
|
||||
_rayToWorld = rayToWorld;
|
||||
_collisionObject = null;
|
||||
}
|
||||
|
||||
public Vector3 RayFromWorld { get { return _rayFromWorld; } set { _rayFromWorld = value; } }
|
||||
public Vector3 RayToWorld { get { return _rayToWorld; } set { _rayToWorld = value; } }
|
||||
public Vector3 HitNormalWorld { get { return _hitNormalWorld; } set { _hitNormalWorld = value; } }
|
||||
public Vector3 HitPointWorld { get { return _hitPointWorld; } set { _hitPointWorld = value; } }
|
||||
public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } }
|
||||
|
||||
public override float AddSingleResult(LocalRayResult rayResult)
|
||||
{
|
||||
//caller already does the filter on the m_closestHitFraction
|
||||
//assert(rayResult.m_hitFraction <= m_closestHitFraction);
|
||||
ClosestHitFraction = rayResult.HitFraction;
|
||||
_collisionObject = rayResult.CollisionObject;
|
||||
_hitNormalWorld = Vector3.TransformNormal(rayResult.HitNormalLocal, _collisionObject.WorldTransform);
|
||||
MathHelper.SetInterpolate3(_rayFromWorld, _rayToWorld, rayResult.HitFraction, ref _hitPointWorld);
|
||||
return rayResult.HitFraction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class CompoundCollisionAlgorithm : CollisionAlgorithm
|
||||
{
|
||||
private List<CollisionAlgorithm> _childCollisionAlgorithms;
|
||||
private bool _isSwapped;
|
||||
|
||||
public CompoundCollisionAlgorithm(
|
||||
CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo,
|
||||
CollisionObject bodyA,
|
||||
CollisionObject bodyB, bool isSwapped)
|
||||
: base(collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
//Begin
|
||||
_isSwapped = isSwapped;
|
||||
|
||||
CollisionObject collisionObject = isSwapped ? bodyB : bodyA;
|
||||
CollisionObject otherObject = isSwapped ? bodyA : bodyB;
|
||||
|
||||
BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);
|
||||
|
||||
CompoundShape compoundShape = collisionObject.CollisionShape as CompoundShape;
|
||||
int childrenNumber = compoundShape.ChildShapeCount;
|
||||
int index = 0;
|
||||
|
||||
_childCollisionAlgorithms = new List<CollisionAlgorithm>(childrenNumber);
|
||||
|
||||
for (index = 0; index < childrenNumber; index++)
|
||||
{
|
||||
CollisionShape childShape = compoundShape.GetChildShape(index);
|
||||
CollisionShape orgShape = collisionObject.CollisionShape;
|
||||
|
||||
collisionObject.CollisionShape = childShape;
|
||||
_childCollisionAlgorithms[index] = collisionAlgorithmConstructionInfo.Dispatcher.FindAlgorithm(collisionObject, otherObject);
|
||||
collisionObject.CollisionShape = orgShape;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessCollision(
|
||||
CollisionObject bodyA,
|
||||
CollisionObject bodyB,
|
||||
DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
//Begin
|
||||
|
||||
CollisionObject collisionObject = _isSwapped ? bodyB : bodyB;
|
||||
CollisionObject otherObject = _isSwapped ? bodyA : bodyB;
|
||||
|
||||
//Debug.Assert(collisionObject.getCollisionShape().isCompound());
|
||||
BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);
|
||||
|
||||
CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;
|
||||
|
||||
int childrenNumber = _childCollisionAlgorithms.Count;
|
||||
|
||||
for (int i = 0; i < childrenNumber; i++)
|
||||
{
|
||||
CompoundShape childShape = compoundShape.GetChildShape(i) as CompoundShape;
|
||||
|
||||
Matrix orgTransform = collisionObject.WorldTransform;
|
||||
CollisionShape orgShape = collisionObject.CollisionShape;
|
||||
|
||||
Matrix childTransform = compoundShape.GetChildTransform(i);
|
||||
Matrix newChildWorld = orgTransform * childTransform;
|
||||
|
||||
collisionObject.WorldTransform = newChildWorld;
|
||||
collisionObject.CollisionShape = childShape;
|
||||
_childCollisionAlgorithms[i].ProcessCollision(collisionObject, otherObject, dispatchInfo, resultOut);
|
||||
|
||||
collisionObject.CollisionShape = orgShape;
|
||||
collisionObject.WorldTransform = orgTransform;
|
||||
}
|
||||
}
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
CollisionObject collisionObject = _isSwapped ? bodyB : bodyA;
|
||||
CollisionObject otherObject = _isSwapped ? bodyA : bodyB;
|
||||
|
||||
BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);
|
||||
|
||||
CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;
|
||||
|
||||
float hitFraction = 1.0f;
|
||||
|
||||
for (int i = 0; i < _childCollisionAlgorithms.Count; i++)
|
||||
{
|
||||
CollisionShape childShape = compoundShape.GetChildShape(i);
|
||||
|
||||
Matrix orgTransform = collisionObject.WorldTransform;
|
||||
CollisionShape orgShape = collisionObject.CollisionShape;
|
||||
|
||||
Matrix childTransform = compoundShape.GetChildTransform(i);
|
||||
Matrix newChildWorld = orgTransform * childTransform;
|
||||
collisionObject.WorldTransform = newChildWorld;
|
||||
|
||||
collisionObject.CollisionShape = childShape;
|
||||
float frac = _childCollisionAlgorithms[i].CalculateTimeOfImpact(
|
||||
collisionObject, otherObject, dispatchInfo, resultOut
|
||||
);
|
||||
|
||||
if (frac < hitFraction)
|
||||
{
|
||||
hitFraction = frac;
|
||||
}
|
||||
|
||||
collisionObject.CollisionShape = orgShape;
|
||||
collisionObject.WorldTransform = orgTransform;
|
||||
}
|
||||
|
||||
return hitFraction;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new CompoundCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
|
||||
}
|
||||
};
|
||||
|
||||
public class SwappedCreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new CompoundCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class ConvexConcaveCollisionAlgorithm : CollisionAlgorithm
|
||||
{
|
||||
private bool _isSwapped;
|
||||
private ConvexTriangleCallback _convexTriangleCallback;
|
||||
|
||||
public ConvexConcaveCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
|
||||
: base(collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
_isSwapped = isSwapped;
|
||||
_convexTriangleCallback = new ConvexTriangleCallback(collisionAlgorithmConstructionInfo.Dispatcher, bodyA, bodyB, isSwapped);
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
_convexTriangleCallback.ClearCache();
|
||||
}
|
||||
|
||||
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
CollisionObject convexBody = _isSwapped ? bodyB : bodyA;
|
||||
CollisionObject triBody = _isSwapped ? bodyA : bodyB;
|
||||
|
||||
if (triBody.CollisionShape.IsConcave)
|
||||
{
|
||||
CollisionObject triOb = triBody;
|
||||
ConcaveShape concaveShape = triOb.CollisionShape as ConcaveShape;
|
||||
|
||||
if (convexBody.CollisionShape.IsConvex)
|
||||
{
|
||||
float collisionMarginTriangle = concaveShape.Margin;
|
||||
|
||||
resultOut.SetPersistentManifold(_convexTriangleCallback.Manifold);
|
||||
_convexTriangleCallback.SetTimeStepAndCounters(collisionMarginTriangle, dispatchInfo, resultOut);
|
||||
|
||||
//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
|
||||
//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
|
||||
|
||||
_convexTriangleCallback.Manifold.SetBodies(convexBody, triBody);
|
||||
concaveShape.ProcessAllTriangles(_convexTriangleCallback, _convexTriangleCallback.AabbMin, _convexTriangleCallback.AabbMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
CollisionObject convexbody = _isSwapped ? bodyB : bodyA;
|
||||
CollisionObject triBody = _isSwapped ? bodyA : bodyB;
|
||||
|
||||
|
||||
//quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
|
||||
|
||||
//only perform CCD above a certain threshold, this prevents blocking on the long run
|
||||
//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
|
||||
float squareMot0 = (convexbody.InterpolationWorldTransform.Translation - convexbody.WorldTransform.Translation).LengthSquared();
|
||||
if (squareMot0 < convexbody.CcdSquareMotionThreshold)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Matrix triInv = MathHelper.InvertMatrix(triBody.WorldTransform);
|
||||
Matrix convexFromLocal = triInv * convexbody.WorldTransform;
|
||||
Matrix convexToLocal = triInv * convexbody.InterpolationWorldTransform;
|
||||
|
||||
if (triBody.CollisionShape.IsConcave)
|
||||
{
|
||||
Vector3 rayAabbMin = convexFromLocal.Translation;
|
||||
MathHelper.SetMin(ref rayAabbMin, convexToLocal.Translation);
|
||||
Vector3 rayAabbMax = convexFromLocal.Translation;
|
||||
MathHelper.SetMax(ref rayAabbMax, convexToLocal.Translation);
|
||||
float ccdRadius0 = convexbody.CcdSweptSphereRadius;
|
||||
rayAabbMin -= new Vector3(ccdRadius0, ccdRadius0, ccdRadius0);
|
||||
rayAabbMax += new Vector3(ccdRadius0, ccdRadius0, ccdRadius0);
|
||||
|
||||
float curHitFraction = 1f; //is this available?
|
||||
LocalTriangleSphereCastCallback raycastCallback = new LocalTriangleSphereCastCallback(convexFromLocal, convexToLocal,
|
||||
convexbody.CcdSweptSphereRadius, curHitFraction);
|
||||
|
||||
raycastCallback.HitFraction = convexbody.HitFraction;
|
||||
|
||||
CollisionObject concavebody = triBody;
|
||||
|
||||
ConcaveShape triangleMesh = concavebody.CollisionShape as ConcaveShape;
|
||||
|
||||
if (triangleMesh != null)
|
||||
{
|
||||
triangleMesh.ProcessAllTriangles(raycastCallback, rayAabbMin, rayAabbMax);
|
||||
}
|
||||
|
||||
if (raycastCallback.HitFraction < convexbody.HitFraction)
|
||||
{
|
||||
convexbody.HitFraction = raycastCallback.HitFraction;
|
||||
return raycastCallback.HitFraction;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new ConvexConcaveCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
|
||||
}
|
||||
}
|
||||
|
||||
public class SwappedCreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new ConvexConcaveCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalTriangleSphereCastCallback : ITriangleCallback
|
||||
{
|
||||
private Matrix _ccdSphereFromTrans;
|
||||
private Matrix _ccdSphereToTrans;
|
||||
private Matrix _meshTransform;
|
||||
|
||||
private float _ccdSphereRadius;
|
||||
private float _hitFraction;
|
||||
|
||||
public LocalTriangleSphereCastCallback(Matrix from, Matrix to, float ccdSphereRadius, float hitFraction)
|
||||
{
|
||||
_ccdSphereFromTrans = from;
|
||||
_ccdSphereToTrans = to;
|
||||
_ccdSphereRadius = ccdSphereRadius;
|
||||
_hitFraction = hitFraction;
|
||||
}
|
||||
|
||||
public Matrix CcdSphereFromTrans { get { return _ccdSphereFromTrans; } set { _ccdSphereFromTrans = value; } }
|
||||
public Matrix CcdSphereToTrans { get { return _ccdSphereToTrans; } set { _ccdSphereToTrans = value; } }
|
||||
public Matrix MeshTransform { get { return _meshTransform; } set { _meshTransform = value; } }
|
||||
public float CcdSphereRadius { get { return _ccdSphereRadius; } set { _ccdSphereRadius = value; } }
|
||||
public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
|
||||
|
||||
public void ProcessTriangle(Vector3[] triangle, int partId, int triangleIndex)
|
||||
{
|
||||
//do a swept sphere for now
|
||||
Matrix ident = Matrix.Identity;
|
||||
CastResult castResult = new CastResult();
|
||||
castResult.Fraction = _hitFraction;
|
||||
SphereShape pointShape = new SphereShape(_ccdSphereRadius);
|
||||
TriangleShape triShape = new TriangleShape(triangle[0], triangle[1], triangle[2]);
|
||||
VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
|
||||
SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, triShape, simplexSolver);
|
||||
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
|
||||
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
|
||||
//local space?
|
||||
|
||||
if (convexCaster.CalcTimeOfImpact(_ccdSphereFromTrans, _ccdSphereToTrans,
|
||||
ident, ident, castResult))
|
||||
{
|
||||
if (_hitFraction > castResult.Fraction)
|
||||
_hitFraction = castResult.Fraction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class ConvexConvexAlgorithm : CollisionAlgorithm, IDisposable
|
||||
{
|
||||
private const bool DisableCcd = false;
|
||||
private GjkPairDetector _gjkPairDetector;
|
||||
private bool _ownManifold;
|
||||
private PersistentManifold _manifold;
|
||||
private bool _lowLevelOfDetail;
|
||||
|
||||
public ConvexConvexAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
|
||||
: base(collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
_gjkPairDetector = new GjkPairDetector(null, null, simplexSolver, penetrationDepthSolver);
|
||||
_ownManifold = false;
|
||||
_manifold = manifold;
|
||||
_lowLevelOfDetail = false;
|
||||
}
|
||||
|
||||
public bool LowLevelOfDetail { get { return _lowLevelOfDetail; } set { _lowLevelOfDetail = value; } }
|
||||
public bool OwnManifold { get { return _ownManifold; } set { _ownManifold = value; } }
|
||||
public PersistentManifold Manifold { get { return _manifold; } set { _manifold = value; } }
|
||||
|
||||
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
if (_manifold == null)
|
||||
{
|
||||
//swapped?
|
||||
_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
|
||||
_ownManifold = true;
|
||||
}
|
||||
resultOut.SetPersistentManifold(_manifold);
|
||||
|
||||
ConvexShape min0 = bodyA.CollisionShape as ConvexShape;
|
||||
ConvexShape min1 = bodyB.CollisionShape as ConvexShape;
|
||||
|
||||
GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
|
||||
|
||||
//TODO: if (dispatchInfo.m_useContinuous)
|
||||
_gjkPairDetector.setMinkowskiA(min0);
|
||||
_gjkPairDetector.setMinkowskiB(min1);
|
||||
input.MaximumDistanceSquared = min0.Margin + min1.Margin + PersistentManifold.ContactBreakingThreshold;
|
||||
input.MaximumDistanceSquared *= input.MaximumDistanceSquared;
|
||||
|
||||
// input.m_maximumDistanceSquared = 1e30f;
|
||||
|
||||
input.TransformA = bodyA.WorldTransform;
|
||||
input.TransformB = bodyB.WorldTransform;
|
||||
|
||||
_gjkPairDetector.GetClosestPoints(input, resultOut, dispatchInfo.DebugDraw);
|
||||
}
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
//Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
|
||||
|
||||
//Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
|
||||
//col0->m_worldTransform,
|
||||
float resultFraction = 1f;
|
||||
|
||||
float squareMotA = (colA.InterpolationWorldTransform.Translation - colA.WorldTransform.Translation).LengthSquared();
|
||||
float squareMotB = (colB.InterpolationWorldTransform.Translation - colB.WorldTransform.Translation).LengthSquared();
|
||||
|
||||
if (squareMotA < colA.CcdSquareMotionThreshold &&
|
||||
squareMotB < colB.CcdSquareMotionThreshold)
|
||||
return resultFraction;
|
||||
|
||||
if (DisableCcd)
|
||||
return 1f;
|
||||
|
||||
//An adhoc way of testing the Continuous Collision Detection algorithms
|
||||
//One object is approximated as a sphere, to simplify things
|
||||
//Starting in penetration should report no time of impact
|
||||
//For proper CCD, better accuracy and handling of 'allowed' penetration should be added
|
||||
//also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)
|
||||
|
||||
// Convex0 against sphere for Convex1
|
||||
{
|
||||
ConvexShape convexA = colA.CollisionShape as ConvexShape;
|
||||
|
||||
SphereShape sphereB = new SphereShape(colB.CcdSweptSphereRadius); //todo: allow non-zero sphere sizes, for better approximation
|
||||
CastResult result = new CastResult();
|
||||
VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
|
||||
//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
|
||||
//Simplification, one object is simplified as a sphere
|
||||
GjkConvexCast ccdB = new GjkConvexCast(convexA, sphereB, voronoiSimplex);
|
||||
//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
|
||||
if (ccdB.CalcTimeOfImpact(colA.WorldTransform, colA.InterpolationWorldTransform,
|
||||
colB.WorldTransform, colB.InterpolationWorldTransform, result))
|
||||
{
|
||||
//store result.m_fraction in both bodies
|
||||
if (colA.HitFraction > result.Fraction)
|
||||
colA.HitFraction = result.Fraction;
|
||||
|
||||
if (colB.HitFraction > result.Fraction)
|
||||
colB.HitFraction = result.Fraction;
|
||||
|
||||
if (resultFraction > result.Fraction)
|
||||
resultFraction = result.Fraction;
|
||||
}
|
||||
}
|
||||
|
||||
// Sphere (for convex0) against Convex1
|
||||
{
|
||||
ConvexShape convexB = colB.CollisionShape as ConvexShape;
|
||||
|
||||
SphereShape sphereA = new SphereShape(colA.CcdSweptSphereRadius); //todo: allow non-zero sphere sizes, for better approximation
|
||||
CastResult result = new CastResult();
|
||||
VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
|
||||
//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
|
||||
///Simplification, one object is simplified as a sphere
|
||||
GjkConvexCast ccdB = new GjkConvexCast(sphereA, convexB, voronoiSimplex);
|
||||
//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
|
||||
if (ccdB.CalcTimeOfImpact(colA.WorldTransform, colA.InterpolationWorldTransform,
|
||||
colB.WorldTransform, colB.InterpolationWorldTransform, result))
|
||||
{
|
||||
//store result.m_fraction in both bodies
|
||||
if (colA.HitFraction > result.Fraction)
|
||||
colA.HitFraction = result.Fraction;
|
||||
|
||||
if (colB.HitFraction > result.Fraction)
|
||||
colB.HitFraction = result.Fraction;
|
||||
|
||||
if (resultFraction > result.Fraction)
|
||||
resultFraction = result.Fraction;
|
||||
}
|
||||
}
|
||||
return resultFraction;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
private IConvexPenetrationDepthSolver _penetrationDepthSolver;
|
||||
private ISimplexSolver _simplexSolver;
|
||||
//private bool _ownsSolvers;
|
||||
|
||||
public CreateFunc()
|
||||
{
|
||||
//_ownsSolvers = true;
|
||||
_simplexSolver = new VoronoiSimplexSolver();
|
||||
_penetrationDepthSolver = new GjkEpaPenetrationDepthSolver();
|
||||
}
|
||||
|
||||
public CreateFunc(ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
|
||||
{
|
||||
//_ownsSolvers = false;
|
||||
_simplexSolver = simplexSolver;
|
||||
_penetrationDepthSolver = penetrationDepthSolver;
|
||||
}
|
||||
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new ConvexConvexAlgorithm(collisionAlgorithmConstructionInfo.Manifold, collisionAlgorithmConstructionInfo, bodyA, bodyB, _simplexSolver, _penetrationDepthSolver);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
public void Dispose()
|
||||
{
|
||||
if (_ownManifold)
|
||||
{
|
||||
if (_manifold != null)
|
||||
Dispatcher.ReleaseManifold(_manifold);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class ConvexTriangleCallback : ITriangleCallback, IDisposable
|
||||
{
|
||||
private CollisionObject _convexBody;
|
||||
private CollisionObject _triBody;
|
||||
|
||||
private Vector3 _aabbMin;
|
||||
private Vector3 _aabbMax;
|
||||
|
||||
private ManifoldResult _resultOut;
|
||||
|
||||
private IDispatcher _dispatcher;
|
||||
private DispatcherInfo _dispatchInfo;
|
||||
private float _collisionMarginTriangle;
|
||||
|
||||
private int _triangleCount;
|
||||
|
||||
private PersistentManifold _manifold;
|
||||
|
||||
public ConvexTriangleCallback(IDispatcher dispatcher, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
|
||||
{
|
||||
_dispatcher = dispatcher;
|
||||
_dispatchInfo = null;
|
||||
_convexBody = isSwapped ? bodyB : bodyA;
|
||||
_triBody = isSwapped ? bodyA : bodyB;
|
||||
|
||||
// create the manifold from the dispatcher 'manifold pool'
|
||||
_manifold = _dispatcher.GetNewManifold(_convexBody, _triBody);
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
public Vector3 AabbMin { get { return _aabbMin; } }
|
||||
public Vector3 AabbMax { get { return _aabbMax; } }
|
||||
public int TriangleCount { get { return _triangleCount; } set { _triangleCount = value; } }
|
||||
public PersistentManifold Manifold { get { return _manifold; } set { _manifold = value; } }
|
||||
|
||||
public void SetTimeStepAndCounters(float collisionMarginTriangle, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
_dispatchInfo = dispatchInfo;
|
||||
_collisionMarginTriangle = collisionMarginTriangle;
|
||||
_resultOut = resultOut;
|
||||
|
||||
//recalc aabbs
|
||||
Matrix convexInTriangleSpace = MathHelper.InvertMatrix(_triBody.WorldTransform) * _convexBody.WorldTransform;
|
||||
CollisionShape convexShape = _convexBody.CollisionShape;
|
||||
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
|
||||
convexShape.GetAabb(convexInTriangleSpace, out _aabbMin, out _aabbMax);
|
||||
float extraMargin = collisionMarginTriangle;
|
||||
Vector3 extra = new Vector3(extraMargin, extraMargin, extraMargin);
|
||||
|
||||
_aabbMax += extra;
|
||||
_aabbMin -= extra;
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
_dispatcher.ClearManifold(_manifold);
|
||||
}
|
||||
|
||||
#region ITriangleCallback Members
|
||||
public void ProcessTriangle(Vector3[] triangle, int partID, int triangleIndex)
|
||||
{
|
||||
//aabb filter is already applied!
|
||||
CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo = new CollisionAlgorithmConstructionInfo();
|
||||
collisionAlgorithmConstructionInfo.Dispatcher = _dispatcher;
|
||||
|
||||
CollisionObject collisionObject = _triBody;
|
||||
|
||||
//debug drawing of the overlapping triangles
|
||||
/*if (m_dispatchInfoPtr && m_dispatchInfoPtr.m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)
|
||||
{
|
||||
Vector3 color = new Vector3(255, 255, 0);
|
||||
btTransform & tr = ob->WorldTransform;
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]), tr(triangle[1]), color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]), tr(triangle[2]), color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]), tr(triangle[0]), color);
|
||||
}*/
|
||||
|
||||
if (_convexBody.CollisionShape.IsConvex)
|
||||
{
|
||||
TriangleShape triangleShape = new TriangleShape(triangle[0], triangle[1], triangle[2]);
|
||||
triangleShape.Margin=_collisionMarginTriangle;
|
||||
|
||||
CollisionShape tempShape = collisionObject.CollisionShape;
|
||||
collisionObject.CollisionShape = triangleShape;
|
||||
|
||||
CollisionAlgorithm collisionAlgorithm = collisionAlgorithmConstructionInfo.Dispatcher.FindAlgorithm(_convexBody, _triBody, _manifold);
|
||||
|
||||
_resultOut.SetShapeIdentifiers(-1, -1, partID, triangleIndex);
|
||||
collisionAlgorithm.ProcessCollision(_convexBody, _triBody, _dispatchInfo, _resultOut);
|
||||
collisionObject.CollisionShape = tempShape;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region IDisposable Members
|
||||
public void Dispose()
|
||||
{
|
||||
ClearCache();
|
||||
_dispatcher.ReleaseManifold(_manifold);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// EmptyAlgorithm is a stub for unsupported collision pairs.
|
||||
/// The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame.
|
||||
/// </summary>
|
||||
public class EmptyAlgorithm : CollisionAlgorithm
|
||||
{
|
||||
public EmptyAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
|
||||
: base(collisionAlgorithmConstructionInfo) { }
|
||||
|
||||
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { }
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new EmptyAlgorithm(collisionAlgorithmConstructionInfo);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public delegate bool ContactAddedCallback(ManifoldPoint contactPoint, CollisionObject collisionObjectA, int partIdA, int indexA, CollisionObject collisionObjectB, int partIdB, int indexB);
|
||||
|
||||
public class ManifoldResult : DiscreteCollisionDetectorInterface.Result
|
||||
{
|
||||
private PersistentManifold _manifold;
|
||||
private static ContactAddedCallback _contactAddedCallback = null;
|
||||
|
||||
//we need this for compounds
|
||||
private Matrix _rootTransA;
|
||||
private Matrix _rootTransB;
|
||||
|
||||
private CollisionObject _bodyA;
|
||||
private CollisionObject _bodyB;
|
||||
private int _partIdA;
|
||||
private int _partIdB;
|
||||
private int _indexA;
|
||||
private int _indexB;
|
||||
|
||||
public ManifoldResult()
|
||||
{
|
||||
}
|
||||
|
||||
public ManifoldResult(CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
_bodyA = bodyA;
|
||||
_bodyB = bodyB;
|
||||
_rootTransA = bodyA.WorldTransform;
|
||||
_rootTransB = bodyB.WorldTransform;
|
||||
}
|
||||
|
||||
public static ContactAddedCallback ContactAddedCallback { get { return _contactAddedCallback; } set { _contactAddedCallback = value; } }
|
||||
|
||||
public void SetPersistentManifold(PersistentManifold manifold)
|
||||
{
|
||||
_manifold = manifold;
|
||||
}
|
||||
|
||||
public override void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB)
|
||||
{
|
||||
_partIdA = partIdA;
|
||||
_partIdB = partIdB;
|
||||
_indexA = indexA;
|
||||
_indexB = indexB;
|
||||
}
|
||||
|
||||
public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth)
|
||||
{
|
||||
if (_manifold == null)
|
||||
throw new BulletException("Manifold Pointer is null.");
|
||||
|
||||
//order in manifold needs to match
|
||||
|
||||
if (depth > PersistentManifold.ContactBreakingThreshold)
|
||||
return;
|
||||
|
||||
bool isSwapped = _manifold.BodyA != _bodyA;
|
||||
|
||||
Vector3 pointA = pointInWorld + normalOnBInWorld * depth;
|
||||
Vector3 localA;
|
||||
Vector3 localB;
|
||||
|
||||
if (isSwapped)
|
||||
{
|
||||
localA = MathHelper.InvXForm(_rootTransB, pointA);
|
||||
localB = MathHelper.InvXForm(_rootTransA, pointInWorld);
|
||||
}
|
||||
else
|
||||
{
|
||||
localA = MathHelper.InvXForm(_rootTransA, pointA);
|
||||
localB = MathHelper.InvXForm(_rootTransB, pointInWorld);
|
||||
}
|
||||
|
||||
ManifoldPoint newPt = new ManifoldPoint(localA, localB, normalOnBInWorld, depth);
|
||||
|
||||
int insertIndex = _manifold.GetCacheEntry(newPt);
|
||||
|
||||
newPt.CombinedFriction = CalculateCombinedFriction(_bodyA, _bodyB);
|
||||
newPt.CombinedRestitution = CalculateCombinedRestitution(_bodyA, _bodyB);
|
||||
|
||||
//User can override friction and/or restitution
|
||||
if (_contactAddedCallback != null &&
|
||||
//and if either of the two bodies requires custom material
|
||||
((_bodyA.CollisionFlags & CollisionOptions.CustomMaterialCallback) != 0 ||
|
||||
(_bodyB.CollisionFlags & CollisionOptions.CustomMaterialCallback) != 0))
|
||||
{
|
||||
//experimental feature info, for per-triangle material etc.
|
||||
CollisionObject obj0 = isSwapped ? _bodyB : _bodyA;
|
||||
CollisionObject obj1 = isSwapped ? _bodyA : _bodyB;
|
||||
_contactAddedCallback(newPt, obj0, _partIdA, _indexA, obj1, _partIdB, _indexB);
|
||||
}
|
||||
|
||||
if (insertIndex >= 0)
|
||||
{
|
||||
_manifold.ReplaceContactPoint(newPt, insertIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_manifold.AddManifoldPoint(newPt);
|
||||
}
|
||||
}
|
||||
|
||||
private float CalculateCombinedFriction(CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
float friction = bodyA.Friction * bodyB.Friction;
|
||||
|
||||
float MaxFriction = 10;
|
||||
if (friction < -MaxFriction)
|
||||
friction = -MaxFriction;
|
||||
if (friction > MaxFriction)
|
||||
friction = MaxFriction;
|
||||
return friction;
|
||||
}
|
||||
|
||||
private float CalculateCombinedRestitution(CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return bodyA.Restitution * bodyB.Restitution;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class SimulationIslandManager
|
||||
{
|
||||
private UnionFind _unionFind = new UnionFind();
|
||||
|
||||
public void InitUnionFind(int n)
|
||||
{
|
||||
_unionFind.Reset(n);
|
||||
}
|
||||
|
||||
public UnionFind UnionFind { get { return _unionFind; } }
|
||||
|
||||
public virtual void UpdateActivationState(CollisionWorld world, IDispatcher dispatcher)
|
||||
{
|
||||
InitUnionFind(world.CollisionObjectsCount);
|
||||
|
||||
// put the index into m_controllers into m_tag
|
||||
int index = 0;
|
||||
for (int i = 0; i < world.CollisionObjects.Count; i++)
|
||||
{
|
||||
world.CollisionObjects[i].IslandTag = index;
|
||||
world.CollisionObjects[i].HitFraction = 1;
|
||||
world.CollisionObjects[i].CompanionID = -1;
|
||||
index++;
|
||||
}
|
||||
// do the union find
|
||||
FindUnions(dispatcher);
|
||||
}
|
||||
|
||||
public virtual void StoreIslandActivationState(CollisionWorld world)
|
||||
{
|
||||
// put the islandId ('find' value) into m_tag
|
||||
int index = 0;
|
||||
for (int i = 0; i < world.CollisionObjects.Count; i++)
|
||||
{
|
||||
if (world.CollisionObjects[i].MergesSimulationIslands)
|
||||
{
|
||||
world.CollisionObjects[i].IslandTag = _unionFind.Find(index);
|
||||
world.CollisionObjects[i].CompanionID = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
world.CollisionObjects[i].IslandTag = -1;
|
||||
world.CollisionObjects[i].CompanionID = -2;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public void FindUnions(IDispatcher dispatcher)
|
||||
{
|
||||
for (int i = 0; i < dispatcher.ManifoldCount; i++)
|
||||
{
|
||||
PersistentManifold manifold = dispatcher.GetManifoldByIndex(i);
|
||||
//static objects (invmass 0.f) don't merge !
|
||||
|
||||
CollisionObject colObjA = manifold.BodyA as CollisionObject;
|
||||
CollisionObject colObjB = manifold.BodyB as CollisionObject;
|
||||
|
||||
if (((colObjA != null) && (colObjA.MergesSimulationIslands)) &&
|
||||
((colObjB != null) && (colObjB.MergesSimulationIslands)))
|
||||
{
|
||||
_unionFind.Unite(colObjA.IslandTag, colObjB.IslandTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildAndProcessIslands(IDispatcher dispatcher, List<CollisionObject> collisionObjects, IIslandCallback callback)
|
||||
{
|
||||
//we are going to sort the unionfind array, and store the element id in the size
|
||||
//afterwards, we clean unionfind, to make sure no-one uses it anymore
|
||||
UnionFind.SortIslands();
|
||||
int numElem = UnionFind.ElementCount;
|
||||
|
||||
int endIslandIndex = 1;
|
||||
int startIslandIndex;
|
||||
|
||||
//update the sleeping state for bodies, if all are sleeping
|
||||
for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
|
||||
{
|
||||
int islandId = UnionFind[startIslandIndex].ID;
|
||||
for (endIslandIndex = startIslandIndex + 1; (endIslandIndex < numElem) && (UnionFind[endIslandIndex].ID == islandId); endIslandIndex++)
|
||||
{
|
||||
}
|
||||
|
||||
//int numSleeping = 0;
|
||||
|
||||
bool allSleeping = true;
|
||||
|
||||
int idx;
|
||||
for (idx = startIslandIndex; idx < endIslandIndex; idx++)
|
||||
{
|
||||
int i = UnionFind[idx].Size;
|
||||
|
||||
CollisionObject colObjA = collisionObjects[i];
|
||||
if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
|
||||
{
|
||||
Console.WriteLine("error in island management");
|
||||
}
|
||||
|
||||
BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
|
||||
if (colObjA.IslandTag == islandId)
|
||||
{
|
||||
if (colObjA.ActivationState == ActivationState.Active)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
if (colObjA.ActivationState == ActivationState.DisableDeactivation)
|
||||
{
|
||||
allSleeping = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (allSleeping)
|
||||
{
|
||||
for (idx = startIslandIndex; idx < endIslandIndex; idx++)
|
||||
{
|
||||
int i = UnionFind[idx].Size;
|
||||
CollisionObject colObjA = collisionObjects[i];
|
||||
if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
|
||||
{
|
||||
Console.WriteLine("error in island management");
|
||||
}
|
||||
|
||||
BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
|
||||
|
||||
if (colObjA.IslandTag == islandId)
|
||||
{
|
||||
colObjA.ActivationState =ActivationState.IslandSleeping;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (idx = startIslandIndex; idx < endIslandIndex; idx++)
|
||||
{
|
||||
int i = UnionFind[idx].Size;
|
||||
|
||||
CollisionObject colObjA = collisionObjects[i];
|
||||
if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
|
||||
{
|
||||
Console.WriteLine("error in island management");
|
||||
}
|
||||
|
||||
BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
|
||||
|
||||
if (colObjA.IslandTag == islandId)
|
||||
{
|
||||
if (colObjA.ActivationState == ActivationState.IslandSleeping)
|
||||
{
|
||||
colObjA.ActivationState = ActivationState.WantsDeactivation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//int maxNumManifolds = dispatcher.ManifoldCount;
|
||||
List<PersistentManifold> islandmanifold = new List<PersistentManifold>(dispatcher.ManifoldCount);
|
||||
|
||||
for (int i = 0; i < dispatcher.ManifoldCount; i++)
|
||||
{
|
||||
PersistentManifold manifold = dispatcher.GetManifoldByIndex(i);
|
||||
|
||||
CollisionObject colObjA = manifold.BodyA as CollisionObject;
|
||||
CollisionObject colObjB = manifold.BodyB as CollisionObject;
|
||||
|
||||
//todo: check sleeping conditions!
|
||||
if (((colObjA != null) && colObjA.ActivationState != ActivationState.IslandSleeping) ||
|
||||
((colObjB != null) && colObjB.ActivationState != ActivationState.IslandSleeping))
|
||||
{
|
||||
|
||||
//kinematic objects don't merge islands, but wake up all connected objects
|
||||
if (colObjA.IsStaticOrKinematicObject && colObjA.ActivationState != ActivationState.IslandSleeping)
|
||||
{
|
||||
colObjB.Activate();
|
||||
}
|
||||
if (colObjB.IsStaticOrKinematicObject && colObjB.ActivationState != ActivationState.IslandSleeping)
|
||||
{
|
||||
colObjA.Activate();
|
||||
}
|
||||
|
||||
//filtering for response
|
||||
if (dispatcher.NeedsResponse(colObjA, colObjB))
|
||||
islandmanifold.Add(manifold);
|
||||
}
|
||||
}
|
||||
|
||||
int numManifolds = islandmanifold.Count;
|
||||
|
||||
// Sort manifolds, based on islands
|
||||
// Sort the vector using predicate and std::sort
|
||||
islandmanifold.Sort(new Comparison<PersistentManifold>(PersistentManifoldSortPredicate));
|
||||
|
||||
//now process all active islands (sets of manifolds for now)
|
||||
int startManifoldIndex = 0;
|
||||
int endManifoldIndex = 1;
|
||||
|
||||
List<CollisionObject> islandBodies = new List<CollisionObject>();
|
||||
|
||||
for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
|
||||
{
|
||||
int islandId = UnionFind[startIslandIndex].ID;
|
||||
bool islandSleeping = false;
|
||||
for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (UnionFind[endIslandIndex].ID == islandId); endIslandIndex++)
|
||||
{
|
||||
int i = UnionFind[endIslandIndex].Size;
|
||||
CollisionObject colObjA = collisionObjects[i];
|
||||
islandBodies.Add(colObjA);
|
||||
if (!colObjA.IsActive)
|
||||
islandSleeping = true;
|
||||
}
|
||||
|
||||
//find the accompanying contact manifold for this islandId
|
||||
int numIslandManifolds = 0;
|
||||
List<PersistentManifold> startManifold = new List<PersistentManifold>(numIslandManifolds);
|
||||
|
||||
if (startManifoldIndex < numManifolds)
|
||||
{
|
||||
int curIslandID = GetIslandId(islandmanifold[startManifoldIndex]);
|
||||
if (curIslandID == islandId)
|
||||
{
|
||||
for (int k = startManifoldIndex; k < islandmanifold.Count; k++)
|
||||
{
|
||||
startManifold.Add(islandmanifold[k]);
|
||||
}
|
||||
for (endManifoldIndex = startManifoldIndex + 1; (endManifoldIndex < numManifolds) && (islandId == GetIslandId(islandmanifold[endManifoldIndex])); endManifoldIndex++) { }
|
||||
|
||||
// Process the actual simulation, only if not sleeping/deactivated
|
||||
numIslandManifolds = endManifoldIndex - startManifoldIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!islandSleeping)
|
||||
{
|
||||
callback.ProcessIsland(islandBodies, startManifold, numIslandManifolds, islandId);
|
||||
}
|
||||
|
||||
if (numIslandManifolds != 0)
|
||||
{
|
||||
startManifoldIndex = endManifoldIndex;
|
||||
}
|
||||
|
||||
islandBodies.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetIslandId(PersistentManifold lhs)
|
||||
{
|
||||
int islandId;
|
||||
CollisionObject rcolObjA = lhs.BodyA as CollisionObject;
|
||||
CollisionObject rcolObjB = lhs.BodyB as CollisionObject;
|
||||
islandId = rcolObjA.IslandTag >= 0 ? rcolObjA.IslandTag : rcolObjB.IslandTag;
|
||||
return islandId;
|
||||
}
|
||||
|
||||
private static int PersistentManifoldSortPredicate(PersistentManifold lhs, PersistentManifold rhs)
|
||||
{
|
||||
int rIslandIdA, lIslandIdB;
|
||||
rIslandIdA = GetIslandId(rhs);
|
||||
lIslandIdB = GetIslandId(lhs);
|
||||
//return lIslandId0 < rIslandId0;
|
||||
if (lIslandIdB < rIslandIdA)
|
||||
return -1;
|
||||
//else if (lIslandIdB > rIslandIdA)
|
||||
// return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public interface IIslandCallback
|
||||
{
|
||||
void ProcessIsland(List<CollisionObject> bodies, List<PersistentManifold> manifolds, int numManifolds, int islandID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// SphereBoxCollisionAlgorithm provides sphere-box collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
/// </summary>
|
||||
public class SphereBoxCollisionAlgorithm : CollisionAlgorithm, IDisposable
|
||||
{
|
||||
private bool _ownManifold;
|
||||
private PersistentManifold _manifold;
|
||||
private bool _isSwapped;
|
||||
|
||||
public SphereBoxCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject collisionObjectA, CollisionObject collisionObjectB, bool isSwapped)
|
||||
: base(collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
_ownManifold = false;
|
||||
_manifold = manifold;
|
||||
_isSwapped = isSwapped;
|
||||
|
||||
CollisionObject sphereObject = _isSwapped ? collisionObjectB : collisionObjectA;
|
||||
CollisionObject boxObject = _isSwapped ? collisionObjectA : collisionObjectB;
|
||||
|
||||
if (_manifold == null && Dispatcher.NeedsCollision(sphereObject, boxObject))
|
||||
{
|
||||
_manifold = Dispatcher.GetNewManifold(sphereObject, boxObject);
|
||||
_ownManifold = true;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetSphereDistance(CollisionObject boxObject, out Vector3 pointOnBox, out Vector3 pointOnSphere, Vector3 sphereCenter, float radius)
|
||||
{
|
||||
pointOnBox = new Vector3();
|
||||
pointOnSphere = new Vector3();
|
||||
|
||||
float margins;
|
||||
Vector3[] bounds = new Vector3[2];
|
||||
BoxShape boxShape = boxObject.CollisionShape as BoxShape;
|
||||
|
||||
bounds[0] = -boxShape.HalfExtents;
|
||||
bounds[1] = boxShape.HalfExtents;
|
||||
|
||||
margins = boxShape.Margin; //also add sphereShape margin?
|
||||
|
||||
Matrix m44T = boxObject.WorldTransform;
|
||||
|
||||
Vector3[] boundsVec = new Vector3[2];
|
||||
float penetration;
|
||||
|
||||
boundsVec[0] = bounds[0];
|
||||
boundsVec[1] = bounds[1];
|
||||
|
||||
Vector3 marginsVec = new Vector3(margins, margins, margins);
|
||||
|
||||
// add margins
|
||||
bounds[0] += marginsVec;
|
||||
bounds[1] -= marginsVec;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
Vector3 tmp, prel, normal, v3P;
|
||||
Vector3[] n = new Vector3[6];
|
||||
float sep = 10000000.0f, sepThis;
|
||||
|
||||
n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
|
||||
n[1] = new Vector3(0.0f, -1.0f, 0.0f);
|
||||
n[2] = new Vector3(0.0f, 0.0f, -1.0f);
|
||||
n[3] = new Vector3(1.0f, 0.0f, 0.0f);
|
||||
n[4] = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
n[5] = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
|
||||
// convert point in local space
|
||||
prel = MathHelper.InvXForm(m44T, sphereCenter);
|
||||
|
||||
bool found = false;
|
||||
|
||||
v3P = prel;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int j = i < 3 ? 0 : 1;
|
||||
if ((sepThis = (Vector3.Dot(v3P - bounds[j], n[i]))) > 0.0f)
|
||||
{
|
||||
v3P = v3P - n[i] * sepThis;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if (found)
|
||||
{
|
||||
bounds[0] = boundsVec[0];
|
||||
bounds[1] = boundsVec[1];
|
||||
|
||||
normal = Vector3.Normalize(prel - v3P);
|
||||
pointOnBox = v3P + normal * margins;
|
||||
pointOnSphere = prel - normal * radius;
|
||||
|
||||
if ((Vector3.Dot(pointOnSphere - pointOnBox, normal)) > 0.0f)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// transform back in world space
|
||||
tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
|
||||
pointOnBox = tmp;
|
||||
tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
|
||||
pointOnSphere = tmp;
|
||||
float seps2 = (pointOnBox - pointOnSphere).LengthSquared();
|
||||
|
||||
//if this fails, fallback into deeper penetration case, below
|
||||
if (seps2 > MathHelper.Epsilon)
|
||||
{
|
||||
sep = -(float)Math.Sqrt(seps2);
|
||||
normal = (pointOnBox - pointOnSphere);
|
||||
normal *= 1f / sep;
|
||||
}
|
||||
return sep;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Deep penetration case
|
||||
|
||||
penetration = GetSpherePenetration(boxObject, ref pointOnBox, ref pointOnSphere, sphereCenter, radius, bounds[0], bounds[1]);
|
||||
|
||||
bounds[0] = boundsVec[0];
|
||||
bounds[1] = boundsVec[1];
|
||||
|
||||
if (penetration <= 0.0f)
|
||||
return (penetration - margins);
|
||||
else
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
public float GetSpherePenetration(CollisionObject boxObject, ref Vector3 pointOnBox, ref Vector3 pointOnSphere, Vector3 sphereCenter, float radius, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
Vector3[] bounds = new Vector3[2];
|
||||
|
||||
bounds[0] = aabbMin;
|
||||
bounds[1] = aabbMax;
|
||||
|
||||
Vector3 p0 = new Vector3(), tmp, prel, normal = new Vector3();
|
||||
Vector3[] n = new Vector3[6];
|
||||
float sep = -10000000.0f, sepThis;
|
||||
|
||||
n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
|
||||
n[1] = new Vector3(0.0f, -1.0f, 0.0f);
|
||||
n[2] = new Vector3(0.0f, 0.0f, -1.0f);
|
||||
n[3] = new Vector3(1.0f, 0.0f, 0.0f);
|
||||
n[4] = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
n[5] = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
|
||||
Matrix m44T = boxObject.WorldTransform;
|
||||
|
||||
// convert point in local space
|
||||
prel = MathHelper.InvXForm(m44T, sphereCenter);
|
||||
|
||||
///////////
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int j = i < 3 ? 0 : 1;
|
||||
if ((sepThis = (Vector3.Dot(prel - bounds[j], n[i])) - radius) > 0.0f) return 1.0f;
|
||||
if (sepThis > sep)
|
||||
{
|
||||
p0 = bounds[j];
|
||||
normal = n[i];
|
||||
sep = sepThis;
|
||||
}
|
||||
}
|
||||
|
||||
pointOnBox = prel - normal * (Vector3.Dot(normal, (prel - p0)));
|
||||
pointOnSphere = pointOnBox + normal * sep;
|
||||
|
||||
// transform back in world space
|
||||
tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
|
||||
pointOnBox = tmp;
|
||||
tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
|
||||
pointOnSphere = tmp;
|
||||
normal = Vector3.Normalize(pointOnBox - pointOnSphere);
|
||||
|
||||
return sep;
|
||||
}
|
||||
|
||||
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
if (_manifold == null)
|
||||
return;
|
||||
|
||||
CollisionObject sphereObject = _isSwapped ? bodyB : bodyA;
|
||||
CollisionObject boxObject = _isSwapped ? bodyA : bodyB;
|
||||
|
||||
SphereShape sphereA = sphereObject.CollisionShape as SphereShape;
|
||||
|
||||
Vector3 pOnBox, pOnSphere;
|
||||
Vector3 sphereCenter = sphereObject.WorldTransform.Translation;
|
||||
float radius = sphereA.Radius;
|
||||
|
||||
float dist = GetSphereDistance(boxObject, out pOnBox, out pOnSphere, sphereCenter, radius);
|
||||
|
||||
if (dist < MathHelper.Epsilon)
|
||||
{
|
||||
Vector3 normalOnSurfaceB = Vector3.Normalize(pOnBox - pOnSphere);
|
||||
|
||||
// report a contact. internally this will be kept persistent, and contact reduction is done
|
||||
resultOut.SetPersistentManifold(_manifold);
|
||||
resultOut.AddContactPoint(normalOnSurfaceB, pOnBox, dist);
|
||||
}
|
||||
}
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject collisionObjectA, CollisionObject collisionObjectB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
//not yet
|
||||
return 1;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
if (!IsSwapped)
|
||||
return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
|
||||
else
|
||||
return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && _ownManifold)
|
||||
{
|
||||
if (_manifold != null)
|
||||
Dispatcher.ReleaseManifold(_manifold);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class SphereSphereCollisionAlgorithm : CollisionAlgorithm
|
||||
{
|
||||
private bool _ownManifold;
|
||||
private PersistentManifold _manifold;
|
||||
|
||||
public SphereSphereCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
: base(collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
_ownManifold = false;
|
||||
_manifold = manifold;
|
||||
|
||||
if (_manifold == null)
|
||||
{
|
||||
_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
|
||||
_ownManifold = true;
|
||||
}
|
||||
}
|
||||
|
||||
public SphereSphereCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
|
||||
: base(collisionAlgorithmConstructionInfo) { }
|
||||
|
||||
~SphereSphereCollisionAlgorithm()
|
||||
{
|
||||
if (_ownManifold)
|
||||
{
|
||||
if (_manifold != null)
|
||||
Dispatcher.ReleaseManifold(_manifold);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
if (_manifold == null)
|
||||
return;
|
||||
|
||||
SphereShape sphereA = bodyA.CollisionShape as SphereShape;
|
||||
SphereShape sphereB = bodyB.CollisionShape as SphereShape;
|
||||
|
||||
Vector3 diff = bodyA.WorldTransform.Translation - bodyB.WorldTransform.Translation;
|
||||
float len = diff.Length();
|
||||
float radiusA = sphereA.Radius;
|
||||
float radiusB = sphereB.Radius;
|
||||
|
||||
//if distance positive, don't generate a new contact
|
||||
if (len > (radiusA + radiusB))
|
||||
return;
|
||||
|
||||
//distance (negative means penetration)
|
||||
float dist = len - (radiusA + radiusB);
|
||||
|
||||
Vector3 normalOnSurfaceB = diff / len;
|
||||
//point on A (worldspace)
|
||||
Vector3 posA = bodyA.WorldTransform.Translation - radiusA * normalOnSurfaceB;
|
||||
//point on B (worldspace)
|
||||
Vector3 posB = bodyB.WorldTransform.Translation + radiusB * normalOnSurfaceB;
|
||||
|
||||
// report a contact. internally this will be kept persistent, and contact reduction is done
|
||||
resultOut.SetPersistentManifold(_manifold);
|
||||
resultOut.AddContactPoint(normalOnSurfaceB, posB, dist);
|
||||
}
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
//not yet
|
||||
return 1f;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new SphereSphereCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// SphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
|
||||
/// </summary>
|
||||
public class SphereTriangleCollisionAlgorithm : CollisionAlgorithm, IDisposable
|
||||
{
|
||||
private bool _ownManifold;
|
||||
private PersistentManifold _manifold;
|
||||
private bool _isSwapped;
|
||||
|
||||
public SphereTriangleCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
|
||||
: base(collisionAlgorithmConstructionInfo)
|
||||
{
|
||||
_ownManifold = false;
|
||||
_manifold = manifold;
|
||||
_isSwapped = isSwapped;
|
||||
|
||||
if (_manifold == null)
|
||||
{
|
||||
_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
|
||||
_ownManifold = true;
|
||||
}
|
||||
}
|
||||
|
||||
public SphereTriangleCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
|
||||
: base(collisionAlgorithmConstructionInfo) { }
|
||||
|
||||
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
if (_manifold == null)
|
||||
return;
|
||||
|
||||
SphereShape sphere = bodyA.CollisionShape as SphereShape;
|
||||
TriangleShape triangle = bodyB.CollisionShape as TriangleShape;
|
||||
|
||||
/// report a contact. internally this will be kept persistent, and contact reduction is done
|
||||
resultOut.SetPersistentManifold(_manifold);
|
||||
SphereTriangleDetector detector = new SphereTriangleDetector(sphere, triangle);
|
||||
|
||||
DiscreteCollisionDetectorInterface.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
|
||||
input.MaximumDistanceSquared = 1e30f;//todo: tighter bounds
|
||||
input.TransformA = bodyA.WorldTransform;
|
||||
input.TransformB = bodyB.WorldTransform;
|
||||
|
||||
detector.GetClosestPoints(input, resultOut, null);
|
||||
}
|
||||
|
||||
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
|
||||
{
|
||||
//not yet
|
||||
return 1f;
|
||||
}
|
||||
|
||||
public class CreateFunc : CollisionAlgorithmCreateFunction
|
||||
{
|
||||
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
|
||||
{
|
||||
return new SphereTriangleCollisionAlgorithm(collisionAlgorithmConstructionInfo.Manifold, collisionAlgorithmConstructionInfo, bodyA, bodyB, IsSwapped);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
public void Dispose()
|
||||
{
|
||||
if (_ownManifold)
|
||||
if (_manifold != null)
|
||||
Dispatcher.ReleaseManifold(_manifold);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class SphereTriangleDetector : DiscreteCollisionDetectorInterface
|
||||
{
|
||||
private SphereShape _sphere;
|
||||
private TriangleShape _triangle;
|
||||
private const int MaxOverlap = 0;
|
||||
|
||||
public SphereTriangleDetector(SphereShape sphere, TriangleShape triangle)
|
||||
{
|
||||
this._sphere = sphere;
|
||||
this._triangle = triangle;
|
||||
}
|
||||
|
||||
public override void GetClosestPoints(DiscreteCollisionDetectorInterface.ClosestPointInput input, DiscreteCollisionDetectorInterface.Result output, IDebugDraw debugDraw)
|
||||
{
|
||||
Matrix transformA = input.TransformA;
|
||||
Matrix transformB = input.TransformB;
|
||||
|
||||
Vector3 point = new Vector3();
|
||||
Vector3 normal = new Vector3();
|
||||
Single timeOfImpact = 1.0f;
|
||||
Single depth = 0.0f;
|
||||
|
||||
//move sphere into triangle space
|
||||
Matrix sphereInTr = MathHelper.InverseTimes(transformB, transformA);
|
||||
|
||||
if (Collide(sphereInTr.Translation, point, normal, depth, timeOfImpact))
|
||||
output.AddContactPoint(Vector3.TransformNormal(normal, transformB), Vector3.TransformNormal(point, transformB), depth);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See also geometrictools.com
|
||||
/// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
|
||||
/// </summary>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="p"></param>
|
||||
/// <param name="nearest"></param>
|
||||
/// <returns></returns>
|
||||
private float SegmentSquareDistance(Vector3 from, Vector3 to, Vector3 point, Vector3 nearest)
|
||||
{
|
||||
Vector3 diff = point - from;
|
||||
Vector3 v = to - from;
|
||||
float t = Vector3.Dot(v, diff);
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
float dotVV = Vector3.Dot(v, v);
|
||||
if (t < dotVV)
|
||||
{
|
||||
t /= dotVV;
|
||||
diff -= t * v;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = 1;
|
||||
diff -= v;
|
||||
}
|
||||
}
|
||||
else
|
||||
t = 0;
|
||||
|
||||
nearest = from + t * v;
|
||||
return Vector3.Dot(diff, diff);
|
||||
}
|
||||
|
||||
private bool Collide(Vector3 sphereCenter, Vector3 point, Vector3 resultNormal, float depth, float timeOfImpact)
|
||||
{
|
||||
Vector3[] vertices = _triangle.Vertices;
|
||||
Vector3 c = sphereCenter;
|
||||
float r = _sphere.Radius;
|
||||
|
||||
Vector3 delta = new Vector3();
|
||||
|
||||
Vector3 normal = Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]);
|
||||
normal = Vector3.Normalize(normal);
|
||||
Vector3 p1ToCentre = c - vertices[0];
|
||||
float distanceFromPlane = Vector3.Dot(p1ToCentre, normal);
|
||||
|
||||
if (distanceFromPlane < 0)
|
||||
{
|
||||
//triangle facing the other way
|
||||
distanceFromPlane *= -1;
|
||||
normal *= -1;
|
||||
}
|
||||
|
||||
float contactMargin = PersistentManifold.ContactBreakingThreshold;
|
||||
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
|
||||
bool isInsideShellPlane = distanceFromPlane < r;
|
||||
|
||||
float deltaDotNormal = Vector3.Dot(delta, normal);
|
||||
if (!isInsideShellPlane && deltaDotNormal >= 0.0f)
|
||||
return false;
|
||||
|
||||
// Check for contact / intersection
|
||||
bool hasContact = false;
|
||||
Vector3 contactPoint = new Vector3();
|
||||
if (isInsideContactPlane)
|
||||
{
|
||||
if (FaceContains(c, vertices, normal))
|
||||
{
|
||||
// Inside the contact wedge - touches a point on the shell plane
|
||||
hasContact = true;
|
||||
contactPoint = c - normal * distanceFromPlane;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could be inside one of the contact capsules
|
||||
float contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
|
||||
Vector3 nearestOnEdge = new Vector3();
|
||||
for (int i = 0; i < _triangle.EdgeCount; i++)
|
||||
{
|
||||
Vector3 pa, pb;
|
||||
_triangle.GetEdge(i, out pa, out pb);
|
||||
|
||||
float distanceSqr = SegmentSquareDistance(pa, pb, c, nearestOnEdge);
|
||||
if (distanceSqr < contactCapsuleRadiusSqr)
|
||||
{
|
||||
// Yep, we're inside a capsule
|
||||
hasContact = true;
|
||||
contactPoint = nearestOnEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasContact)
|
||||
{
|
||||
Vector3 contactToCentre = c - contactPoint;
|
||||
float distanceSqr = contactToCentre.LengthSquared();
|
||||
if (distanceSqr < (r - MaxOverlap) * (r - MaxOverlap))
|
||||
{
|
||||
float distance = (float)Math.Sqrt(distanceSqr);
|
||||
resultNormal = contactToCentre;
|
||||
resultNormal = Vector3.Normalize(resultNormal);
|
||||
point = contactPoint;
|
||||
depth = -(r - distance);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Vector3.Dot(delta, contactToCentre) >= 0.0f)
|
||||
return false;
|
||||
|
||||
// Moving towards the contact point -> collision
|
||||
point = contactPoint;
|
||||
timeOfImpact = 0.0f;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool PointInTriangle(Vector3[] vertices, Vector3 normal, Vector3 p)
|
||||
{
|
||||
Vector3 p1 = vertices[0];
|
||||
Vector3 p2 = vertices[1];
|
||||
Vector3 p3 = vertices[2];
|
||||
|
||||
Vector3 edge1 = p2 - p1;
|
||||
Vector3 edge2 = p3 - p2;
|
||||
Vector3 edge3 = p1 - p3;
|
||||
|
||||
Vector3 p1ToP = p - p1;
|
||||
Vector3 p2ToP = p - p2;
|
||||
Vector3 p3ToP = p - p3;
|
||||
|
||||
Vector3 edge1Normal = Vector3.Cross(edge1, normal);
|
||||
Vector3 edge2Normal = Vector3.Cross(edge2, normal);
|
||||
Vector3 edge3Normal = Vector3.Cross(edge3, normal);
|
||||
|
||||
float r1, r2, r3;
|
||||
r1 = Vector3.Dot(edge1Normal, p1ToP);
|
||||
r2 = Vector3.Dot(edge2Normal, p2ToP);
|
||||
r3 = Vector3.Dot(edge3Normal, p3ToP);
|
||||
if ((r1 > 0 && r2 > 0 && r3 > 0) ||
|
||||
(r1 <= 0 && r2 <= 0 && r3 <= 0))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool FaceContains(Vector3 p, Vector3[] vertices, Vector3 normal)
|
||||
{
|
||||
Vector3 lp = p;
|
||||
Vector3 lnormal = normal;
|
||||
return PointInTriangle(vertices, lnormal, lp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class UnionFind : IDisposable
|
||||
{
|
||||
private List<Element> _elements = new List<Element>();
|
||||
|
||||
public int ElementCount
|
||||
{
|
||||
get { return _elements.Count; }
|
||||
}
|
||||
|
||||
public void SortIslands()
|
||||
{
|
||||
for (int i = 0; i < _elements.Count; i++)
|
||||
{
|
||||
_elements[i].ID = Find(i);
|
||||
_elements[i].Size = i;
|
||||
}
|
||||
|
||||
_elements.Sort(Sort);
|
||||
}
|
||||
|
||||
private static int Sort(Element x, Element y)
|
||||
{
|
||||
if (x.ID < y.ID) return -1;
|
||||
//else if (x.ID > y.ID) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public void Reset(int number)
|
||||
{
|
||||
Allocate(number);
|
||||
|
||||
for (int i = 0; i < number; i++)
|
||||
{
|
||||
Element element = new Element();
|
||||
element.ID = i;
|
||||
element.Size = 1;
|
||||
_elements.Insert(i, element);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRoot(int index)
|
||||
{
|
||||
return (_elements[index].Size == index);
|
||||
}
|
||||
|
||||
public Element this[int index]
|
||||
{
|
||||
get { return _elements[index]; }
|
||||
}
|
||||
|
||||
public void Allocate(int number)
|
||||
{
|
||||
//Does nothing
|
||||
_elements = new List<Element>(number);
|
||||
}
|
||||
|
||||
public bool Find(int i, int j)
|
||||
{
|
||||
return (Find(i) == Find(j));
|
||||
}
|
||||
|
||||
public int Find(int i)
|
||||
{
|
||||
while (i != _elements[i].ID)
|
||||
{
|
||||
//Element element = _elements[i];
|
||||
//element.ID = _elements[_elements[i].ID].ID;
|
||||
_elements[i].ID = _elements[_elements[i].ID].ID;
|
||||
i = _elements[i].ID;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void Unite(int p, int q)
|
||||
{
|
||||
int i = Find(p), j = Find(q);
|
||||
if (i == j)
|
||||
return;
|
||||
|
||||
//weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
|
||||
//if (_elements[i].Size < _elements[j].Size)
|
||||
//{
|
||||
// Element element = _elements[i];
|
||||
// element.ID = j;
|
||||
// _elements[i] = element;
|
||||
|
||||
// element = _elements[j];
|
||||
// element.Size += _elements[i].Size;
|
||||
// _elements[j] = element;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Element element = _elements[j];
|
||||
// element.ID = i;
|
||||
// _elements[j] = element;
|
||||
|
||||
// element = _elements[i];
|
||||
// element.Size += _elements[j].Size;
|
||||
// _elements[i] = element;
|
||||
//}
|
||||
_elements[i].ID = j;
|
||||
_elements[j].Size += _elements[i].Size;
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_elements.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class Element
|
||||
{
|
||||
private int _id;
|
||||
private int _size;
|
||||
|
||||
public int ID { get { return _id; } set { _id = value; } }
|
||||
public int Size { get { return _size; } set { _size = value; } }
|
||||
}
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// BUSimplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex).
|
||||
/// </summary>
|
||||
public class BUSimplex1to4 : PolyhedralConvexShape
|
||||
{
|
||||
private int _numVertices = 0;
|
||||
private Vector3[] _vertices = new Vector3[4];
|
||||
|
||||
public BUSimplex1to4() { }
|
||||
|
||||
public BUSimplex1to4(Vector3 pointA)
|
||||
{
|
||||
AddVertex(pointA);
|
||||
}
|
||||
|
||||
public BUSimplex1to4(Vector3 pointA, Vector3 pointB)
|
||||
{
|
||||
AddVertex(pointA);
|
||||
AddVertex(pointB);
|
||||
}
|
||||
|
||||
public BUSimplex1to4(Vector3 pointA, Vector3 pointB, Vector3 pointC)
|
||||
{
|
||||
AddVertex(pointA);
|
||||
AddVertex(pointB);
|
||||
AddVertex(pointC);
|
||||
}
|
||||
|
||||
public BUSimplex1to4(Vector3 pointA, Vector3 pointB, Vector3 pointC, Vector3 pointD)
|
||||
{
|
||||
AddVertex(pointA);
|
||||
AddVertex(pointB);
|
||||
AddVertex(pointC);
|
||||
AddVertex(pointD);
|
||||
}
|
||||
|
||||
protected Vector3[] Vertices { get { return _vertices; } set { _vertices = value; } }
|
||||
|
||||
public override int VertexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _numVertices;
|
||||
}
|
||||
}
|
||||
|
||||
public override int EdgeCount
|
||||
{
|
||||
get
|
||||
{
|
||||
//euler formula, F-E+V = 2, so E = F+V-2
|
||||
switch (_numVertices)
|
||||
{
|
||||
case 0: return 0;
|
||||
case 1: return 0;
|
||||
case 2: return 1;
|
||||
case 3: return 3;
|
||||
case 4: return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override int PlaneCount
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (_numVertices)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return 0;
|
||||
case 2:
|
||||
return 0;
|
||||
case 3:
|
||||
return 2;
|
||||
case 4:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.Tetrahedral;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "BUSimplex1to4";
|
||||
}
|
||||
}
|
||||
|
||||
public void AddVertex(Vector3 v)
|
||||
{
|
||||
_vertices[_numVertices++] = v;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_numVertices = 0;
|
||||
}
|
||||
|
||||
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
|
||||
{
|
||||
switch (_numVertices)
|
||||
{
|
||||
case 2:
|
||||
pa = _vertices[0];
|
||||
pb = _vertices[1];
|
||||
return;
|
||||
case 3:
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
pa = _vertices[0];
|
||||
pb = _vertices[1];
|
||||
return;
|
||||
case 1:
|
||||
pa = _vertices[1];
|
||||
pb = _vertices[2];
|
||||
return;
|
||||
case 2:
|
||||
pa = _vertices[2];
|
||||
pb = _vertices[0];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
pa = _vertices[0];
|
||||
pb = _vertices[1];
|
||||
return;
|
||||
case 1:
|
||||
pa = _vertices[1];
|
||||
pb = _vertices[2];
|
||||
return;
|
||||
case 2:
|
||||
pa = _vertices[2];
|
||||
pb = _vertices[0];
|
||||
return;
|
||||
case 3:
|
||||
pa = _vertices[0];
|
||||
pb = _vertices[3];
|
||||
return;
|
||||
case 4:
|
||||
pa = _vertices[1];
|
||||
pb = _vertices[3];
|
||||
return;
|
||||
case 5:
|
||||
pa = _vertices[2];
|
||||
pb = _vertices[3];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pa = new Vector3();
|
||||
pb = new Vector3();
|
||||
}
|
||||
|
||||
public override void GetVertex(int i, out Vector3 vtx)
|
||||
{
|
||||
vtx = _vertices[i];
|
||||
}
|
||||
|
||||
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
|
||||
{
|
||||
planeNormal = new Vector3();
|
||||
planeSupport = new Vector3();
|
||||
}
|
||||
|
||||
public override bool IsInside(Vector3 pt, float tolerance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class BoxShape : PolyhedralConvexShape
|
||||
{
|
||||
public BoxShape(Vector3 boxHalfExtents)
|
||||
{
|
||||
ImplicitShapeDimensions = boxHalfExtents;
|
||||
}
|
||||
|
||||
public override int VertexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
public override int EdgeCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.Box;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Box";
|
||||
}
|
||||
}
|
||||
|
||||
public override int PreferredPenetrationDirectionsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
public override int PlaneCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 HalfExtents { get { return ImplicitShapeDimensions * LocalScaling; } }
|
||||
|
||||
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
|
||||
{
|
||||
int edgeVert0 = 0;
|
||||
int edgeVert1 = 0;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
edgeVert0 = 0;
|
||||
edgeVert1 = 1;
|
||||
break;
|
||||
case 1:
|
||||
edgeVert0 = 0;
|
||||
edgeVert1 = 2;
|
||||
break;
|
||||
case 2:
|
||||
edgeVert0 = 1;
|
||||
edgeVert1 = 3;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
edgeVert0 = 2;
|
||||
edgeVert1 = 3;
|
||||
break;
|
||||
case 4:
|
||||
edgeVert0 = 0;
|
||||
edgeVert1 = 4;
|
||||
break;
|
||||
case 5:
|
||||
edgeVert0 = 1;
|
||||
edgeVert1 = 5;
|
||||
|
||||
break;
|
||||
case 6:
|
||||
edgeVert0 = 2;
|
||||
edgeVert1 = 6;
|
||||
break;
|
||||
case 7:
|
||||
edgeVert0 = 3;
|
||||
edgeVert1 = 7;
|
||||
break;
|
||||
case 8:
|
||||
edgeVert0 = 4;
|
||||
edgeVert1 = 5;
|
||||
break;
|
||||
case 9:
|
||||
edgeVert0 = 4;
|
||||
edgeVert1 = 6;
|
||||
break;
|
||||
case 10:
|
||||
edgeVert0 = 5;
|
||||
edgeVert1 = 7;
|
||||
break;
|
||||
case 11:
|
||||
edgeVert0 = 6;
|
||||
edgeVert1 = 7;
|
||||
break;
|
||||
default:
|
||||
throw new BulletException();
|
||||
|
||||
}
|
||||
|
||||
GetVertex(edgeVert0, out pa);
|
||||
GetVertex(edgeVert1, out pb);
|
||||
}
|
||||
|
||||
public override void GetVertex(int i, out Vector3 vtx)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
|
||||
vtx = new Vector3(
|
||||
halfExtents.X * (1 - (i & 1)) - halfExtents.X * (i & 1),
|
||||
halfExtents.Y * (1 - ((i & 2) >> 1)) - halfExtents.Y * ((i & 2) >> 1),
|
||||
halfExtents.Z * (1 - ((i & 4) >> 2)) - halfExtents.Z * ((i & 4) >> 2));
|
||||
}
|
||||
|
||||
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
|
||||
{
|
||||
//this plane might not be aligned...
|
||||
Vector4 plane;
|
||||
GetPlaneEquation(out plane, i);
|
||||
planeNormal = new Vector3(plane.X, plane.Y, plane.Z);
|
||||
planeSupport = LocalGetSupportingVertex(-planeNormal);
|
||||
}
|
||||
|
||||
public override bool IsInside(Vector3 pt, float tolerance)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
|
||||
//btScalar minDist = 2*tolerance;
|
||||
|
||||
bool result = (pt.X <= ( halfExtents.X + tolerance)) &&
|
||||
(pt.X >= (-halfExtents.X - tolerance)) &&
|
||||
(pt.Y <= ( halfExtents.Y + tolerance)) &&
|
||||
(pt.Y >= (-halfExtents.Y - tolerance)) &&
|
||||
(pt.Z <= ( halfExtents.Z + tolerance)) &&
|
||||
(pt.Z >= (-halfExtents.Z - tolerance));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
|
||||
return new Vector3( vec.X < 0.0f ? -halfExtents.X : halfExtents.X,
|
||||
vec.Y < 0.0f ? -halfExtents.Y : halfExtents.Y,
|
||||
vec.Z < 0.0f ? -halfExtents.Z : halfExtents.Z);
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
Vector3 margin = new Vector3(Margin, Margin, Margin);
|
||||
halfExtents -= margin;
|
||||
|
||||
return new Vector3( vec.X < 0.0f ? -halfExtents.X : halfExtents.X,
|
||||
vec.Y < 0.0f ? -halfExtents.Y : halfExtents.Y,
|
||||
vec.Z < 0.0f ? -halfExtents.Z : halfExtents.Z);
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
Vector3 margin = new Vector3(Margin, Margin, Margin);
|
||||
halfExtents -= margin;
|
||||
|
||||
for (int i = 0; i < vectors.Length; i++)
|
||||
{
|
||||
Vector3 vec = vectors[i];
|
||||
supportVerticesOut[i] = new Vector3(vec.X < 0.0f ? -halfExtents.X : halfExtents.X,
|
||||
vec.Y < 0.0f ? -halfExtents.Y : halfExtents.Y,
|
||||
vec.Z < 0.0f ? -halfExtents.Z : halfExtents.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void GetPlaneEquation(out Vector4 plane, int i)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
plane = new Vector4(1, 0, 0, 0);
|
||||
plane.W = -halfExtents.X;
|
||||
break;
|
||||
case 1:
|
||||
plane = new Vector4(-1, 0, 0, 0);
|
||||
plane.W = -halfExtents.X;
|
||||
break;
|
||||
case 2:
|
||||
plane = new Vector4(0, 1, 0, 0);
|
||||
plane.W = -halfExtents.Y;
|
||||
break;
|
||||
case 3:
|
||||
plane = new Vector4(0, -1, 0, 0);
|
||||
plane.W = -halfExtents.Y;
|
||||
break;
|
||||
case 4:
|
||||
plane = new Vector4(0, 0, 1, 0);
|
||||
plane.W = -halfExtents.Z;
|
||||
break;
|
||||
case 5:
|
||||
plane = new Vector4(0, 0, -1, 0);
|
||||
plane.W = -halfExtents.Z;
|
||||
break;
|
||||
default:
|
||||
throw new BulletException();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetPreferredPenetrationDirection(int index, out Vector3 penetrationVector)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
penetrationVector = new Vector3(1, 0, 0);
|
||||
break;
|
||||
case 1:
|
||||
penetrationVector = new Vector3(-1, 0, 0);
|
||||
break;
|
||||
case 2:
|
||||
penetrationVector = new Vector3(0, 1, 0);
|
||||
break;
|
||||
case 3:
|
||||
penetrationVector = new Vector3(0, -1, 0);
|
||||
break;
|
||||
case 4:
|
||||
penetrationVector = new Vector3(0, 0, 1);
|
||||
break;
|
||||
case 5:
|
||||
penetrationVector = new Vector3(0, 0, -1);
|
||||
break;
|
||||
default:
|
||||
throw new BulletException();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
|
||||
Matrix abs_b = MathHelper.Absolute(t);
|
||||
Vector3 center = t.Translation;
|
||||
Vector3 row1 = new Vector3(abs_b.M11, abs_b.M12, abs_b.M13);
|
||||
Vector3 row2 = new Vector3(abs_b.M21, abs_b.M22, abs_b.M23);
|
||||
Vector3 row3 = new Vector3(abs_b.M31, abs_b.M32, abs_b.M33);
|
||||
Vector3 extent = new Vector3(Vector3.Dot(row1, halfExtents),
|
||||
Vector3.Dot(row2, halfExtents),
|
||||
Vector3.Dot(row3, halfExtents));
|
||||
extent += new Vector3(Margin, Margin, Margin);
|
||||
|
||||
aabbMin = center - extent;
|
||||
aabbMax = center + extent;
|
||||
}
|
||||
|
||||
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
|
||||
{
|
||||
Vector3 halfExtents = HalfExtents;
|
||||
|
||||
float lx = 2f * (halfExtents.X);
|
||||
float ly = 2f * (halfExtents.Y);
|
||||
float lz = 2f * (halfExtents.Z);
|
||||
|
||||
inertia = new Vector3();
|
||||
inertia.X = mass / (12.0f) * (ly * ly + lz * lz);
|
||||
inertia.Y = mass / (12.0f) * (lx * lx + lz * lz);
|
||||
inertia.Z = mass / (12.0f) * (lx * lx + ly * ly);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
class MyNodeOverlapCallback : INodeOverlapCallback
|
||||
{
|
||||
StridingMeshInterface _meshInterface;
|
||||
ITriangleCallback _callback;
|
||||
Vector3[] _triangle = new Vector3[3];
|
||||
|
||||
public MyNodeOverlapCallback(ITriangleCallback callback, StridingMeshInterface meshInterface)
|
||||
{
|
||||
_meshInterface = meshInterface;
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public void ProcessNode(OptimizedBvhNode node)
|
||||
{
|
||||
List<Vector3> verts;
|
||||
List<int> indicies;
|
||||
int numtriangles;
|
||||
|
||||
_meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart);
|
||||
Vector3 meshScaling = _meshInterface.Scaling;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
_triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling;
|
||||
}
|
||||
|
||||
_callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex);
|
||||
_meshInterface.UnLockReadOnlyVertexBase(node.SubPart);
|
||||
}
|
||||
}
|
||||
|
||||
public class BvhTriangleMeshShape : TriangleMeshShape
|
||||
{
|
||||
OptimizedBvh _bvh = new OptimizedBvh();
|
||||
|
||||
public BvhTriangleMeshShape(StridingMeshInterface meshInterface) : base(meshInterface)
|
||||
{
|
||||
_bvh.Build(meshInterface);
|
||||
}
|
||||
|
||||
public override void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
MyNodeOverlapCallback myNodeCallback = new MyNodeOverlapCallback(callback, MeshInterface);
|
||||
_bvh.ReportAabbOverlappingNodex(myNodeCallback, aabbMin, aabbMax);
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "BvhTriangleMesh";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// CollisionShape provides generic interface for collidable objects
|
||||
/// </summary>
|
||||
public abstract class CollisionShape
|
||||
{
|
||||
//debugging support
|
||||
private string _tempDebug;
|
||||
|
||||
public abstract string Name { get; }
|
||||
public string ExtraDebugInfo { get { return _tempDebug; } set { _tempDebug = value; } }
|
||||
|
||||
public bool IsPolyhedral
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseProxy.IsPolyhedral(ShapeType);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConvex
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseProxy.IsConvex(ShapeType);
|
||||
}
|
||||
}
|
||||
public bool IsConcave
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseProxy.IsConcave(ShapeType);
|
||||
}
|
||||
}
|
||||
public bool IsCompound
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseProxy.IsCompound(ShapeType);
|
||||
}
|
||||
}
|
||||
|
||||
//isInfinite is used to catch simulation error (aabb check)
|
||||
public bool IsInfinite
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseProxy.IsInfinite(ShapeType);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract float Margin { get; set; }
|
||||
public abstract Vector3 LocalScaling { get; set; }
|
||||
public abstract BroadphaseNativeTypes ShapeType { get; }
|
||||
|
||||
|
||||
public virtual void GetBoundingSphere(out Vector3 center, out float radius)
|
||||
{
|
||||
Matrix tr = Matrix.Identity;
|
||||
Vector3 aabbMin, aabbMax;
|
||||
|
||||
GetAabb(tr, out aabbMin, out aabbMax);
|
||||
|
||||
radius = (aabbMax - aabbMin).Length() * 0.5f;
|
||||
center = (aabbMin + aabbMax) * 0.5f;
|
||||
}
|
||||
|
||||
public virtual float GetAngularMotionDisc()
|
||||
{
|
||||
Vector3 center;
|
||||
float disc;
|
||||
GetBoundingSphere(out center, out disc);
|
||||
disc += center.Length();
|
||||
return disc;
|
||||
}
|
||||
|
||||
//calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
|
||||
//result is conservative
|
||||
public void CalculateTemporalAabb(Matrix currentTransform, Vector3 linearVelocity, Vector3 angularVelocity, float timeStep, out Vector3 temporalAabbMin, out Vector3 temporalAabbMax)
|
||||
{
|
||||
//start with static aabb
|
||||
GetAabb(currentTransform, out temporalAabbMin, out temporalAabbMax);
|
||||
|
||||
float temporalAabbMaxx = temporalAabbMax.X;
|
||||
float temporalAabbMaxy = temporalAabbMax.Y;
|
||||
float temporalAabbMaxz = temporalAabbMax.Z;
|
||||
float temporalAabbMinx = temporalAabbMin.X;
|
||||
float temporalAabbMiny = temporalAabbMin.Y;
|
||||
float temporalAabbMinz = temporalAabbMin.Z;
|
||||
|
||||
// add linear motion
|
||||
Vector3 linMotion = linearVelocity * timeStep;
|
||||
//todo: simd would have a vector max/min operation, instead of per-element access
|
||||
if (linMotion.X > 0)
|
||||
temporalAabbMaxx += linMotion.X;
|
||||
else
|
||||
temporalAabbMinx += linMotion.X;
|
||||
if (linMotion.Y > 0)
|
||||
temporalAabbMaxy += linMotion.Y;
|
||||
else
|
||||
temporalAabbMiny += linMotion.Y;
|
||||
if (linMotion.Z > 0)
|
||||
temporalAabbMaxz += linMotion.Z;
|
||||
else
|
||||
temporalAabbMinz += linMotion.Z;
|
||||
|
||||
//add conservative angular motion
|
||||
float angularMotion = angularVelocity.Length() * GetAngularMotionDisc() * timeStep;
|
||||
Vector3 angularMotion3d = new Vector3(angularMotion, angularMotion, angularMotion);
|
||||
temporalAabbMin = new Vector3(temporalAabbMinx, temporalAabbMiny, temporalAabbMinz);
|
||||
temporalAabbMax = new Vector3(temporalAabbMaxx, temporalAabbMaxy, temporalAabbMaxz);
|
||||
|
||||
temporalAabbMin -= angularMotion3d;
|
||||
temporalAabbMax += angularMotion3d;
|
||||
}
|
||||
|
||||
public abstract void GetAabb(Matrix transform, out Vector3 aabbMin, out Vector3 aabbMax);
|
||||
|
||||
public abstract void CalculateLocalInertia(float mass, out Vector3 inertia);
|
||||
}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// CompoundShape allows to store multiple other CollisionShapes
|
||||
/// This allows for concave collision objects. This is more general then the Static Concave TriangleMeshShape.
|
||||
/// </summary>
|
||||
public class CompoundShape : CollisionShape
|
||||
{
|
||||
private List<Matrix> _childTransforms = new List<Matrix>();
|
||||
private List<CollisionShape> _childShapes = new List<CollisionShape>();
|
||||
private Vector3 _localAabbMin;
|
||||
private Vector3 _localAabbMax;
|
||||
|
||||
private OptimizedBvh _aabbTree;
|
||||
private float _collisionMargin;
|
||||
private Vector3 _localScaling;
|
||||
|
||||
public CompoundShape()
|
||||
{
|
||||
_localAabbMin = new Vector3(1e30f, 1e30f, 1e30f);
|
||||
_localAabbMax = new Vector3(-1e30f, -1e30f, -1e30f);
|
||||
_aabbTree = null;
|
||||
_collisionMargin = 0f;
|
||||
_localScaling = new Vector3(1f, 1f, 1f);
|
||||
}
|
||||
|
||||
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
|
||||
{
|
||||
Vector3 localHalfExtents = 0.5f * (_localAabbMax - _localAabbMin);
|
||||
Vector3 localCenter = 0.5f * (_localAabbMax + _localAabbMin);
|
||||
|
||||
Matrix abs_b = MathHelper.Absolute(t);
|
||||
|
||||
Vector3 row1 = new Vector3(abs_b.M11, abs_b.M12, abs_b.M13);
|
||||
Vector3 row2 = new Vector3(abs_b.M21, abs_b.M22, abs_b.M23);
|
||||
Vector3 row3 = new Vector3(abs_b.M31, abs_b.M32, abs_b.M33);
|
||||
|
||||
Vector3 center = new Vector3(Vector3.Dot(row1, localCenter) + t.Translation.X,
|
||||
Vector3.Dot(row2, localCenter) + t.Translation.Y,
|
||||
Vector3.Dot(row3, localCenter) + t.Translation.Z);
|
||||
|
||||
Vector3 extent = new Vector3(Vector3.Dot(row1, localHalfExtents),
|
||||
Vector3.Dot(row2, localHalfExtents),
|
||||
Vector3.Dot(row3, localHalfExtents));
|
||||
|
||||
aabbMin = center - extent;
|
||||
aabbMax = center + extent;
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.Compound;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalScaling
|
||||
{
|
||||
get
|
||||
{
|
||||
return _localScaling;
|
||||
}
|
||||
set
|
||||
{
|
||||
_localScaling = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Compound";
|
||||
}
|
||||
}
|
||||
|
||||
public override float Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return _collisionMargin;
|
||||
}
|
||||
set
|
||||
{
|
||||
_collisionMargin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ChildShapeCount { get { return _childShapes.Count; } }
|
||||
//this is optional, but should make collision queries faster, by culling non-overlapping nodes
|
||||
public OptimizedBvh AabbTree { get { return _aabbTree; } }
|
||||
|
||||
public CollisionShape GetChildShape(int index)
|
||||
{
|
||||
return _childShapes[index];
|
||||
}
|
||||
|
||||
public Matrix GetChildTransform(int index)
|
||||
{
|
||||
return _childTransforms[index];
|
||||
}
|
||||
|
||||
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
|
||||
{
|
||||
//approximation: take the inertia from the aabb for now
|
||||
Matrix ident = Matrix.Identity;
|
||||
Vector3 aabbMin, aabbMax;
|
||||
GetAabb(ident, out aabbMin, out aabbMax);
|
||||
|
||||
Vector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
|
||||
|
||||
float lx = 2f * (halfExtents.X);
|
||||
float ly = 2f * (halfExtents.Y);
|
||||
float lz = 2f * (halfExtents.Z);
|
||||
|
||||
inertia = new Vector3();
|
||||
inertia.X = mass / (12.0f) * (ly * ly + lz * lz);
|
||||
inertia.Y = mass / (12.0f) * (lx * lx + lz * lz);
|
||||
inertia.Z = mass / (12.0f) * (lx * lx + ly * ly);
|
||||
}
|
||||
|
||||
public void AddChildShape(Matrix localTransform, CollisionShape shape)
|
||||
{
|
||||
_childTransforms.Add(localTransform);
|
||||
_childShapes.Add(shape);
|
||||
|
||||
//extend the local aabbMin/aabbMax
|
||||
Vector3 localAabbMin, localAabbMax;
|
||||
shape.GetAabb(localTransform, out localAabbMin, out localAabbMax);
|
||||
if (_localAabbMin.X > localAabbMin.X)
|
||||
{
|
||||
_localAabbMin.X = localAabbMin.X;
|
||||
}
|
||||
if (_localAabbMax.X < localAabbMax.X)
|
||||
{
|
||||
_localAabbMax.X = localAabbMax.X;
|
||||
}
|
||||
if (_localAabbMin.Y > localAabbMin.Y)
|
||||
{
|
||||
_localAabbMin.Y = localAabbMin.Y;
|
||||
}
|
||||
if (_localAabbMax.Y < localAabbMax.Y)
|
||||
{
|
||||
_localAabbMax.Y = localAabbMax.Y;
|
||||
}
|
||||
if (_localAabbMin.Z > localAabbMin.Z)
|
||||
{
|
||||
_localAabbMin.Z = localAabbMin.Z;
|
||||
}
|
||||
if (_localAabbMax.Z < localAabbMax.Z)
|
||||
{
|
||||
_localAabbMax.Z = localAabbMax.Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public abstract class ConcaveShape : CollisionShape
|
||||
{
|
||||
private float _collisionMargin;
|
||||
|
||||
public ConcaveShape() { }
|
||||
|
||||
public float CollisionMargin
|
||||
{
|
||||
get { return _collisionMargin; }
|
||||
set { _collisionMargin = value; }
|
||||
}
|
||||
|
||||
public override float Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return _collisionMargin;
|
||||
}
|
||||
set
|
||||
{
|
||||
_collisionMargin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax);
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// ConeShape implements a Cone shape, around the X axis
|
||||
/// </summary>
|
||||
public class ConeShapeX : ConeShape
|
||||
{
|
||||
public ConeShapeX(float radius, float height)
|
||||
: base(radius, height)
|
||||
{
|
||||
ConeUpIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ConeShape implements a Cone shape, around the Z axis
|
||||
/// </summary>
|
||||
public class ConeShapeZ : ConeShape
|
||||
{
|
||||
public ConeShapeZ(float radius, float height)
|
||||
: base(radius, height)
|
||||
{
|
||||
ConeUpIndex = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ConeShape implements a Cone shape, around the Y axis
|
||||
/// </summary>
|
||||
public class ConeShape : ConvexShape
|
||||
{
|
||||
private float _sinAngle;
|
||||
private float _radius;
|
||||
private float _height;
|
||||
private int[] _coneIndices = new int[3];
|
||||
|
||||
public ConeShape(float radius, float height)
|
||||
{
|
||||
_radius = radius;
|
||||
_height = height;
|
||||
ConeUpIndex = 1;
|
||||
_sinAngle = (_radius / (float)Math.Sqrt(_radius * _radius + _height * _height));
|
||||
}
|
||||
|
||||
public float Radius { get { return _radius; } }
|
||||
public float Height { get { return _height; } }
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.Cone;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Cone";
|
||||
}
|
||||
}
|
||||
|
||||
//choose upAxis index
|
||||
public int ConeUpIndex
|
||||
{
|
||||
get { return _coneIndices[1]; }
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
_coneIndices[0] = 1;
|
||||
_coneIndices[1] = 0;
|
||||
_coneIndices[2] = 2;
|
||||
break;
|
||||
case 1:
|
||||
_coneIndices[0] = 0;
|
||||
_coneIndices[1] = 1;
|
||||
_coneIndices[2] = 2;
|
||||
break;
|
||||
case 2:
|
||||
_coneIndices[0] = 0;
|
||||
_coneIndices[1] = 2;
|
||||
_coneIndices[2] = 1;
|
||||
break;
|
||||
default:
|
||||
BulletDebug.Assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 ConeLocalSupport(Vector3 v)
|
||||
{
|
||||
float halfHeight = _height * 0.5f;
|
||||
bool condition;
|
||||
|
||||
if (_coneIndices[1] == 0)
|
||||
condition = v.X > v.Length() * _sinAngle;
|
||||
else if (_coneIndices[1] == 1)
|
||||
condition = v.Y > v.Length() * _sinAngle;
|
||||
else
|
||||
condition = v.Z > v.Length() * _sinAngle;
|
||||
|
||||
if (condition)
|
||||
{
|
||||
Vector3 tmp = new Vector3();
|
||||
MathHelper.SetValueByIndex(ref tmp, _coneIndices[1], halfHeight);
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
float s = (float)Math.Sqrt(MathHelper.GetValueByIndex(v, _coneIndices[0]) * MathHelper.GetValueByIndex(v, _coneIndices[0])
|
||||
+ MathHelper.GetValueByIndex(v, _coneIndices[2]) * MathHelper.GetValueByIndex(v, _coneIndices[2]));
|
||||
if (s > MathHelper.Epsilon)
|
||||
{
|
||||
float d = _radius / s;
|
||||
Vector3 tmp = new Vector3();
|
||||
MathHelper.SetValueByIndex(ref tmp, _coneIndices[0], MathHelper.GetValueByIndex(v, _coneIndices[0]) * d);
|
||||
MathHelper.SetValueByIndex(ref tmp, _coneIndices[1], -halfHeight);
|
||||
MathHelper.SetValueByIndex(ref tmp, _coneIndices[2], MathHelper.GetValueByIndex(v, _coneIndices[2]) * d);
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 tmp = new Vector3();
|
||||
MathHelper.SetValueByIndex(ref tmp, _coneIndices[1], -halfHeight);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
|
||||
{
|
||||
return ConeLocalSupport(vec);
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
for (int i = 0; i < vectors.Length; i++)
|
||||
supportVerticesOut[i] = ConeLocalSupport(vectors[i]);
|
||||
}
|
||||
|
||||
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
|
||||
{
|
||||
Matrix identity = Matrix.Identity;
|
||||
Vector3 aabbMin, aabbMax;
|
||||
GetAabb(identity, out aabbMin, out aabbMax);
|
||||
|
||||
Vector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
|
||||
|
||||
float margin = Margin;
|
||||
|
||||
float lx = 2f * (halfExtents.X + margin);
|
||||
float ly = 2f * (halfExtents.Y + margin);
|
||||
float lz = 2f * (halfExtents.Z + margin);
|
||||
float x2 = lx * lx;
|
||||
float y2 = ly * ly;
|
||||
float z2 = lz * lz;
|
||||
float scaledmass = mass * 0.08333333f;
|
||||
|
||||
inertia = scaledmass * (new Vector3(y2 + z2, x2 + z2, x2 + y2));
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
|
||||
{
|
||||
Vector3 supVertex = ConeLocalSupport(vec);
|
||||
if (Margin != 0)
|
||||
{
|
||||
Vector3 vecnorm = vec;
|
||||
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
|
||||
{
|
||||
vecnorm = new Vector3(-1f, -1f, -1f);
|
||||
}
|
||||
vecnorm = Vector3.Normalize(vecnorm);
|
||||
supVertex += Margin * vecnorm;
|
||||
}
|
||||
return supVertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
|
||||
/// No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices.
|
||||
/// on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash.
|
||||
/// (memory is much slower then the cpu)
|
||||
/// </summary>
|
||||
public class ConvexHullShape : PolyhedralConvexShape
|
||||
{
|
||||
private List<Vector3> _points = new List<Vector3>();
|
||||
|
||||
public ConvexHullShape() { }
|
||||
|
||||
public override int VertexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _points.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override int EdgeCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _points.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override int PlaneCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.ConvexHull;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Convex";
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
|
||||
{
|
||||
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
|
||||
|
||||
if (Margin != 0)
|
||||
{
|
||||
Vector3 vecnorm = vec;
|
||||
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
|
||||
{
|
||||
vecnorm=new Vector3(-1, -1, -1);
|
||||
}
|
||||
vecnorm = Vector3.Normalize(vecnorm);
|
||||
supVertex += Margin * vecnorm;
|
||||
}
|
||||
return supVertex;
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec0)
|
||||
{
|
||||
Vector3 supVec = new Vector3();
|
||||
float newDot, maxDot = -1e30f;
|
||||
|
||||
Vector3 vec = vec0;
|
||||
float lenSqr = vec.LengthSquared();
|
||||
if (lenSqr < 0.0001f)
|
||||
{
|
||||
vec = new Vector3(1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float rlen = 1f / (float)Math.Sqrt(lenSqr);
|
||||
vec *= rlen;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _points.Count; i++)
|
||||
{
|
||||
Vector3 vtx = _points[i] * LocalScaling;
|
||||
|
||||
newDot = Vector3.Dot(vec, vtx);
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supVec = vtx;
|
||||
}
|
||||
}
|
||||
return supVec;
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
float newDot;
|
||||
//use 'w' component of supportVerticesOut?
|
||||
/*{
|
||||
for (int i = 0; i < numVectors; i++)
|
||||
{
|
||||
supportVerticesOut[i][3] = -1e30f;
|
||||
}
|
||||
}*/
|
||||
#warning Warning!
|
||||
for (int i = 0; i < _points.Count; i++)
|
||||
{
|
||||
Vector3 vtx = _points[i] * LocalScaling;
|
||||
|
||||
for (int j = 0; j < vectors.Length; j++)
|
||||
{
|
||||
newDot = Vector3.Dot(vectors[j], vtx);
|
||||
if (newDot > -1e30f)
|
||||
{
|
||||
//WARNING: don't swap next lines, the w component would get overwritten!
|
||||
supportVerticesOut[j] = vtx;
|
||||
//supportVerticesOut[j][3] = newDot;
|
||||
#warning Warning!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
|
||||
{
|
||||
int index0 = i % _points.Count;
|
||||
int index1 = (i + 1) % _points.Count;
|
||||
pa = _points[index0] * LocalScaling;
|
||||
pb = _points[index1] * LocalScaling;
|
||||
}
|
||||
|
||||
public override void GetVertex(int i, out Vector3 vtx)
|
||||
{
|
||||
vtx = _points[i] * LocalScaling;
|
||||
}
|
||||
|
||||
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
|
||||
{
|
||||
planeNormal = new Vector3();
|
||||
planeSupport = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
|
||||
public override bool IsInside(Vector3 pt, float tolerance)
|
||||
{
|
||||
BulletDebug.Assert(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// ConvexShape is an abstract shape interface.
|
||||
/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface.
|
||||
/// used in combination with GJK or btConvexCast
|
||||
/// </summary>
|
||||
public abstract class ConvexShape : CollisionShape
|
||||
{
|
||||
private const int _maxPreferredPenetrationDirections = 10;
|
||||
private const float _convexDistanceMargin = 0.04f;
|
||||
|
||||
private Vector3 _localScaling;
|
||||
private Vector3 _implicitShapeDimensions;
|
||||
private float _collisionMargin;
|
||||
|
||||
public ConvexShape()
|
||||
: base()
|
||||
{
|
||||
_localScaling = Vector3.One;
|
||||
_collisionMargin = ConvexDistanceMargin;
|
||||
}
|
||||
|
||||
public static int MaxPreferredPenetrationDirections { get { return _maxPreferredPenetrationDirections; } }
|
||||
public static float ConvexDistanceMargin { get { return _convexDistanceMargin; } }
|
||||
|
||||
public Vector3 ImplicitShapeDimensions { get { return _implicitShapeDimensions; } protected set { _implicitShapeDimensions = value; } }
|
||||
public virtual int PreferredPenetrationDirectionsCount { get { return 0; } }
|
||||
|
||||
protected float CollisionMargin { get { return _collisionMargin; } set { _collisionMargin = value; } }
|
||||
|
||||
public virtual void GetPreferredPenetrationDirection(int index, out Vector3 penetrationVector)
|
||||
{
|
||||
penetrationVector = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
|
||||
public abstract Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec);
|
||||
//notice that the vectors should be unit length
|
||||
public abstract void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut);
|
||||
|
||||
/// <summary>
|
||||
/// getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="aabbMin"></param>
|
||||
/// <param name="aabbMax"></param>
|
||||
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
|
||||
{
|
||||
GetAabbSlow(t, out aabbMin, out aabbMax);
|
||||
}
|
||||
|
||||
public override Vector3 LocalScaling
|
||||
{
|
||||
get
|
||||
{
|
||||
return _localScaling;
|
||||
}
|
||||
set
|
||||
{
|
||||
_localScaling = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override float Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return _collisionMargin;
|
||||
}
|
||||
set
|
||||
{
|
||||
_collisionMargin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Vector3 LocalGetSupportingVertex(Vector3 vec)
|
||||
{
|
||||
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
|
||||
|
||||
if (Margin != 0f)
|
||||
{
|
||||
Vector3 vecnorm = vec;
|
||||
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
|
||||
{
|
||||
vecnorm = new Vector3(-1f, -1f, -1f);
|
||||
}
|
||||
vecnorm.Normalize();
|
||||
supVertex += Margin * vecnorm;
|
||||
}
|
||||
return supVertex;
|
||||
}
|
||||
|
||||
public virtual void GetAabbSlow(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
|
||||
{
|
||||
float margin = Margin;
|
||||
aabbMax = new Vector3();
|
||||
aabbMin = new Vector3();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Vector3 vec = new Vector3(0f, 0f, 0f);
|
||||
MathHelper.SetElement(ref vec, i, 1);
|
||||
|
||||
Vector3 sv = LocalGetSupportingVertex(Vector3.TransformNormal(vec, t));
|
||||
|
||||
Vector3 tmp = MathHelper.MatrixToVector(t, sv);
|
||||
MathHelper.SetElement(ref aabbMax, i, MathHelper.GetElement(tmp, i) + margin);
|
||||
MathHelper.SetElement(ref vec, i, -1f);
|
||||
tmp = MathHelper.MatrixToVector(t, LocalGetSupportingVertex(Vector3.TransformNormal(vec, t)));
|
||||
MathHelper.SetElement(ref aabbMin, i, MathHelper.GetElement(tmp, i) - margin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// ConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use ConvexHullShape instead.
|
||||
/// It uses the StridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data.
|
||||
/// </summary>
|
||||
public class ConvexTriangleMeshShape : PolyhedralConvexShape
|
||||
{
|
||||
private StridingMeshInterface _stridingMesh;
|
||||
|
||||
public ConvexTriangleMeshShape(StridingMeshInterface meshInterface)
|
||||
{
|
||||
_stridingMesh = meshInterface;
|
||||
}
|
||||
|
||||
public StridingMeshInterface getStridingMesh()
|
||||
{
|
||||
return _stridingMesh;
|
||||
}
|
||||
|
||||
public override int VertexCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override int EdgeCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override int PlaneCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalScaling
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.LocalScaling;
|
||||
}
|
||||
set
|
||||
{
|
||||
_stridingMesh.Scaling = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.ConvexTriangleMesh;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ConvexTrimesh";
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
|
||||
{
|
||||
pa = new Vector3();
|
||||
pb = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
|
||||
public override void GetVertex(int i, out Vector3 vtx)
|
||||
{
|
||||
vtx = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
|
||||
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
|
||||
{
|
||||
planeNormal = new Vector3();
|
||||
planeSupport = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
|
||||
public override bool IsInside(Vector3 pt, float tolerance)
|
||||
{
|
||||
BulletDebug.Assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
|
||||
{
|
||||
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
|
||||
|
||||
if (Margin != 0)
|
||||
{
|
||||
Vector3 vecnorm = vec;
|
||||
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
|
||||
{
|
||||
vecnorm = new Vector3(-1, -1, -1);
|
||||
}
|
||||
vecnorm = Vector3.Normalize(vecnorm);
|
||||
supVertex += Margin * vecnorm;
|
||||
}
|
||||
return supVertex;
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec0)
|
||||
{
|
||||
Vector3 supVec = new Vector3();
|
||||
|
||||
Vector3 vec = vec0;
|
||||
float lenSqr = vec.LengthSquared();
|
||||
if (lenSqr < 0.0001f)
|
||||
{
|
||||
vec = new Vector3(1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float rlen = 1f / (float)Math.Sqrt(lenSqr);
|
||||
vec *= rlen;
|
||||
}
|
||||
|
||||
LocalSupportVertexCallback supportCallback = new LocalSupportVertexCallback(vec);
|
||||
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
|
||||
_stridingMesh.InternalProcessAllTriangles(supportCallback, -aabbMax, aabbMax);
|
||||
supVec = supportCallback.SupportVertexLocal;
|
||||
|
||||
return supVec;
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
//use 'w' component of supportVerticesOut?
|
||||
/*{
|
||||
for (int i = 0; i < numVectors; i++)
|
||||
{
|
||||
supportVerticesOut[i][3] = -1e30f;
|
||||
}
|
||||
}*/
|
||||
for (int j = 0; j < vectors.Length; j++)
|
||||
{
|
||||
Vector3 vec = vectors[j];
|
||||
LocalSupportVertexCallback supportCallback = new LocalSupportVertexCallback(vec);
|
||||
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
|
||||
_stridingMesh.InternalProcessAllTriangles(supportCallback, -aabbMax, aabbMax);
|
||||
supportVerticesOut[j] = supportCallback.SupportVertexLocal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// implements cylinder shape interface
|
||||
/// </summary>
|
||||
public class CylinderShape : BoxShape
|
||||
{
|
||||
public CylinderShape(Vector3 halfExtents)
|
||||
: base(halfExtents)
|
||||
{
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.Cylinder;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int UpAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual float Radius
|
||||
{
|
||||
get
|
||||
{
|
||||
return HalfExtents.Z;
|
||||
}
|
||||
}
|
||||
|
||||
//debugging
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CylinderY";
|
||||
}
|
||||
}
|
||||
|
||||
//getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
||||
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
|
||||
{
|
||||
GetAabbSlow(t, out aabbMin, out aabbMax);
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
|
||||
{
|
||||
return CylinderLocalSupportY(HalfExtents, vec);
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
for (int i = 0; i < vectors.Length; i++)
|
||||
{
|
||||
supportVerticesOut[i] = CylinderLocalSupportY(HalfExtents, vectors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
|
||||
{
|
||||
|
||||
Vector3 supVertex;
|
||||
supVertex = LocalGetSupportingVertexWithoutMargin(vec);
|
||||
|
||||
if (Margin != 0)
|
||||
{
|
||||
Vector3 vecnorm = vec;
|
||||
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
|
||||
{
|
||||
vecnorm=new Vector3(-1, -1, -1);
|
||||
}
|
||||
vecnorm = Vector3.Normalize(vecnorm);
|
||||
supVertex += Margin * vecnorm;
|
||||
}
|
||||
return supVertex;
|
||||
}
|
||||
|
||||
private Vector3 CylinderLocalSupportY(Vector3 halfExtents, Vector3 v)
|
||||
{
|
||||
float radius = halfExtents.X;
|
||||
float halfHeight = halfExtents.Y;
|
||||
|
||||
Vector3 tmp = new Vector3();
|
||||
float d;
|
||||
|
||||
float s = (float)Math.Sqrt(v.X * v.X + v.Z * v.Z);
|
||||
if (s != 0)
|
||||
{
|
||||
d = radius / s;
|
||||
tmp.X = v.X * d;
|
||||
tmp.Y = v.Y < 0 ? -halfHeight : halfHeight;
|
||||
tmp.Z = v.Z * d;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.X = radius;
|
||||
tmp.Y = v.Y < 0 ? -halfHeight : halfHeight;
|
||||
tmp.Z = 0;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class CylinderShapeX : CylinderShape
|
||||
{
|
||||
public CylinderShapeX(Vector3 halfExtents)
|
||||
: base(halfExtents) { }
|
||||
|
||||
public override int UpAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override float Radius
|
||||
{
|
||||
get
|
||||
{
|
||||
return HalfExtents.Y;
|
||||
}
|
||||
}
|
||||
|
||||
//debugging
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CylinderX";
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
|
||||
{
|
||||
return CylinderLocalSupportX(HalfExtents, vec);
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
for (int i = 0; i < vectors.Length; i++)
|
||||
{
|
||||
supportVerticesOut[i] = CylinderLocalSupportX(HalfExtents, vectors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 CylinderLocalSupportX(Vector3 halfExtents, Vector3 v)
|
||||
{
|
||||
//mapping depends on how cylinder local orientation is
|
||||
// extents of the cylinder is: X,Y is for radius, and Z for height
|
||||
float radius = halfExtents.Y;
|
||||
float halfHeight = halfExtents.X;
|
||||
|
||||
Vector3 tmp = new Vector3();
|
||||
float d;
|
||||
|
||||
float s = (float)Math.Sqrt(v.Y * v.Y + v.Z * v.Z);
|
||||
if (s != 0)
|
||||
{
|
||||
d = radius / s;
|
||||
tmp.Y = v.Y * d;
|
||||
tmp.X = v.X < 0 ? -halfHeight : halfHeight;
|
||||
tmp.Z = v.Z * d;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.Y = radius;
|
||||
tmp.X = v.X < 0 ? -halfHeight : halfHeight;
|
||||
tmp.Z = 0;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class CylinderShapeZ : CylinderShape
|
||||
{
|
||||
public CylinderShapeZ(Vector3 halfExtents)
|
||||
: base(halfExtents) { }
|
||||
|
||||
public override int UpAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public override float Radius
|
||||
{
|
||||
get
|
||||
{
|
||||
return HalfExtents.X;
|
||||
}
|
||||
}
|
||||
|
||||
//debugging
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CylinderZ";
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
|
||||
{
|
||||
return CylinderLocalSupportZ(HalfExtents, vec);
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
for (int i = 0; i < vectors.Length; i++)
|
||||
{
|
||||
supportVerticesOut[i] = CylinderLocalSupportZ(HalfExtents, vectors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 CylinderLocalSupportZ(Vector3 halfExtents, Vector3 v)
|
||||
{
|
||||
//mapping depends on how cylinder local orientation is
|
||||
// extents of the cylinder is: X,Y is for radius, and Z for height
|
||||
float radius = halfExtents.X;
|
||||
float halfHeight = halfExtents.Z;
|
||||
|
||||
Vector3 tmp = new Vector3();
|
||||
float d;
|
||||
|
||||
float s = (float)Math.Sqrt(v.X * v.X + v.Y * v.Y);
|
||||
if (s != 0)
|
||||
{
|
||||
d = radius / s;
|
||||
tmp.X = v.X * d;
|
||||
tmp.Z = v.Z < 0 ? -halfHeight : halfHeight;
|
||||
tmp.Y = v.Y * d;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.X = radius;
|
||||
tmp.Z = v.Z < 0 ? -halfHeight : halfHeight;
|
||||
tmp.Y = 0;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class EmptyShape : ConcaveShape
|
||||
{
|
||||
private Vector3 _localScaling;
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Empty";
|
||||
}
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalScaling
|
||||
{
|
||||
get
|
||||
{
|
||||
return _localScaling;
|
||||
}
|
||||
set
|
||||
{
|
||||
_localScaling = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ProcessAllTriangles(ITriangleCallback callback, Microsoft.Xna.Framework.Vector3 aabbMin, Microsoft.Xna.Framework.Vector3 aabbMax)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
|
||||
{
|
||||
Vector3 margin = new Vector3(Margin, Margin, Margin);
|
||||
aabbMin = t.Translation - margin;
|
||||
aabbMax = t.Translation + margin;
|
||||
}
|
||||
|
||||
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
|
||||
{
|
||||
inertia = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class FilteredCallback : ITriangleIndexCallback
|
||||
{
|
||||
private ITriangleCallback _callback;
|
||||
private Vector3 _aabbMin;
|
||||
private Vector3 _aabbMax;
|
||||
|
||||
public FilteredCallback(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
_callback = callback;
|
||||
_aabbMin = aabbMin;
|
||||
_aabbMax = aabbMax;
|
||||
}
|
||||
|
||||
public ITriangleCallback TriangleCallback { get { return _callback; } set { _callback = value; } }
|
||||
public Vector3 AabbMin { get { return _aabbMin; } set { _aabbMin = value; } }
|
||||
public Vector3 AabbMax { get { return _aabbMax; } set { _aabbMax = value; } }
|
||||
|
||||
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
|
||||
{
|
||||
if (MathHelper.TestTriangleAgainstAabb2(triangle, _aabbMin, _aabbMax))
|
||||
{
|
||||
//check aabb in triangle-space, before doing this
|
||||
_callback.ProcessTriangle(triangle, partId, triangleIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public interface ITriangleIndexCallback
|
||||
{
|
||||
void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public class LocalSupportVertexCallback : ITriangleIndexCallback
|
||||
{
|
||||
private Vector3 _supportVertexLocal;
|
||||
private float _maxDot;
|
||||
private Vector3 _supportVecLocal;
|
||||
|
||||
public LocalSupportVertexCallback(Vector3 supportVecLocal)
|
||||
{
|
||||
_supportVertexLocal = new Vector3();
|
||||
_maxDot = -1e30f;
|
||||
_supportVecLocal = supportVecLocal;
|
||||
}
|
||||
|
||||
public float MaxDot { get { return _maxDot; } set { _maxDot = value; } }
|
||||
public Vector3 SupportVertexLocal { get { return _supportVecLocal; } set { _supportVecLocal = value; } }
|
||||
|
||||
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
float dot = Vector3.Dot(_supportVecLocal, triangle[i]);
|
||||
if (dot > _maxDot)
|
||||
{
|
||||
_maxDot = dot;
|
||||
_supportVertexLocal = triangle[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// MinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes.
|
||||
/// </summary>
|
||||
public class MinkowskiSumShape : ConvexShape
|
||||
{
|
||||
private Matrix _transformA;
|
||||
private Matrix _transformB;
|
||||
private ConvexShape _shapeA;
|
||||
private ConvexShape _shapeB;
|
||||
|
||||
public MinkowskiSumShape(ConvexShape shapeA, ConvexShape shapeB)
|
||||
{
|
||||
_shapeA = shapeA;
|
||||
_shapeB = shapeB;
|
||||
_transformA = Matrix.Identity;
|
||||
_transformB = Matrix.Identity;
|
||||
}
|
||||
|
||||
public Matrix TransformA { get { return _transformA; } set { _transformA = value; } }
|
||||
public Matrix TransformB { get { return _transformB; } set { _transformB = value; } }
|
||||
public ConvexShape ShapeA { get { return _shapeA; } }
|
||||
public ConvexShape ShapeB { get { return _shapeB; } }
|
||||
|
||||
public override float Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return _shapeA.Margin + _shapeB.Margin;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Margin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.MinkowskiDifference;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "MinkowskiSum";
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
|
||||
{
|
||||
Vector3 supVertexA = MathHelper.MatrixToVector(_transformA, _shapeA.LocalGetSupportingVertexWithoutMargin(Vector3.TransformNormal(vec, _transformA)));
|
||||
Vector3 supVertexB = MathHelper.MatrixToVector(_transformB, _shapeB.LocalGetSupportingVertexWithoutMargin(Vector3.TransformNormal(vec, _transformB)));
|
||||
return supVertexA + supVertexB;
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
for (int i = 0; i < vectors.Length; i++)
|
||||
supportVerticesOut[i] = LocalGetSupportingVertexWithoutMargin(vectors[i]);
|
||||
}
|
||||
|
||||
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
|
||||
{
|
||||
inertia = new Vector3();
|
||||
BulletDebug.Assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// MultiSphereShape represents implicit convex hull of a collection of spheres (using getSupportingVertex)
|
||||
/// </summary>
|
||||
public class MultiSphereShape : ConvexShape
|
||||
{
|
||||
private const int _maxNumSpheres = 5;
|
||||
private Vector3[] _localPositions = new Vector3[MaxNumSpheres];
|
||||
private float[] _radi = new float[MaxNumSpheres];
|
||||
private Vector3 _inertiaHalfExtents;
|
||||
|
||||
private int m_numSpheres;
|
||||
|
||||
public MultiSphereShape(Vector3 inertiaHalfExtents, Vector3[] positions, float[] radi, int numSpheres)
|
||||
{
|
||||
_inertiaHalfExtents = inertiaHalfExtents;
|
||||
float startMargin = 1e30f;
|
||||
|
||||
m_numSpheres = numSpheres;
|
||||
for (int i = 0; i < m_numSpheres; i++)
|
||||
{
|
||||
_localPositions[i] = positions[i];
|
||||
_radi[i] = radi[i];
|
||||
if (radi[i] < startMargin)
|
||||
startMargin = radi[i];
|
||||
}
|
||||
Margin = startMargin;
|
||||
}
|
||||
|
||||
public static int MaxNumSpheres { get { return _maxNumSpheres; } }
|
||||
|
||||
public override BroadphaseNativeTypes ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
return BroadphaseNativeTypes.MultiSphere;
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "MultiSphere";
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vecA)
|
||||
{
|
||||
Vector3 supVec = new Vector3();
|
||||
|
||||
float maxDot = -1e30f;
|
||||
|
||||
|
||||
Vector3 vec = vecA;
|
||||
float lenSqr = vec.LengthSquared();
|
||||
if (lenSqr < 0.0001f)
|
||||
{
|
||||
vec = new Vector3(1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float rlen = 1f / (float)Math.Sqrt(lenSqr);
|
||||
vec *= rlen;
|
||||
}
|
||||
|
||||
Vector3 vtx;
|
||||
float newDot;
|
||||
|
||||
for (int i = 0; i < m_numSpheres; i++)
|
||||
{
|
||||
vtx = _localPositions[i] + vec * LocalScaling * _radi[i] - vec * Margin;
|
||||
newDot = Vector3.Dot(vec, vtx);
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supVec = vtx;
|
||||
}
|
||||
}
|
||||
|
||||
return supVec;
|
||||
}
|
||||
|
||||
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
|
||||
{
|
||||
for (int j = 0; j < vectors.Length; j++)
|
||||
{
|
||||
float maxDot = -1e30f;
|
||||
Vector3 vtx;
|
||||
float newDot;
|
||||
|
||||
for (int i = 0; i < m_numSpheres; i++)
|
||||
{
|
||||
vtx = _localPositions[i] + vectors[j] * LocalScaling * _radi[i] - vectors[j] * Margin;
|
||||
newDot = Vector3.Dot(vectors[j], vtx);
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supportVerticesOut[j] = vtx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
|
||||
{
|
||||
//as an approximation, take the inertia of the box that bounds the spheres
|
||||
Matrix ident = Matrix.Identity;
|
||||
Vector3 halfExtents = _inertiaHalfExtents;
|
||||
|
||||
float margin = ConvexDistanceMargin;
|
||||
|
||||
float lx = 2f * (halfExtents.X + margin);
|
||||
float ly = 2f * (halfExtents.Y + margin);
|
||||
float lz = 2f * (halfExtents.Z + margin);
|
||||
float x2 = lx * lx;
|
||||
float y2 = ly * ly;
|
||||
float z2 = lz * lz;
|
||||
float scaledmass = mass * 0.08333333f;
|
||||
|
||||
inertia = new Vector3();
|
||||
inertia.X = scaledmass * (y2 + z2);
|
||||
inertia.Y = scaledmass * (x2 + z2);
|
||||
inertia.Z = scaledmass * (x2 + y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
public interface INodeOverlapCallback
|
||||
{
|
||||
void ProcessNode(OptimizedBvhNode node);
|
||||
}
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// OptimizedBvh store an AABB tree that can be quickly traversed on CPU (and SPU,GPU in future)
|
||||
/// </summary>
|
||||
public class OptimizedBvh
|
||||
{
|
||||
private static int _maxIterations = 0;
|
||||
private OptimizedBvhNode _rootNode;
|
||||
|
||||
private OptimizedBvhNode[] _contiguousNodes;
|
||||
private int _curNodeIndex;
|
||||
|
||||
private List<OptimizedBvhNode> _leafNodes = new List<OptimizedBvhNode>();
|
||||
|
||||
public OptimizedBvh() { }
|
||||
|
||||
public void Build(StridingMeshInterface triangles)
|
||||
{
|
||||
NodeTriangleCallback callback = new NodeTriangleCallback(_leafNodes);
|
||||
|
||||
Vector3 aabbMin = new Vector3(-1e30f, -1e30f, -1e30f);
|
||||
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
|
||||
|
||||
triangles.InternalProcessAllTriangles(callback, aabbMin, aabbMax);
|
||||
|
||||
//now we have an array of leafnodes in m_leafNodes
|
||||
_contiguousNodes = new OptimizedBvhNode[2 * _leafNodes.Count];
|
||||
for (int i = 0; i < _contiguousNodes.Length; i++)
|
||||
_contiguousNodes[i] = new OptimizedBvhNode();
|
||||
_curNodeIndex = 0;
|
||||
|
||||
_rootNode = BuildTree(_leafNodes, 0, _leafNodes.Count);
|
||||
}
|
||||
|
||||
public OptimizedBvhNode BuildTree(List<OptimizedBvhNode> leafNodes, int startIndex, int endIndex)
|
||||
{
|
||||
OptimizedBvhNode internalNode;
|
||||
|
||||
int splitAxis, splitIndex, i;
|
||||
int numIndices = endIndex - startIndex;
|
||||
int curIndex = _curNodeIndex;
|
||||
|
||||
if (numIndices <= 0)
|
||||
throw new BulletException();
|
||||
|
||||
if (numIndices == 1)
|
||||
{
|
||||
_contiguousNodes[_curNodeIndex++] = leafNodes[startIndex];
|
||||
//return new (&m_contiguousNodes[m_curNodeIndex++]) btOptimizedBvhNode(leafNodes[startIndex]);
|
||||
return leafNodes[startIndex];
|
||||
}
|
||||
|
||||
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
|
||||
splitAxis = CalculateSplittingAxis(leafNodes, startIndex, endIndex);
|
||||
|
||||
splitIndex = SortAndCalculateSplittingIndex(leafNodes, startIndex, endIndex, splitAxis);
|
||||
|
||||
internalNode = _contiguousNodes[_curNodeIndex++];
|
||||
|
||||
internalNode.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f);
|
||||
internalNode.AabbMin = new Vector3(1e30f, 1e30f, 1e30f);
|
||||
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
internalNode.AabbMax = MathHelper.SetMax(internalNode.AabbMax, leafNodes[i].AabbMax);
|
||||
internalNode.AabbMin = MathHelper.SetMin(internalNode.AabbMin, leafNodes[i].AabbMin);
|
||||
}
|
||||
|
||||
//internalNode->m_escapeIndex;
|
||||
internalNode.LeftChild = BuildTree(leafNodes, startIndex, splitIndex);
|
||||
internalNode.RightChild = BuildTree(leafNodes, splitIndex, endIndex);
|
||||
|
||||
internalNode.EscapeIndex = _curNodeIndex - curIndex;
|
||||
return internalNode;
|
||||
}
|
||||
|
||||
public int CalculateSplittingAxis(List<OptimizedBvhNode> leafNodes, int startIndex, int endIndex)
|
||||
{
|
||||
Vector3 means = new Vector3();
|
||||
Vector3 variance = new Vector3();
|
||||
int numIndices = endIndex - startIndex;
|
||||
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
|
||||
means += center;
|
||||
}
|
||||
means *= (1f / (float)numIndices);
|
||||
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
|
||||
Vector3 diff2 = center - means;
|
||||
diff2 = diff2 * diff2;
|
||||
variance += diff2;
|
||||
}
|
||||
variance *= (1f / ((float)numIndices - 1));
|
||||
|
||||
return MathHelper.MaxAxis(variance);
|
||||
}
|
||||
|
||||
public int SortAndCalculateSplittingIndex(List<OptimizedBvhNode> leafNodes, int startIndex, int endIndex, int splitAxis)
|
||||
{
|
||||
int splitIndex = startIndex;
|
||||
int numIndices = endIndex - startIndex;
|
||||
float splitValue;
|
||||
|
||||
Vector3 means = new Vector3();
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
|
||||
means += center;
|
||||
}
|
||||
means *= (1f / (float)numIndices);
|
||||
|
||||
if (splitAxis == 0)
|
||||
splitValue = means.X;
|
||||
else if (splitAxis == 1)
|
||||
splitValue = means.Y;
|
||||
else if (splitAxis == 2)
|
||||
splitValue = means.Z;
|
||||
else
|
||||
throw new ArgumentException();
|
||||
|
||||
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
|
||||
float centerSplit;
|
||||
|
||||
if (splitAxis == 0)
|
||||
centerSplit = means.X;
|
||||
else if (splitAxis == 1)
|
||||
centerSplit = means.Y;
|
||||
else if (splitAxis == 2)
|
||||
centerSplit = means.Z;
|
||||
else
|
||||
throw new ArgumentException();
|
||||
|
||||
if (centerSplit > splitValue)
|
||||
{
|
||||
//swap
|
||||
OptimizedBvhNode tmp = leafNodes[i];
|
||||
leafNodes[i] = leafNodes[splitIndex];
|
||||
leafNodes[splitIndex] = tmp;
|
||||
splitIndex++;
|
||||
}
|
||||
}
|
||||
if ((splitIndex == startIndex) || (splitIndex == (endIndex - 1)))
|
||||
{
|
||||
splitIndex = startIndex + (numIndices >> 1);
|
||||
}
|
||||
return splitIndex;
|
||||
}
|
||||
|
||||
public void WalkTree(OptimizedBvhNode rootNode, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
bool isLeafNode, aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
|
||||
if (aabbOverlap)
|
||||
{
|
||||
isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);
|
||||
if (isLeafNode)
|
||||
{
|
||||
nodeCallback.ProcessNode(rootNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
WalkTree(rootNode.LeftChild, nodeCallback, aabbMin, aabbMax);
|
||||
WalkTree(rootNode.RightChild, nodeCallback, aabbMin, aabbMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WalkStacklessTree(OptimizedBvhNode[] rootNodeArray, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
int escapeIndex, curIndex = 0;
|
||||
int walkIterations = 0;
|
||||
bool aabbOverlap, isLeafNode;
|
||||
int rootNodeIndex = 0;
|
||||
OptimizedBvhNode rootNode = rootNodeArray[rootNodeIndex];
|
||||
|
||||
while (curIndex < _curNodeIndex)
|
||||
{
|
||||
//catch bugs in tree data
|
||||
if (walkIterations >= _curNodeIndex)
|
||||
throw new BulletException();
|
||||
|
||||
walkIterations++;
|
||||
aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
|
||||
isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);
|
||||
|
||||
if (isLeafNode && aabbOverlap)
|
||||
{
|
||||
nodeCallback.ProcessNode(rootNode);
|
||||
}
|
||||
|
||||
if (aabbOverlap || isLeafNode)
|
||||
{
|
||||
rootNodeIndex++; // this
|
||||
curIndex++;
|
||||
if (rootNodeIndex < rootNodeArray.Length)
|
||||
rootNode = rootNodeArray[rootNodeIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
escapeIndex = rootNode.EscapeIndex;
|
||||
rootNodeIndex += escapeIndex; // and this
|
||||
curIndex += escapeIndex;
|
||||
if (rootNodeIndex < rootNodeArray.Length)
|
||||
rootNode = rootNodeArray[rootNodeIndex];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_maxIterations < walkIterations)
|
||||
_maxIterations = walkIterations;
|
||||
}
|
||||
|
||||
public void ReportAabbOverlappingNodex(INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
|
||||
{
|
||||
//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
|
||||
//walkTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
|
||||
//WalkStacklessTree(_rootNode, nodeCallback, aabbMin, aabbMax);
|
||||
WalkStacklessTree(_contiguousNodes, nodeCallback, aabbMin, aabbMax);
|
||||
}
|
||||
|
||||
public void ReportSphereOverlappingNodex(INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax) { }
|
||||
}
|
||||
|
||||
public class NodeTriangleCallback : ITriangleIndexCallback
|
||||
{
|
||||
private List<OptimizedBvhNode> _triangleNodes;
|
||||
|
||||
public NodeTriangleCallback(List<OptimizedBvhNode> triangleNodes)
|
||||
{
|
||||
_triangleNodes = triangleNodes;
|
||||
}
|
||||
|
||||
public List<OptimizedBvhNode> TriangleNodes { get { return _triangleNodes; } set { _triangleNodes = value; } }
|
||||
|
||||
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
|
||||
{
|
||||
|
||||
OptimizedBvhNode node = new OptimizedBvhNode();
|
||||
node.AabbMin = new Vector3(1e30f, 1e30f, 1e30f);
|
||||
node.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f);
|
||||
|
||||
node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[0]);
|
||||
node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[0]);
|
||||
node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[1]);
|
||||
node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[1]);
|
||||
node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[2]);
|
||||
node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[2]);
|
||||
|
||||
node.EscapeIndex = -1;
|
||||
node.LeftChild = null;
|
||||
node.RightChild = null;
|
||||
|
||||
//for child nodes
|
||||
node.SubPart = partId;
|
||||
node.TriangleIndex = triangleIndex;
|
||||
|
||||
_triangleNodes.Add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace XnaDevRu.BulletX
|
||||
{
|
||||
/// <summary>
|
||||
/// OptimizedBvhNode contains both internal and leaf node information.
|
||||
/// It hasn't been optimized yet for storage. Some obvious optimizations are:
|
||||
/// Removal of the pointers (can already be done, they are not used for traversal)
|
||||
/// and storing aabbmin/max as quantized integers.
|
||||
/// 'subpart' doesn't need an integer either. It allows to re-use graphics triangle
|
||||
/// meshes stored in a non-uniform way (like batches/subparts of triangle-fans
|
||||
/// </summary>
|
||||
public class OptimizedBvhNode
|
||||
{
|
||||
private Vector3 _aabbMin;
|
||||
private Vector3 _aabbMax;
|
||||
|
||||
//these 2 pointers are obsolete, the stackless traversal just uses the escape index
|
||||
private OptimizedBvhNode _leftChild;
|
||||
private OptimizedBvhNode _rightChild;
|
||||
|
||||
private int _escapeIndex;
|
||||
|
||||
//for child nodes
|
||||
private int _subPart;
|
||||
private int _triangleIndex;
|
||||
|
||||
public Vector3 AabbMin { get { return _aabbMin; } set { _aabbMin = value; } }
|
||||
public Vector3 AabbMax { get { return _aabbMax; } set { _aabbMax = value; } }
|
||||
|
||||
public OptimizedBvhNode LeftChild { get { return _leftChild; } set { _leftChild = value; } }
|
||||
public OptimizedBvhNode RightChild { get { return _rightChild; } set { _rightChild = value; } }
|
||||
|
||||
public int EscapeIndex { get { return _escapeIndex; } set { _escapeIndex = value; } }
|
||||
|
||||
public int SubPart { get { return _subPart; } set { _subPart = value; } }
|
||||
public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user