Merge from trunk

(The last time there was some files missing due to failed connection to svn server while merging.. thats why this stuff of reverting last merge and redoing it)

svn merge -r 16231:16608 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
Andre Susano Pinto
2008-09-19 14:15:36 +00:00
parent 2f9f0710d1
commit 656ee61718
777 changed files with 61444 additions and 18725 deletions

View File

@@ -23,6 +23,7 @@ subject to the following restrictions:
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
//profiling/timings
#include "LinearMath/btQuickprof.h"
@@ -53,6 +54,7 @@ void DrawRasterizerLine(const float* from,const float* to,int color);
#include <stdio.h>
#include <string.h> // for memset
#ifdef NEW_BULLET_VEHICLE_SUPPORT
class WrapperVehicle : public PHY_IVehicle
@@ -329,30 +331,23 @@ m_filterCallback(NULL)
{
m_triggerCallbacks[i] = 0;
}
m_collisionConfiguration = new btDefaultCollisionConfiguration();
if (!dispatcher)
{
dispatcher = new btCollisionDispatcher();
dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_ownDispatcher = dispatcher;
}
if(!pairCache)
{
//todo: calculate/let user specify this world sizes
btVector3 worldMin(-10000,-10000,-10000);
btVector3 worldMax(10000,10000,10000);
pairCache = new btAxisSweep3(worldMin,worldMax);
// remember that this was allocated by us so that we can release it
m_ownPairCache = pairCache;
//broadphase = new btSimpleBroadphase();
}
m_broadphase = new btDbvtBroadphase();
m_filterCallback = new CcdOverlapFilterCallBack(this);
pairCache->setOverlapFilterCallback(m_filterCallback);
m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback);
setSolverType(1);//issues with quickstep and memory allocations
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,m_solver);
// m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_debugDrawer = 0;
m_gravity = btVector3(0.f,-10.f,0.f);
m_dynamicsWorld->setGravity(m_gravity);
@@ -363,24 +358,43 @@ m_filterCallback(NULL)
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
btRigidBody* body = ctrl->GetRigidBody();
btCollisionObject* obj = ctrl->GetCollisionObject();
//this m_userPointer is just used for triggers, see CallbackTriggers
body->setUserPointer(ctrl);
obj->setUserPointer(ctrl);
if (body)
body->setGravity( m_gravity );
body->setGravity( m_gravity );
m_controllers.insert(ctrl);
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
if (body->isStaticOrKinematicObject())
if (body)
{
body->setActivationState(ISLAND_SLEEPING);
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
} else
{
if (ctrl->GetSoftBody())
{
//not yet
btAssert(0);
//m_dynamicsWorld->addSo
} else
{
if (obj->getCollisionShape())
{
m_dynamicsWorld->addCollisionObject(obj,ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
}
}
if (obj->isStaticOrKinematicObject())
{
obj->setActivationState(ISLAND_SLEEPING);
}
//CollisionObject(body,ctrl->GetCollisionFilterGroup(),ctrl->GetCollisionFilterMask());
assert(body->getBroadphaseHandle());
assert(obj->getBroadphaseHandle());
btBroadphaseInterface* scene = getBroadphase();
@@ -389,7 +403,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
assert(shapeinterface);
const btTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform();
const btTransform& t = ctrl->GetCollisionObject()->getWorldTransform();
btPoint3 minAabb,maxAabb;
@@ -401,32 +415,34 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
//extent it with the motion
btVector3 linMotion = body->getLinearVelocity()*timeStep;
if (body)
{
btVector3 linMotion = body->getLinearVelocity()*timeStep;
float maxAabbx = maxAabb.getX();
float maxAabby = maxAabb.getY();
float maxAabbz = maxAabb.getZ();
float minAabbx = minAabb.getX();
float minAabby = minAabb.getY();
float minAabbz = minAabb.getZ();
float maxAabbx = maxAabb.getX();
float maxAabby = maxAabb.getY();
float maxAabbz = maxAabb.getZ();
float minAabbx = minAabb.getX();
float minAabby = minAabb.getY();
float minAabbz = minAabb.getZ();
if (linMotion.x() > 0.f)
maxAabbx += linMotion.x();
else
minAabbx += linMotion.x();
if (linMotion.y() > 0.f)
maxAabby += linMotion.y();
else
minAabby += linMotion.y();
if (linMotion.z() > 0.f)
maxAabbz += linMotion.z();
else
minAabbz += linMotion.z();
if (linMotion.x() > 0.f)
maxAabbx += linMotion.x();
else
minAabbx += linMotion.x();
if (linMotion.y() > 0.f)
maxAabby += linMotion.y();
else
minAabby += linMotion.y();
if (linMotion.z() > 0.f)
maxAabbz += linMotion.z();
else
minAabbz += linMotion.z();
minAabb = btVector3(minAabbx,minAabby,minAabbz);
maxAabb = btVector3(maxAabbx,maxAabby,maxAabbz);
minAabb = btVector3(minAabbx,minAabby,minAabbz);
maxAabb = btVector3(maxAabbx,maxAabby,maxAabbz);
}
@@ -435,8 +451,22 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
{
//also remove constraint
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
btRigidBody* body = ctrl->GetRigidBody();
if (body)
{
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
} else
{
//if a softbody
if (ctrl->GetSoftBody())
{
//not yet
btAssert(0);
} else
{
m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject());
}
}
m_controllers.erase(ctrl);
if (ctrl->m_registerCount != 0)
@@ -451,13 +481,20 @@ void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctr
// this function is used when the collisionning group of a controller is changed
// remove and add the collistioning object
btRigidBody* body = ctrl->GetRigidBody();
btVector3 inertia;
m_dynamicsWorld->removeCollisionObject(body);
body->setCollisionFlags(newCollisionFlags);
body->getCollisionShape()->calculateLocalInertia(newMass, inertia);
body->setMassProps(newMass, inertia);
m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask);
btCollisionObject* obj = ctrl->GetCollisionObject();
if (obj)
{
btVector3 inertia(0.0,0.0,0.0);
m_dynamicsWorld->removeCollisionObject(obj);
obj->setCollisionFlags(newCollisionFlags);
if (body)
{
if (newMass)
body->getCollisionShape()->calculateLocalInertia(newMass, inertia);
body->setMassProps(newMass, inertia);
}
m_dynamicsWorld->addCollisionObject(obj, newCollisionGroup, newCollisionMask);
}
// to avoid nasty interaction, we must update the property of the controller as well
ctrl->m_cci.m_mass = newMass;
ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup;
@@ -469,9 +506,9 @@ void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctr
{
if (m_controllers.insert(ctrl).second)
{
btRigidBody* body = ctrl->GetRigidBody();
body->setUserPointer(ctrl);
m_dynamicsWorld->addCollisionObject(body,
btCollisionObject* obj = ctrl->GetCollisionObject();
obj->setUserPointer(ctrl);
m_dynamicsWorld->addCollisionObject(obj,
ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
}
@@ -480,7 +517,19 @@ void CcdPhysicsEnvironment::disableCcdPhysicsController(CcdPhysicsController* ct
{
if (m_controllers.erase(ctrl))
{
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
btRigidBody* body = ctrl->GetRigidBody();
if (body)
{
m_dynamicsWorld->removeRigidBody(body);
} else
{
if (ctrl->GetSoftBody())
{
} else
{
m_dynamicsWorld->removeCollisionObject(body);
}
}
}
}
@@ -518,6 +567,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
veh->SyncWheels();
}
m_dynamicsWorld->debugDrawWorld();
CallbackTriggers();
return true;
@@ -578,7 +630,7 @@ void CcdPhysicsEnvironment::setSolverDamping(float damping)
void CcdPhysicsEnvironment::setLinearAirDamping(float damping)
{
gLinearAirDamping = damping;
//gLinearAirDamping = damping;
}
void CcdPhysicsEnvironment::setUseEpa(bool epa)
@@ -597,7 +649,7 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
{
m_solver = new btSequentialImpulseConstraintSolver();
((btSequentialImpulseConstraintSolver*)m_solver)->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
// ((btSequentialImpulseConstraintSolver*)m_solver)->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
break;
}
}
@@ -659,9 +711,10 @@ int CcdPhysicsEnvironment::createUniversalD6Constraint(
{
bool useReferenceFrameA = true;
genericConstraint = new btGeneric6DofConstraint(
*rb0,*rb1,
frameInA,frameInB);
frameInA,frameInB,useReferenceFrameA);
genericConstraint->setLinearLowerLimit(linearMinLimits);
genericConstraint->setLinearUpperLimit(linearMaxLimits);
genericConstraint->setAngularLowerLimit(angularMinLimits);
@@ -709,35 +762,54 @@ void CcdPhysicsEnvironment::removeConstraint(int constraintId)
struct FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{
PHY_IPhysicsController* m_ignoreClient;
PHY_IRayCastFilterCallback& m_phyRayFilter;
const btCollisionShape* m_hitTriangleShape;
int m_hitTriangleIndex;
FilterClosestRayResultCallback (PHY_IPhysicsController* ignoreClient,const btVector3& rayFrom,const btVector3& rayTo)
FilterClosestRayResultCallback (PHY_IRayCastFilterCallback& phyRayFilter,const btVector3& rayFrom,const btVector3& rayTo)
: btCollisionWorld::ClosestRayResultCallback(rayFrom,rayTo),
m_ignoreClient(ignoreClient)
m_phyRayFilter(phyRayFilter),
m_hitTriangleShape(NULL),
m_hitTriangleIndex(0)
{
}
virtual ~FilterClosestRayResultCallback()
{
}
virtual float AddSingleResult( btCollisionWorld::LocalRayResult& rayResult)
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
{
if (!(proxy0->m_collisionFilterGroup & m_collisionFilterMask))
return false;
if (!(m_collisionFilterGroup & proxy0->m_collisionFilterMask))
return false;
btCollisionObject* object = (btCollisionObject*)proxy0->m_clientObject;
CcdPhysicsController* phyCtrl = static_cast<CcdPhysicsController*>(object->getUserPointer());
if (phyCtrl == m_phyRayFilter.m_ignoreController)
return false;
return m_phyRayFilter.needBroadphaseRayCast(phyCtrl);
}
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
{
CcdPhysicsController* curHit = static_cast<CcdPhysicsController*>(rayResult.m_collisionObject->getUserPointer());
//ignore client...
if (curHit != m_ignoreClient)
{
//if valid
return ClosestRayResultCallback::AddSingleResult(rayResult);
// save shape information as ClosestRayResultCallback::AddSingleResult() does not do it
if (rayResult.m_localShapeInfo)
{
m_hitTriangleShape = rayResult.m_collisionObject->getCollisionShape();
m_hitTriangleIndex = rayResult.m_localShapeInfo->m_triangleIndex;
} else
{
m_hitTriangleShape = NULL;
m_hitTriangleIndex = 0;
}
return m_closestHitFraction;
return ClosestRayResultCallback::addSingleResult(rayResult,normalInWorldSpace);
}
};
PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)
{
@@ -751,19 +823,101 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
//Either Ray Cast with or without filtering
//btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
FilterClosestRayResultCallback rayCallback(ignoreClient,rayFrom,rayTo);
FilterClosestRayResultCallback rayCallback(filterCallback,rayFrom,rayTo);
PHY_IPhysicsController* nearestHit = 0;
PHY_RayCastResult result;
memset(&result, 0, sizeof(result));
// don't collision with sensor object
m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback, CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter);
if (rayCallback.HasHit())
{
nearestHit = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->getUserPointer());
hitX = rayCallback.m_hitPointWorld.getX();
hitY = rayCallback.m_hitPointWorld.getY();
hitZ = rayCallback.m_hitPointWorld.getZ();
rayCallback.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter;
//, ,filterCallback.m_faceNormal);
m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);
if (rayCallback.hasHit())
{
CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->getUserPointer());
result.m_controller = controller;
result.m_hitPoint[0] = rayCallback.m_hitPointWorld.getX();
result.m_hitPoint[1] = rayCallback.m_hitPointWorld.getY();
result.m_hitPoint[2] = rayCallback.m_hitPointWorld.getZ();
if (rayCallback.m_hitTriangleShape != NULL)
{
// identify the mesh polygon
CcdShapeConstructionInfo* shapeInfo = controller->m_shapeInfo;
if (shapeInfo)
{
btCollisionShape* shape = controller->GetCollisionObject()->getCollisionShape();
if (shape->isCompound())
{
btCompoundShape* compoundShape = (btCompoundShape*)shape;
CcdShapeConstructionInfo* compoundShapeInfo = shapeInfo;
// need to search which sub-shape has been hit
for (int i=0; i<compoundShape->getNumChildShapes(); i++)
{
shapeInfo = compoundShapeInfo->GetChildShape(i);
shape=compoundShape->getChildShape(i);
if (shape == rayCallback.m_hitTriangleShape)
break;
}
}
if (shape == rayCallback.m_hitTriangleShape &&
rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size())
{
result.m_meshObject = shapeInfo->m_meshObject;
result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex);
// Bullet returns the normal from "outside".
// If the user requests the real normal, compute it now
if (filterCallback.m_faceNormal)
{
// mesh shapes are shared and stored in the shapeInfo
btTriangleMeshShape* triangleShape = shapeInfo->GetMeshShape();
if (triangleShape)
{
// this code is copied from Bullet
btVector3 triangle[3];
const unsigned char *vertexbase;
int numverts;
PHY_ScalarType type;
int stride;
const unsigned char *indexbase;
int indexstride;
int numfaces;
PHY_ScalarType indicestype;
btStridingMeshInterface* meshInterface = triangleShape->getMeshInterface();
meshInterface->getLockedReadOnlyVertexIndexBase(
&vertexbase,
numverts,
type,
stride,
&indexbase,
indexstride,
numfaces,
indicestype,
0);
unsigned int* gfxbase = (unsigned int*)(indexbase+rayCallback.m_hitTriangleIndex*indexstride);
const btVector3& meshScaling = shape->getLocalScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
}
meshInterface->unLockReadOnlyVertexBase(0);
btVector3 triangleNormal;
triangleNormal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]);
rayCallback.m_hitNormalWorld = rayCallback.m_collisionObject->getWorldTransform().getBasis()*triangleNormal;
}
}
}
}
}
if (rayCallback.m_hitNormalWorld.length2() > (SIMD_EPSILON*SIMD_EPSILON))
{
rayCallback.m_hitNormalWorld.normalize();
@@ -771,14 +925,14 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
{
rayCallback.m_hitNormalWorld.setValue(1,0,0);
}
normalX = rayCallback.m_hitNormalWorld.getX();
normalY = rayCallback.m_hitNormalWorld.getY();
normalZ = rayCallback.m_hitNormalWorld.getZ();
result.m_hitNormal[0] = rayCallback.m_hitNormalWorld.getX();
result.m_hitNormal[1] = rayCallback.m_hitNormalWorld.getY();
result.m_hitNormal[2] = rayCallback.m_hitNormalWorld.getZ();
filterCallback.reportHit(&result);
}
return nearestHit;
return result.m_controller;
}
@@ -833,6 +987,12 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
if (NULL != m_filterCallback)
delete m_filterCallback;
if (NULL != m_collisionConfiguration)
delete m_collisionConfiguration;
if (NULL != m_broadphase)
delete m_broadphase;
}
@@ -845,7 +1005,7 @@ void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float
{
//param = 1..12, min0,max0,min1,max1...min6,max6
btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint;
genCons->SetLimit(param,value0,value1);
genCons->setLimit(param,value0,value1);
break;
};
default:
@@ -1191,10 +1351,11 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA;
frameInB = inv * globalFrameA;
bool useReferenceFrameA = true;
genericConstraint = new btGeneric6DofConstraint(
*rb0,*rb1,
frameInA,frameInB);
frameInA,frameInB,useReferenceFrameA);
} else
@@ -1215,9 +1376,10 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
///frameInB in worldspace
frameInB = rb0->getCenterOfMassTransform() * frameInA;
bool useReferenceFrameA = true;
genericConstraint = new btGeneric6DofConstraint(
*rb0,s_fixedObject2,
frameInA,frameInB);
frameInA,frameInB,useReferenceFrameA);
}
if (genericConstraint)