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:
erwin.coumans
2010-02-25 20:12:40 +00:00
parent 44503b20a9
commit 40dc18f604
272 changed files with 561 additions and 44611 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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)
{
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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]);
}
}
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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")]

View File

@@ -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>

View File

@@ -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;
}
}
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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")]

View File

@@ -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>

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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")]

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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")]

View File

@@ -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>

View File

@@ -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);
}
}
}

View File

@@ -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];
}
}
}

View File

@@ -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,
}
}

View File

@@ -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);
}
}
}

View File

@@ -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,
}
}
}

View File

@@ -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);
}
}

View File

@@ -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; } }
}
}

View File

@@ -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; } }
}
}

View File

@@ -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);
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
}
}

View File

@@ -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
}
}

View File

@@ -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));
}
}
}

View File

@@ -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; } }
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
};
}
}

View File

@@ -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;
}
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
};
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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; } }
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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";
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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];
}
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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