2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
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.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
1
16
#include "CcdPhysicsController.h"
3
18
#include "Dynamics/RigidBody.h"
4
19
#include "PHY_IMotionState.h"
5
20
#include "BroadphaseCollision/BroadphaseProxy.h"
21
#include "BroadphaseCollision/BroadphaseInterface.h"
6
22
#include "CollisionShapes/ConvexShape.h"
23
#include "CcdPhysicsEnvironment.h"
24
#include "SimdTransformUtil.h"
26
#include "CollisionShapes/SphereShape.h"
27
#include "CollisionShapes/ConeShape.h"
13
34
float gDeactivationTime = 2.f;
14
35
bool gDisableDeactivation = false;
16
float gLinearSleepingTreshold = 0.8f;
37
float gLinearSleepingTreshold = 0.4f;
17
38
float gAngularSleepingTreshold = 1.0f;
19
40
#include "Dynamics/MassProps.h"
21
42
SimdVector3 startVel(0,0,0);//-10000);
22
43
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
24
46
m_collisionDelay = 0;
25
47
m_newClientInfo = 0;
27
49
m_MotionState = ci.m_MotionState;
58
if (m_body->getInvMass())
59
m_body->setLinearVelocity(startVel);
64
SimdTransform CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState)
30
66
SimdTransform trans;
32
m_MotionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
68
motionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
33
69
trans.setOrigin(SimdVector3(tmp[0],tmp[1],tmp[2]));
35
71
SimdQuaternion orn;
36
m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
72
motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
37
73
trans.setRotation(orn);
39
MassProps mp(ci.m_mass, ci.m_localInertiaTensor);
41
m_body = new RigidBody(mp,0,0,ci.m_friction,ci.m_restitution);
43
m_body->SetCollisionShape( ci.m_collisionShape);
78
void CcdPhysicsController::CreateRigidbody()
81
SimdTransform trans = GetTransformFromMotionState(m_cci.m_MotionState);
83
MassProps mp(m_cci.m_mass, m_cci.m_localInertiaTensor);
85
m_body = new RigidBody(mp,0,0,m_cci.m_friction,m_cci.m_restitution);
86
m_body->m_collisionShape = m_cci.m_collisionShape;
46
m_broadphaseHandle = ci.m_broadphaseHandle;
50
90
// init the rigidbody properly
53
m_body->setMassProps(ci.m_mass, ci.m_localInertiaTensor);
54
m_body->setGravity( ci.m_gravity);
93
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
94
//setMassProps this also sets collisionFlags
95
m_body->m_collisionFlags = m_cci.m_collisionFlags;
57
m_body->setDamping(ci.m_linearDamping, ci.m_angularDamping);
97
m_body->setGravity( m_cci.m_gravity);
98
m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
60
99
m_body->setCenterOfMassTransform( trans );
63
if (m_body->getInvMass())
64
m_body->setLinearVelocity(startVel);
69
104
CcdPhysicsController::~CcdPhysicsController()
71
106
//will be reference counted, due to sharing
107
m_cci.m_physicsEnv->removeCcdPhysicsController(this);
72
108
delete m_MotionState;
79
115
bool CcdPhysicsController::SynchronizeMotionStates(float time)
81
const SimdVector3& worldPos = m_body->getCenterOfMassPosition();
82
m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
84
const SimdQuaternion& worldquat = m_body->getOrientation();
85
m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
87
m_MotionState->calculateWorldTransformations();
90
m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
92
SimdVector3 scaling(scale[0],scale[1],scale[2]);
93
m_body->GetCollisionShape()->setLocalScaling(scaling);
117
//sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.)
119
if (!m_body->IsStatic())
121
const SimdVector3& worldPos = m_body->getCenterOfMassPosition();
122
m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
124
const SimdQuaternion& worldquat = m_body->getOrientation();
125
m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
127
m_MotionState->calculateWorldTransformations();
130
m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
131
SimdVector3 scaling(scale[0],scale[1],scale[2]);
132
GetCollisionShape()->setLocalScaling(scaling);
135
SimdVector3 worldPos;
136
SimdQuaternion worldquat;
138
m_MotionState->getWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
139
m_MotionState->getWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
140
SimdTransform oldTrans = m_body->getCenterOfMassTransform();
141
SimdTransform newTrans(worldquat,worldPos);
143
m_body->setCenterOfMassTransform(newTrans);
144
//need to keep track of previous position for friction effects...
146
m_MotionState->calculateWorldTransformations();
149
m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
150
SimdVector3 scaling(scale[0],scale[1],scale[2]);
151
GetCollisionShape()->setLocalScaling(scaling);
98
CollisionShape* CcdPhysicsController::GetCollisionShape()
100
return m_body->GetCollisionShape();
106
158
WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding')
116
168
// controller replication
117
169
void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
171
m_MotionState = motionstate;
178
m_cci.m_physicsEnv->addCcdPhysicsController(this);
181
/* SM_Object* dynaparent=0;
182
SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
186
dynaparent = sumoparentctrl->GetSumoObject();
189
SM_Object* orgsumoobject = m_sumoObj;
192
m_sumoObj = new SM_Object(
193
orgsumoobject->getShapeHandle(),
194
orgsumoobject->getMaterialProps(),
195
orgsumoobject->getShapeProps(),
198
m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
200
m_sumoObj->setMargin(orgsumoobject->getMargin());
201
m_sumoObj->setPosition(orgsumoobject->getPosition());
202
m_sumoObj->setOrientation(orgsumoobject->getOrientation());
203
//if it is a dyna, register for a callback
204
m_sumoObj->registerCallback(*this);
206
m_sumoScene->add(* (m_sumoObj));
213
void CcdPhysicsController::SetMargin(float margin)
215
if (m_body && m_body->GetCollisionShape())
217
m_body->GetCollisionShape()->SetMargin(margin);
223
float CcdPhysicsController::GetMargin() const
225
if (m_body && m_body->GetCollisionShape())
227
return m_body->GetCollisionShape()->GetMargin();
121
235
// kinematic methods
122
236
void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)
124
SimdTransform xform = m_body->getCenterOfMassTransform();
125
xform.setOrigin(xform.getOrigin() + SimdVector3(dlocX,dlocY,dlocZ));
126
this->m_body->setCenterOfMassTransform(xform);
242
SimdVector3 dloc(dlocX,dlocY,dlocZ);
243
SimdTransform xform = m_body->getCenterOfMassTransform();
247
dloc = xform.getBasis()*dloc;
250
xform.setOrigin(xform.getOrigin() + dloc);
251
m_body->setCenterOfMassTransform(xform);
187
319
void CcdPhysicsController::getPosition(PHY__Vector3& pos) const
321
const SimdTransform& xform = m_body->getCenterOfMassTransform();
322
pos[0] = xform.getOrigin().x();
323
pos[1] = xform.getOrigin().y();
324
pos[2] = xform.getOrigin().z();
192
327
void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
329
if (!SimdFuzzyZero(m_cci.m_scaling.x()-scaleX) ||
330
!SimdFuzzyZero(m_cci.m_scaling.y()-scaleY) ||
331
!SimdFuzzyZero(m_cci.m_scaling.z()-scaleZ))
333
m_cci.m_scaling = SimdVector3(scaleX,scaleY,scaleZ);
335
if (m_body && m_body->GetCollisionShape())
337
m_body->GetCollisionShape()->setLocalScaling(m_cci.m_scaling);
338
m_body->GetCollisionShape()->CalculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
339
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
196
344
// physics methods
197
345
void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)
347
SimdVector3 torque(torqueX,torqueY,torqueZ);
348
SimdTransform xform = m_body->getCenterOfMassTransform();
351
torque = xform.getBasis()*torque;
353
m_body->applyTorque(torque);
200
356
void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local)
358
SimdVector3 force(forceX,forceY,forceZ);
359
SimdTransform xform = m_body->getCenterOfMassTransform();
362
force = xform.getBasis()*force;
364
m_body->applyCentralForce(force);
203
366
void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)
205
368
SimdVector3 angvel(ang_velX,ang_velY,ang_velZ);
207
m_body->setAngularVelocity(angvel);
369
if (angvel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
375
SimdTransform xform = m_body->getCenterOfMassTransform();
378
angvel = xform.getBasis()*angvel;
381
m_body->setAngularVelocity(angvel);
210
385
void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)
213
388
SimdVector3 linVel(lin_velX,lin_velY,lin_velZ);
214
m_body->setLinearVelocity(linVel);
389
if (linVel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
395
SimdTransform xform = m_body->getCenterOfMassTransform();
398
linVel = xform.getBasis()*linVel;
400
m_body->setLinearVelocity(linVel);
216
403
void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
219
405
SimdVector3 impulse(impulseX,impulseY,impulseZ);
220
SimdVector3 pos(attachX,attachY,attachZ);
224
m_body->applyImpulse(impulse,pos);
407
if (impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON))
411
SimdVector3 pos(attachX,attachY,attachZ);
415
m_body->applyImpulse(impulse,pos);
227
419
void CcdPhysicsController::SetActive(bool active)
230
422
// reading out information from physics
231
423
void CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ)
425
const SimdVector3& linvel = this->m_body->getLinearVelocity();
432
void CcdPhysicsController::GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ)
434
const SimdVector3& angvel= m_body->getAngularVelocity();
435
angVelX = angvel.x();
436
angVelY = angvel.y();
437
angVelZ = angvel.z();
234
440
void CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)
442
SimdVector3 pos(posX,posY,posZ);
443
SimdVector3 rel_pos = pos-m_body->getCenterOfMassPosition();
444
SimdVector3 linvel = m_body->getVelocityInLocalPoint(rel_pos);
237
449
void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ)
514
PHY_IPhysicsController* CcdPhysicsController::GetReplica()
516
//very experimental, shape sharing is not implemented yet.
517
//just support SphereShape/ConeShape for now
519
CcdConstructionInfo cinfo = m_cci;
520
if (cinfo.m_collisionShape)
522
switch (cinfo.m_collisionShape->GetShapeType())
524
case SPHERE_SHAPE_PROXYTYPE:
526
SphereShape* orgShape = (SphereShape*)cinfo.m_collisionShape;
527
cinfo.m_collisionShape = new SphereShape(*orgShape);
531
case CONE_SHAPE_PROXYTYPE:
533
ConeShape* orgShape = (ConeShape*)cinfo.m_collisionShape;
534
cinfo.m_collisionShape = new ConeShape(*orgShape);
546
cinfo.m_MotionState = new DefaultMotionState();
548
CcdPhysicsController* replica = new CcdPhysicsController(cinfo);
552
///////////////////////////////////////////////////////////
553
///A small utility class, DefaultMotionState
555
///////////////////////////////////////////////////////////
557
DefaultMotionState::DefaultMotionState()
559
m_worldTransform.setIdentity();
563
DefaultMotionState::~DefaultMotionState()
568
void DefaultMotionState::getWorldPosition(float& posX,float& posY,float& posZ)
570
posX = m_worldTransform.getOrigin().x();
571
posY = m_worldTransform.getOrigin().y();
572
posZ = m_worldTransform.getOrigin().z();
575
void DefaultMotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
582
void DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)
584
quatIma0 = m_worldTransform.getRotation().x();
585
quatIma1 = m_worldTransform.getRotation().y();
586
quatIma2 = m_worldTransform.getRotation().z();
587
quatReal = m_worldTransform.getRotation()[3];
590
void DefaultMotionState::setWorldPosition(float posX,float posY,float posZ)
592
SimdPoint3 pos(posX,posY,posZ);
593
m_worldTransform.setOrigin( pos );
596
void DefaultMotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
598
SimdQuaternion orn(quatIma0,quatIma1,quatIma2,quatReal);
599
m_worldTransform.setRotation( orn );
602
void DefaultMotionState::calculateWorldTransformations()