Allow Bullet soft bodies to be created using a AddObject actuator. Added a fake world coordinate system to game soft bodies, although the vertices are already in world space.

Added Bullet/Gimpact concave collision detection to Blender. If your build system isn't updated yet, please add extern/bullet2/src/BulletCollision/Gimpact/*
This allows moving/dynamic concave triangle meshes (decomposing meshes into compound convex shapes, and using 'compound' shapes is still preferred)
This commit is contained in:
Erwin Coumans
2008-09-26 02:27:59 +00:00
parent 6732718ef1
commit a1bef84ea8
55 changed files with 14429 additions and 46 deletions

View File

@@ -23,6 +23,8 @@ subject to the following restrictions:
#include "BulletSoftBody//btSoftBodyInternals.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "LinearMath/btConvexHull.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
@@ -46,10 +48,13 @@ btVector3 startVel(0,0,0);//-10000);
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
m_prototypeTransformInitialized = false;
m_softbodyMappingDone = false;
m_collisionDelay = 0;
m_newClientInfo = 0;
m_registerCount = 0;
m_softBodyTransformInitialized = false;
// copy pointers locally to allow smart release
m_MotionState = ci.m_MotionState;
m_collisionShape = ci.m_collisionShape;
@@ -144,7 +149,7 @@ btSoftBody* CcdPhysicsController::GetSoftBody()
void CcdPhysicsController::CreateRigidbody()
{
btTransform trans = GetTransformFromMotionState(m_MotionState);
//btTransform trans = GetTransformFromMotionState(m_MotionState);
m_bulletMotionState = new BlenderBulletMotionState(m_MotionState);
///either create a btCollisionObject, btRigidBody or btSoftBody
@@ -189,18 +194,12 @@ void CcdPhysicsController::CreateRigidbody()
if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE)
{
btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape;
btAlignedObjectArray<btVector3> transformedVertices;
transformedVertices.resize(convexHull->getNumPoints());
for (int i=0;i<convexHull->getNumPoints();i++)
{
transformedVertices[i] = trans(convexHull->getPoints()[i]);
}
//psb = btSoftBodyHelpers::CreateFromConvexHull(sbi,&transformedVertices[0],convexHull->getNumPoints());
{
int nvertices = convexHull->getNumPoints();
const btVector3* vertices = &transformedVertices[0];
const btVector3* vertices = convexHull->getPoints();
btSoftBodyWorldInfo& worldInfo = softDynaWorld->getWorldInfo();
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
@@ -226,7 +225,7 @@ void CcdPhysicsController::CreateRigidbody()
{
RAS_MeshObject* rasMesh= GetShapeInfo()->GetMesh();
if (rasMesh)
if (rasMesh && !m_softbodyMappingDone)
{
//printf("apply\n");
@@ -251,17 +250,20 @@ void CcdPhysicsController::CreateRigidbody()
for(i=it.startvertex; i<it.endvertex; i++,index++)
{
RAS_TexVert* vertex = &it.vertex[i];
//search closest index, and store it in vertex
vertex->setSoftBodyIndex(0);
btScalar maxDistSqr = 1e30;
btSoftBody::tNodeArray& nodes(psb->m_nodes);
btVector3 xyz = trans(btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]));
btVector3 xyz = btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]);
for (int n=0;n<nodes.size();n++)
{
btScalar distSqr = (nodes[n].m_x - xyz).length2();
if (distSqr<maxDistSqr)
{
maxDistSqr = distSqr;
vertex->setSoftBodyIndex(n);
}
}
@@ -330,6 +332,7 @@ void CcdPhysicsController::CreateRigidbody()
}
m_softbodyMappingDone = true;
m_object = psb;
@@ -408,6 +411,13 @@ void CcdPhysicsController::CreateRigidbody()
m_MotionState->setWorldPosition(startTrans.getOrigin().getX(),startTrans.getOrigin().getY(),startTrans.getOrigin().getZ());
m_MotionState->setWorldOrientation(0,0,0,1);
if (!m_prototypeTransformInitialized)
{
m_prototypeTransformInitialized = true;
m_softBodyTransformInitialized = true;
GetSoftBody()->transform(startTrans);
}
// btVector3 wp = m_softBody->getWorldTransform().getOrigin();
// MT_Point3 center(wp.getX(),wp.getY(),wp.getZ());
// m_gameobj->NodeSetWorldPosition(center);
@@ -572,6 +582,7 @@ void CcdPhysicsController::WriteDynamicsToMotionState()
// controller replication
void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
{
m_softBodyTransformInitialized=false;
m_MotionState = motionstate;
m_registerCount = 0;
m_collisionShape = NULL;
@@ -652,7 +663,7 @@ void CcdPhysicsController::SetCenterOfMassTransform(btTransform& xform)
//either collision object or soft body?
if (GetSoftBody())
{
//not yet
} else
{
@@ -761,6 +772,9 @@ void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float
SetCenterOfMassTransform(xform);
// not required
//m_bulletMotionState->setWorldTransform(xform);
}
}
@@ -781,6 +795,15 @@ void CcdPhysicsController::setWorldOrientation(const btMatrix3x3& orn)
SetCenterOfMassTransform(xform);
// not required
//m_bulletMotionState->setWorldTransform(xform);
//only once!
if (!m_softBodyTransformInitialized && GetSoftBody())
{
m_softbodyStartTrans.setBasis(orn);
xform.setOrigin(m_softbodyStartTrans.getOrigin());
GetSoftBody()->transform(xform);
m_softBodyTransformInitialized = true;
}
}
}
@@ -799,6 +822,8 @@ void CcdPhysicsController::setPosition(float posX,float posY,float posZ)
btTransform xform = m_object->getWorldTransform();
xform.setOrigin(btVector3(posX,posY,posZ));
SetCenterOfMassTransform(xform);
if (!m_softBodyTransformInitialized)
m_softbodyStartTrans.setOrigin(xform.getOrigin());
// not required
//m_bulletMotionState->setWorldTransform(xform);
}
@@ -931,6 +956,15 @@ void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,floa
m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
}
btSoftBody* soft = GetSoftBody();
if (soft)
{
if (local)
{
linVel = m_softbodyStartTrans.getBasis()*linVel;
}
soft->setVelocity(linVel);
} else
{
btTransform xform = m_object->getWorldTransform();
if (local)
@@ -940,7 +974,6 @@ void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,floa
btRigidBody* body = GetRigidBody();
if (body)
body->setLinearVelocity(linVel);
}
}
}
@@ -1186,8 +1219,10 @@ CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mes
return NULL;
}
bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bool useGimpact)
{
m_useGimpact = useGimpact;
// assume no shape information
// no support for dynamic change of shape yet
assert(m_meshObject == NULL);
@@ -1353,19 +1388,35 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
// 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering
// One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1
// and btScaledBvhTriangleMeshShape otherwise.
if (!m_unscaledShape)
if (m_useGimpact)
{
collisionMeshData = new btTriangleMesh();
// m_vertexArray is necessarily a multiple of 3
for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
collisionMeshData = new btTriangleMesh();
// m_vertexArray is necessarily a multiple of 3
for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
{
collisionMeshData->addTriangle(*it++,*it++,*it++);
}
btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(collisionMeshData);
collisionShape = gimpactShape;
gimpactShape->updateBound();
} else
{
if (!m_unscaledShape)
{
collisionMeshData->addTriangle(*it++,*it++,*it++);
collisionMeshData = new btTriangleMesh();
// m_vertexArray is necessarily a multiple of 3
for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
{
collisionMeshData->addTriangle(*it++,*it++,*it++);
}
// this shape will be shared and not deleted until shapeInfo is deleted
m_unscaledShape = new btBvhTriangleMeshShape( collisionMeshData, true );
m_unscaledShape->recalcLocalAabb();
}
// this shape will be shared and not deleted until shapeInfo is deleted
m_unscaledShape = new btBvhTriangleMeshShape( collisionMeshData, true );
m_unscaledShape->recalcLocalAabb();
collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f));
}
collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f));
break;
case PHY_SHAPE_COMPOUND: