- Added support for kinematic objects (interaction between rigidbodies), deriving linear/angular velocity from previous transform/current transform and deltatime.

- Made another attempt to migrate from Sumo to Bullet: import of older files automatically switch to Bullet, but you can override it, and save the file in 2.42 version. then it stays Sumo physics.
This commit is contained in:
Erwin Coumans 2006-05-11 00:13:42 +00:00
parent 2358e85b6d
commit 93c47e1071
16 changed files with 150 additions and 31 deletions

@ -194,7 +194,9 @@ void SimpleBroadphase::AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProx
if (m_NumOverlapBroadphasePair >= m_maxOverlap)
{
//printf("Error: too many overlapping objects: m_NumOverlapBroadphasePair: %d\n",m_NumOverlapBroadphasePair);
#ifdef DEBUG
assert(0);
#endif
} else
{
m_NumOverlapBroadphasePair++;

@ -31,8 +31,9 @@ struct CollisionObject
{
SimdTransform m_worldTransform;
//m_nextPredictedWorldTransform is used for CCD and interpolation
SimdTransform m_nextPredictedWorldTransform;
//m_interpolationWorldTransform is used for CCD and interpolation
//it can be either previous or future (predicted) transform
SimdTransform m_interpolationWorldTransform;
enum CollisionFlags
{
@ -57,7 +58,7 @@ struct CollisionObject
bool mergesSimulationIslands() const;
inline bool IsStatic() {
inline bool IsStatic() const {
return m_collisionFlags & isStatic;
}

@ -184,7 +184,7 @@ float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,B
const SimdVector3& from = convexbody->m_worldTransform.getOrigin();
SimdVector3 to = convexbody->m_nextPredictedWorldTransform.getOrigin();
SimdVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
//todo: only do if the motion exceeds the 'radius'
struct LocalTriangleRaycastCallback : public TriangleRaycastCallback

@ -374,8 +374,8 @@ float ConvexConvexAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,Broad
if (disableCcd)
return 1.f;
if (ccd1.calcTimeOfImpact(col0->m_worldTransform,col0->m_nextPredictedWorldTransform,
col1->m_worldTransform,col1->m_nextPredictedWorldTransform,result))
if (ccd1.calcTimeOfImpact(col0->m_worldTransform,col0->m_interpolationWorldTransform,
col1->m_worldTransform,col1->m_interpolationWorldTransform,result))
{
//store result.m_fraction in both bodies

@ -33,7 +33,8 @@ RigidBody::RigidBody( const MassProps& massProps,SimdScalar linearDamping,SimdSc
m_linearDamping(0.f),
m_angularDamping(0.5f),
m_friction(friction),
m_restitution(restitution)
m_restitution(restitution),
m_kinematicTimeStep(0.f)
{
m_debugBodyId = uniqueId++;
@ -57,6 +58,21 @@ void RigidBody::predictIntegratedTransform(SimdScalar timeStep,SimdTransform& pr
SimdTransformUtil::IntegrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform);
}
void RigidBody::saveKinematicState(SimdScalar timeStep)
{
if (m_kinematicTimeStep)
{
SimdVector3 linVel,angVel;
SimdTransformUtil::CalculateVelocity(m_interpolationWorldTransform,m_worldTransform,m_kinematicTimeStep,m_linearVelocity,m_angularVelocity);
//printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ());
}
m_interpolationWorldTransform = m_worldTransform;
m_kinematicTimeStep = timeStep;
}
void RigidBody::getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const
{
@ -65,6 +81,7 @@ void RigidBody::getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const
void RigidBody::setGravity(const SimdVector3& acceleration)
{
if (m_inverseMass != 0.0f)
@ -91,6 +108,9 @@ void RigidBody::setDamping(SimdScalar lin_damping, SimdScalar ang_damping)
void RigidBody::applyForces(SimdScalar step)
{
if (IsStatic())
return;
applyCentralForce(m_gravity);
@ -165,6 +185,9 @@ void RigidBody::updateInertiaTensor()
void RigidBody::integrateVelocities(SimdScalar step)
{
if (IsStatic())
return;
m_linearVelocity += m_totalForce * (m_inverseMass * step);
m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step;

@ -48,6 +48,9 @@ public:
/// continuous collision detection needs prediction
void predictIntegratedTransform(SimdScalar step, SimdTransform& predictedTransform) const;
void saveKinematicState(SimdScalar step);
void applyForces(SimdScalar step);
void setGravity(const SimdVector3& acceleration);
@ -65,7 +68,9 @@ public:
void setMassProps(SimdScalar mass, const SimdVector3& inertia);
SimdScalar getInvMass() const { return m_inverseMass; }
const SimdMatrix3x3& getInvInertiaTensorWorld() const { return m_invInertiaTensorWorld; }
const SimdMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
}
void integrateVelocities(SimdScalar step);
@ -104,7 +109,8 @@ public:
void applyTorqueImpulse(const SimdVector3& torque)
{
m_angularVelocity += m_invInertiaTensorWorld * torque;
if (!IsStatic())
m_angularVelocity += m_invInertiaTensorWorld * torque;
}
@ -125,20 +131,37 @@ public:
void updateInertiaTensor();
const SimdPoint3& getCenterOfMassPosition() const { return m_worldTransform.getOrigin(); }
const SimdPoint3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
}
SimdQuaternion getOrientation() const;
const SimdTransform& getCenterOfMassTransform() const { return m_worldTransform; }
const SimdVector3& getLinearVelocity() const { return m_linearVelocity; }
const SimdVector3& getAngularVelocity() const { return m_angularVelocity; }
const SimdTransform& getCenterOfMassTransform() const {
return m_worldTransform;
}
const SimdVector3& getLinearVelocity() const {
return m_linearVelocity;
}
const SimdVector3& getAngularVelocity() const {
return m_angularVelocity;
}
void setLinearVelocity(const SimdVector3& lin_vel);
void setAngularVelocity(const SimdVector3& ang_vel) { m_angularVelocity = ang_vel; }
void setAngularVelocity(const SimdVector3& ang_vel) {
if (!IsStatic())
{
m_angularVelocity = ang_vel;
}
}
SimdVector3 getVelocityInLocalPoint(const SimdVector3& rel_pos) const
{
//we also calculate lin/ang velocity for kinematic objects
return m_linearVelocity + m_angularVelocity.cross(rel_pos);
//for kinematic objects, we could also use use:
// return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
}
void translate(const SimdVector3& v)
@ -208,9 +231,13 @@ private:
SimdScalar m_friction;
SimdScalar m_restitution;
SimdScalar m_kinematicTimeStep;
BroadphaseProxy* m_broadphaseProxy;
public:

@ -31,7 +31,7 @@ class BP_Proxy;
float gDeactivationTime = 2.f;
bool gDisableDeactivation = false;
float gLinearSleepingTreshold = 0.8f;
float gLinearSleepingTreshold = 0.4f;
float gAngularSleepingTreshold = 1.0f;
#include "Dynamics/MassProps.h"
@ -136,7 +136,7 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
m_MotionState->getWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
SimdTransform oldTrans = m_body->getCenterOfMassTransform();
SimdTransform newTrans(worldquat,worldPos);
m_body->setCenterOfMassTransform(newTrans);
//need to keep track of previous position for friction effects...

@ -171,6 +171,17 @@ class CcdPhysicsController : public PHY_IPhysicsController
void SetAabb(const SimdVector3& aabbMin,const SimdVector3& aabbMax);
class PHY_IMotionState* GetMotionState()
{
return m_MotionState;
}
const class PHY_IMotionState* GetMotionState() const
{
return m_MotionState;
}
};
#endif //BULLET2_PHYSICSCONTROLLER_H

@ -586,6 +586,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
m_scalingPropagated = true;
}
#ifdef USE_QUICKPROF
Profiler::endBlock("SyncMotionStates");
@ -605,9 +606,12 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
RigidBody* body = ctrl->GetRigidBody();
if (body->GetActivationState() != ISLAND_SLEEPING)
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_nextPredictedWorldTransform);
if (!body->IsStatic())
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
}
}
}
@ -807,8 +811,15 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
if (body->GetActivationState() != ISLAND_SLEEPING)
{
body->predictIntegratedTransform(timeStep* toi, predictedTrans);
body->proceedToTransform( predictedTrans);
if (body->IsStatic())
{
//to calculate velocities next frame
body->saveKinematicState(timeStep);
} else
{
body->predictIntegratedTransform(timeStep* toi, predictedTrans);
body->proceedToTransform( predictedTrans);
}
}
}
@ -893,6 +904,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
}
#endif //NEW_BULLET_VEHICLE_SUPPORT
}
return true;
}

@ -119,7 +119,7 @@ public:
axis[3] = 0.f;
//check for axis length
SimdScalar len = axis.length2();
if (len < 0.001f)
if (len < SIMD_EPSILON*SIMD_EPSILON)
axis = SimdVector3(1.f,0.f,0.f);
else
axis /= SimdSqrt(len);

@ -4440,14 +4440,30 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
if(main->versionfile <= 225) {
World *wo;
/* Use Sumo for old games */
for (wo = main->world.first; wo; wo= wo->id.next) {
wo->physicsEngine = 2;
}
} else
{
if(main->versionfile <= 241) {
World *wo;
/* Migrate to Bullet for recent games */
/* People can still explicitely choose for Sumo */
for (wo = main->world.first; wo; wo= wo->id.next) {
wo->physicsEngine = 5;
}
}
}
if(main->versionfile <= 227) {
Scene *sce;
Material *ma;
@ -4891,6 +4907,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
if(main->versionfile <= 234) {
Scene *sce;
World *wo;

@ -1742,7 +1742,7 @@ static void world_panel_mistaph(World *wrld)
"Physics %t|None %x0|Sumo %x2|Ode %x4 |Bullet %x5",
#else
//"Physics %t|None %x0|Sumo %x2|Bullet %x5", //disable Sumo, until too many people complain ;-)
"Physics %t|None %x0|Bullet %x2|Bullet %x5",
"Physics %t|None %x0|Sumo (deprecated) %x2|Bullet %x5",
#endif
10,180,140,19, &wrld->physicsEngine, 0, 0, 0, 0,
"Physics Engine");

@ -281,7 +281,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
}
case WOPHY_SUMO:
{
physics_engine = UseBullet;//UseSumo; //disable Sumo, just use Bullet for now (unless too many people complain)
physics_engine = UseSumo;
break;
}
case WOPHY_NONE:

@ -31,7 +31,7 @@ class BP_Proxy;
float gDeactivationTime = 2.f;
bool gDisableDeactivation = false;
float gLinearSleepingTreshold = 0.8f;
float gLinearSleepingTreshold = 0.4f;
float gAngularSleepingTreshold = 1.0f;
#include "Dynamics/MassProps.h"
@ -136,7 +136,7 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
m_MotionState->getWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
SimdTransform oldTrans = m_body->getCenterOfMassTransform();
SimdTransform newTrans(worldquat,worldPos);
m_body->setCenterOfMassTransform(newTrans);
//need to keep track of previous position for friction effects...

@ -171,6 +171,17 @@ class CcdPhysicsController : public PHY_IPhysicsController
void SetAabb(const SimdVector3& aabbMin,const SimdVector3& aabbMax);
class PHY_IMotionState* GetMotionState()
{
return m_MotionState;
}
const class PHY_IMotionState* GetMotionState() const
{
return m_MotionState;
}
};
#endif //BULLET2_PHYSICSCONTROLLER_H

@ -586,6 +586,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
m_scalingPropagated = true;
}
#ifdef USE_QUICKPROF
Profiler::endBlock("SyncMotionStates");
@ -605,9 +606,12 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
RigidBody* body = ctrl->GetRigidBody();
if (body->GetActivationState() != ISLAND_SLEEPING)
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_nextPredictedWorldTransform);
if (!body->IsStatic())
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
}
}
}
@ -807,8 +811,15 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
if (body->GetActivationState() != ISLAND_SLEEPING)
{
body->predictIntegratedTransform(timeStep* toi, predictedTrans);
body->proceedToTransform( predictedTrans);
if (body->IsStatic())
{
//to calculate velocities next frame
body->saveKinematicState(timeStep);
} else
{
body->predictIntegratedTransform(timeStep* toi, predictedTrans);
body->proceedToTransform( predictedTrans);
}
}
}
@ -893,6 +904,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
}
#endif //NEW_BULLET_VEHICLE_SUPPORT
}
return true;
}