AnimatLab  2
Test
BlRigidBody.cpp
1 // BlRigidBody.cpp: implementation of the BlRigidBody class.
2 //
4 
5 #include "StdAfx.h"
6 #include "BlJoint.h"
7 #include "BlRigidBody.h"
8 #include "BlSimulator.h"
9 
10 namespace BulletAnimatSim
11 {
12  namespace Environment
13  {
14 
16 // Construction/Destruction
18 
19 BlRigidBody::BlRigidBody()
20 {
21  m_btCompoundShape = NULL;
22  m_btCollisionShape = NULL;
23  m_btCollisionObject = NULL;
24  m_btPart = NULL;
25  m_osgbMotion = NULL;
26  m_lpBulletData = NULL;
27  m_fltStaticMasses = 0;
28  m_eBodyType = BOX_SHAPE_PROXYTYPE;
29 
30  m_fltBuoyancy = 0;
32 
33  for(int iIdx=0; iIdx<3; iIdx++)
34  {
35  m_vLinearDragForce[iIdx] = 0;
36  m_vAngularDragTorque[iIdx] = 0;
37  }
38 
39  m_lpMaterial = NULL;
40  m_lpVsSim = NULL;
41 
42  m_btStickyLock = NULL;
43  m_btStickyLock2 = NULL;
44 }
45 
46 BlRigidBody::~BlRigidBody()
47 {
48 
49 try
50 {
51  m_aryContactPoints.Clear();
52  //Cleanup of all BlRigidBody objects is taken care of in the DeletePhysics call
53 }
54 catch(...)
55 {Std_TraceMsg(0, "Caught Error in desctructor of BlRigidBody\r\n", "", -1, false, true);}
56 }
57 
58 bool BlRigidBody::Physics_IsDefined()
59 {
60  if(m_btPart && m_btCollisionShape)
61  return true;
62  else
63  return false;
64 }
65 
66 bool BlRigidBody::Physics_IsGeometryDefined()
67 {
68  if(m_btCollisionShape)
69  return true;
70  else
71  return false;
72 }
73 
74 CStdFPoint BlRigidBody::Physics_GetCurrentPosition()
75 {
76  if(m_osgbMotion && m_lpThisMI)
77  {
78  m_osgWorldMatrix = m_osgMT->getMatrix();
79 
80  //Then update the absolute position and rotation.
81  osg::Vec3d vPos = m_osgWorldMatrix.getTrans();
82  m_lpThisMI->AbsolutePosition(vPos[0], vPos[1], vPos[2]);
83  return m_lpThisMI->AbsolutePosition();
84  }
85  else
86  {
87  CStdFPoint vPos;
88  return vPos;
89  }
90 }
91 
92 osg::Matrix BlRigidBody::GetPhysicsWorldMatrix()
93 {
94  if(m_osgbMotion)
95  {
96  btTransform trans;
97  m_osgbMotion->getWorldTransform(trans);
98  osg::Matrix osgMT = osgbCollision::asOsgMatrix(trans);
99  return osgMT;
100  }
101  else
102  {
103  osg::Matrix osgMatrix;
104  osgMatrix.makeIdentity();
105  return osgMatrix;
106  }
107 }
108 
109 BlSimulator *BlRigidBody::GetBlSimulator()
110 {
111  if(!m_lpVsSim)
112  {
113  m_lpVsSim = dynamic_cast<BlSimulator *>(m_lpThisAB->GetSimulator());
114  if(!m_lpThisVsMI)
115  THROW_TEXT_ERROR(Osg_Err_lThisPointerNotDefined, Osg_Err_strThisPointerNotDefined, "m_lpVsSim, " + m_lpThisAB->Name());
116  }
117  return m_lpVsSim;
118 }
119 
120 void BlRigidBody::Physics_UpdateNode()
121 {
123  //int i=5;
124  //if(Std_ToLower(m_lpThisAB->ID()) == "b42f968f-0639-4a69-9974-9e0f411d40d8") // && m_lpSim->Time() > 1.8
125  // i=6;
126 
127  OsgBody::UpdatePositionAndRotationFromMatrix();
128 
129  if(m_lpThisRB)
130  {
131  if(m_lpThisRB->IsContactSensor())
132  ResetSensorCollisionGeom();
133  else if(m_lpThisRB->HasStaticJoint())
134  ResetStaticCollisionGeom(); //If this body uses a static joint then we need to reset the offest matrix for its collision geometry.
135  else if(m_btPart)
136  ResetDynamicCollisionGeom();
137  }
138 }
139 
140 void BlRigidBody::Physics_SetFreeze(bool bVal)
141 {
142  ResizePhysicsGeometry();
143 }
144 
145 void BlRigidBody::Physics_SetMass(float fltVal)
146 {
147  ResizePhysicsGeometry();
148 }
149 
150 float BlRigidBody::Physics_GetMass()
151 {
152  if(m_lpThisRB)
153  return m_lpThisRB->Mass();
154 
155  return 0;
156 }
157 
158 float BlRigidBody::Physics_GetDensity()
159 {
160  if(m_lpThisRB)
161  {
162  float fltVolume = m_lpThisRB->Volume();
163  if(fltVolume > 0)
164  return m_lpThisRB->Mass()/fltVolume;
165  }
166 
167  return 0;
168 }
169 
170 void BlRigidBody::Physics_SetMaterialID(std::string strID)
171 {
172  //First remove this rigid body from any previously associated material.
173  if(m_lpMaterial)
174  {
176  m_lpMaterial = NULL;
177  }
178 
179  m_lpMaterial = dynamic_cast<BlMaterialType *>(m_lpThisAB->GetSimulator()->FindByID(strID));
180 
181  if(!m_lpMaterial)
182  THROW_PARAM_ERROR(Bl_Err_lConvertingMaterialType, Bl_Err_strConvertingMaterialType, "ID", strID);
183 
185 
186  MaterialTypeModified();
187 }
188 
189 void BlRigidBody::MaterialTypeModified()
190 {
191  if(m_btPart && m_lpMaterial)
192  {
193  m_btPart->setFriction(m_lpMaterial->FrictionLinearPrimary());
194  m_btPart->setRollingFriction(m_lpMaterial->FrictionAngularPrimaryConverted());
195  m_btPart->setRestitution(m_lpMaterial->Restitution());
196  }
197 }
198 
199 void BlRigidBody::Physics_SetVelocityDamping(float fltLinear, float fltAngular)
200 {
201  if(m_btPart && fltLinear > 0 && fltAngular > 0)
202  m_btPart->setDamping(fltLinear, fltAngular);
203 }
204 
205 void BlRigidBody::Physics_SetCenterOfMass(float fltTx, float fltTy, float fltTz)
206 {
207  ResetPhyiscsAndChildJoints();
208 }
209 
210 void BlRigidBody::Physics_FluidDataChanged()
211 {
212 }
213 
214 void BlRigidBody::Physics_WakeDynamics()
215 {
216  if(m_btPart)
217  {
218  int istate = m_btPart->getActivationState();
219 
220  if(m_lpThisRB->Freeze())
221  m_btPart->setActivationState(0);
222  else if(!m_btPart->isActive())
223  m_btPart->activate(true);
224  }
225 }
226 
227 void BlRigidBody::GetBaseValues()
228 {
229  if(m_lpThisRB)
230  {
231  //Recalculate the mass and volume
232  m_lpThisRB->GetDensity();
233  m_lpThisRB->GetVolume();
234  }
235 }
236 
237 void BlRigidBody::CreateSensorPart()
238 {
239  BlSimulator *lpSim = GetBlSimulator();
240 
241  if(m_lpThisRB && m_lpThisAB && m_btCollisionShape)
242  {
243  BlRigidBody *lpVsParent = dynamic_cast<BlRigidBody *>(m_lpThisRB->Parent());
244 
245  m_btCollisionObject = new btCollisionObject;
246  m_btCollisionObject->setCollisionShape( m_btCollisionShape );
247  m_btCollisionObject->setCollisionFlags( btCollisionObject::CF_KINEMATIC_OBJECT );
248  m_btCollisionObject->setWorldTransform( osgbCollision::asBtTransform( GetOSGWorldMatrix() ) );
249 
250  if(!m_lpBulletData)
251  m_lpBulletData = new BlBulletData(this, false);
252 
253  m_btCollisionObject->setUserPointer((void *) m_lpBulletData);
254 
255  lpSim->DynamicsWorld()->addCollisionObject( m_btCollisionObject, AnimatCollisionTypes::CONTACT_SENSOR, ALL_COLLISIONS );
256 
257  int iFlags = m_btCollisionObject->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK | btCollisionObject::CF_NO_CONTACT_RESPONSE;
258  m_btCollisionObject->setCollisionFlags(iFlags);
259 
260  //Disable collisions between this sensor part and its parent manually. For some reason this is not
261  //done automatically by bullet like it is for two dynamic parts.
262  m_lpThisRB->DisableCollision(m_lpThisRB->Parent());
263  }
264 }
265 
266 void BlRigidBody::CreateDynamicPart()
267 {
268  if(m_lpThisRB && m_lpThisAB && m_btCollisionShape && m_lpMaterial)
269  {
270  BlSimulator *lpSim = GetBlSimulator();
271 
272  float fltMass = 0;
273  CStdFPoint vCom = m_lpThisRB->CenterOfMassWithStaticChildren();
274 
276  // if(Std_ToLower(m_lpThisRB->ID()) == "b42f968f-0639-4a69-9974-9e0f411d40d8")
277  // fltMass = 0;
278 
279  if(m_lpThisRB->HasStaticChildren())
280  CreateStaticChildren(vCom);
281  else if(vCom != CStdFPoint(0, 0, 0))
282  SetupOffsetCOM(vCom);
283 
284  osg::ref_ptr< osgbDynamics::CreationRecord > cr = new osgbDynamics::CreationRecord;
285 
286  //We should always set the COM even if it is zero. This is to prevent the OsgBullet code from trying to approximate it using bounding boxes.
287  //I want the COM to be where I say it is.
288  cr->setCenterOfMass(osg::Vec3(vCom.x, vCom.y, vCom.z) );
289  cr->_sceneGraph = m_osgMT.get();
290  cr->_shapeType = m_eBodyType;
291  cr->_parentTransform = m_osgMT->getMatrix();
292 
293  if(!m_lpThisRB->Freeze())
294  cr->_mass = m_lpThisRB->GetMassValueWithStaticChildren();
295  else
296  cr->_mass = 0;
297 
298  cr->_friction = m_lpMaterial->FrictionLinearPrimary();
299  cr->_rollingFriction = m_lpMaterial->FrictionAngularPrimaryConverted();
300  cr->_restitution = m_lpMaterial->Restitution();
301  cr->_linearDamping = m_lpThisRB->LinearVelocityDamping();
302  cr->_angularDamping = m_lpThisRB->AngularVelocityDamping();
303 
304  m_osgMT->setMatrix(osg::Matrix::identity());
305 
306  m_btPart = osgbDynamics::createRigidBody( cr.get(), m_btCollisionShape );
307 
309  m_btPart->setAnisotropicFriction(m_btCollisionShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
310 
311  m_btPart->setLinearVelocity( btVector3( 0., 0, 0. ) );
312  m_btPart->setAngularVelocity( btVector3( 0., 0, 0. ) );
313 
314  m_osgbMotion = dynamic_cast<osgbDynamics::MotionState *>(m_btPart->getMotionState());
315  m_btCollisionShape = m_btPart->getCollisionShape();
316 
317  if(!m_lpBulletData)
318  m_lpBulletData = new BlBulletData(this, false);
319 
320  m_btPart->setUserPointer((void *) m_lpBulletData);
321 
322  //if this body is frozen; freeze it
323  Physics_WakeDynamics();
324 
325  //If this part has a receptive field then turn on the custom callbacks.
326  if(m_lpThisRB->GetContactSensor())
327  {
328  int iFlags = m_btPart->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK;
329  m_btPart->setCollisionFlags(iFlags);
330  }
331 
332  lpSim->DynamicsWorld()->addRigidBody( m_btPart, AnimatCollisionTypes::RIGID_BODY, ALL_COLLISIONS );
333 
334  if(m_lpThisRB->DisplayDebugCollisionGraphic())
335  {
336  m_osgDebugNode = osgbCollision::osgNodeFromBtCollisionShape( m_btCollisionShape );
337  m_osgDebugNode->setName(m_lpThisRB->Name() + "_Debug");
338  m_osgNodeGroup->addChild(m_osgDebugNode.get());
339  }
340 
341  GetBaseValues();
343  }
344 }
345 
359 void BlRigidBody::SetupOffsetCOM(const CStdFPoint &vCom)
360 {
361  //Swap the current collision shape into the compound collision shape so we can
362  //make the collision shape a compound shape.
363  btCollisionShape *btChildShape = m_btCollisionShape;
364  m_aryCompoundChildShapes.Add(m_btCollisionShape);
365 
366  //Now create the new compound shape
367  m_btCompoundShape = new btCompoundShape();
368 
369  //Set the collision shape to be the new compound.
370  m_btCollisionShape = m_btCompoundShape;
371 
372  //Now add the shape for this body to the compound shape
373  btTransform localTransform;
374  localTransform.setIdentity();
375  localTransform.setOrigin(btVector3(-vCom.x, -vCom.y, -vCom.z));
376  m_btCompoundShape->addChildShape(localTransform, btChildShape);
377 }
378 
379 void BlRigidBody::CreateStaticChildren(const CStdFPoint &vCom)
380 {
381  //Swap the current collision shape into the compound collision shape so we can
382  //make the collision shape a compound shape.
383  btCollisionShape *btChildShape = m_btCollisionShape;
384  m_aryCompoundChildShapes.Add(m_btCollisionShape);
385 
386  //Now create the new compound shape
387  m_btCompoundShape = new btCompoundShape();
388 
389  //Set the collision shape to be the new compound.
390  m_btCollisionShape = m_btCompoundShape;
391 
392  //Now add the shape for this body to the compound shape
393  btTransform localTransform;
394  localTransform.setIdentity();
395  localTransform.setOrigin(btVector3(-vCom.x, -vCom.y, -vCom.z));
396  m_btCompoundShape->addChildShape(localTransform, btChildShape);
397 
398  //Then add all static child shapes
399  int iCount = m_lpThisRB->ChildParts()->GetSize();
400  for(int iIndex=0; iIndex<iCount; iIndex++)
401  {
402  RigidBody *lpChild = m_lpThisRB->ChildParts()->at(iIndex);
403  BlRigidBody *lpBlChild = dynamic_cast<BlRigidBody *>(lpChild);
404  if(lpChild->HasStaticJoint())
405  lpBlChild->AddStaticGeometry(this, m_btCompoundShape, vCom);
406  }
407 }
408 
409 void BlRigidBody::AddStaticGeometry(BlRigidBody *lpChild, btCompoundShape *btCompound, const CStdFPoint &vCom)
410 {
411  if(m_lpThisMI && lpChild && btCompound)
412  {
413  //First create the physics geometry for this part.
414  CreateGeometry(true);
415  //CreatePhysicsGeometry();
416 
417  CStdFPoint vPos = m_lpThisMI->Position() - vCom;
418  CStdFPoint vRot = m_lpThisMI->Rotation();
419  osg::Matrix mt = SetupMatrix(vPos, vRot);
420 
421  btTransform localTransform = osgbCollision::asBtTransform(mt);
422  btCompound->addChildShape(localTransform, m_btCollisionShape);
423 
424  GetBaseValues();
425  }
426 }
427 
428 void BlRigidBody::RemoveStaticGeometry(BlRigidBody *lpChild, btCompoundShape *btCompound)
429 {
430  if(m_lpThisMI && lpChild && btCompound)
431  {
432  //First create the physics geometry for this part.
433  btCompound->removeChildShape(m_btCollisionShape);
434  DeleteCollisionGeometry();
435  }
436 }
437 
438 void BlRigidBody::ResetStaticCollisionGeom()
439 {
440 }
441 
442 void BlRigidBody::ResetSensorCollisionGeom()
443 {
444  if(m_osgMT.valid() && m_osgbMotion && m_btCollisionObject)
445  {
446  osg::Matrix osgMTmat = m_osgMT->getMatrix();
447  btTransform wt = osgbCollision::asBtTransform(osgMTmat);
448  m_osgbMotion->setWorldTransform( wt );
449  m_btCollisionObject->setWorldTransform( wt );
450  }
451 }
452 
453 void BlRigidBody::ResetDynamicCollisionGeom()
454 {
455  if(m_osgMT.valid() && m_osgbMotion && m_btPart)
456  {
457  //We must take into consideration the COM when resetting the world transform.
458  osg::Vec3d vCom = m_osgbMotion->getCenterOfMass();
459  osg::Matrixd osgMtCom = osg::Matrixd::translate(vCom);
460  osg::Matrixd osgMTBase = m_osgMT->getMatrix();
461  osg::Matrixd osgMTmat = osgMTBase * osgMtCom;
462 
463  btTransform wt = osgbCollision::asBtTransform(osgMTmat);
464  m_osgbMotion->setWorldTransform( wt );
465  m_btPart->setWorldTransform( wt );
466  }
467 }
468 
469 void BlRigidBody::DeleteDynamicPart()
470 {
471  if(m_btPart)
472  {
473  GetBlSimulator()->DynamicsWorld()->removeRigidBody(m_btPart);
474  delete m_btPart;
475  m_btPart = NULL;
476 
477  if(m_osgbMotion)
478  {delete m_osgbMotion; m_osgbMotion = NULL;}
479 
480  if(m_lpBulletData)
481  {delete m_lpBulletData; m_lpBulletData = NULL;}
482  }
483 }
484 
485 void BlRigidBody::DeleteSensorPart()
486 {
487  if(m_btCollisionObject)
488  {
489  GetBlSimulator()->DynamicsWorld()->removeCollisionObject(m_btCollisionObject);
490  delete m_btCollisionObject;
491  m_btCollisionObject = NULL;
492 
493  if(m_lpBulletData)
494  {delete m_lpBulletData; m_lpBulletData = NULL;}
495  }
496 }
497 
498 void BlRigidBody::DeleteCollisionGeometry()
499 {
500  //If we have a compound shape defined then collision shape = compound shape. So only delete once.
501  if(m_btCompoundShape)
502  {
503  int iCount = m_btCompoundShape->getNumChildShapes();
504  for(int iIdx=0; iIdx<iCount; iIdx++)
505  m_btCompoundShape->removeChildShapeByIndex(0);
506 
507  m_aryCompoundChildShapes.RemoveAll();
508 
509  delete m_btCompoundShape;
510  m_btCompoundShape = NULL;
511  m_btCollisionShape = NULL;
512  }
513  else if(m_btCollisionShape)
514  {delete m_btCollisionShape; m_btCollisionShape = NULL;}
515 }
516 
517 void BlRigidBody::DeletePhysics(bool bIncludeChildren)
518 {
519  if(m_btPart || m_btCollisionObject)
520  {
521  //First delete all physics associated with this part.
522  //We need to delete all the constrains attached to this part, and then the part itself.
523  DeleteAttachedJointPhysics();
524 
525  //Then delete this part
526  DeleteDynamicPart();
527  DeleteSensorPart();
528 
529  //Then delete collision geometry.
530  DeleteCollisionGeometry();
531 
532  if(bIncludeChildren)
533  DeleteChildPhysics();
534 
535  Physics_DeleteStickyLock();
536  }
537 }
538 
539 void BlRigidBody::DeleteChildPhysics()
540 {
541  int iCount = m_lpThisRB->ChildParts()->GetSize();
542  for(int iIdx=0; iIdx<iCount; iIdx++)
543  {
544  RigidBody *lpChild = m_lpThisRB->ChildParts()->at(iIdx);
545  if(lpChild)
546  {
547  OsgRigidBody *lpVsChild = dynamic_cast<OsgRigidBody *>(lpChild);
548  if(lpVsChild)
549  lpVsChild->DeletePhysics(true);
550  }
551  }
552 }
553 
554 void BlRigidBody::DeleteAttachedJointPhysics()
555 {
556  BlJoint *lpVsJoint = dynamic_cast<BlJoint *>(m_lpThisRB->JointToParent());
557 
558  if(lpVsJoint)
559  lpVsJoint->DeletePhysics(false);
560 
561  int iCount = m_lpThisRB->ChildParts()->GetSize();
562  for(int iIdx=0; iIdx<iCount; iIdx++)
563  {
564  RigidBody *lpChild = m_lpThisRB->ChildParts()->at(iIdx);
565  if(lpChild)
566  {
567  BlJoint *lpVsChildJoint = dynamic_cast<BlJoint *>(lpChild->JointToParent());
568  if(lpVsChildJoint)
569  lpVsChildJoint->DeletePhysics(false);
570  }
571  }
572 }
573 
574 void BlRigidBody::RecreateAttachedJointPhysics()
575 {
576  BlJoint *lpVsJoint = dynamic_cast<BlJoint *>(m_lpThisRB->JointToParent());
577 
578  if(lpVsJoint)
579  lpVsJoint->SetupPhysics();
580 
581  int iCount = m_lpThisRB->ChildParts()->GetSize();
582  for(int iIdx=0; iIdx<iCount; iIdx++)
583  {
584  RigidBody *lpChild = m_lpThisRB->ChildParts()->at(iIdx);
585  if(lpChild)
586  {
587  BlJoint *lpVsChildJoint = dynamic_cast<BlJoint *>(lpChild->JointToParent());
588  if(lpVsChildJoint)
589  lpVsChildJoint->SetupPhysics();
590  }
591  }
592 }
593 
594 void BlRigidBody::ResizePhysicsGeometry()
595 {
596  if(m_lpThisRB && m_lpThisRB->HasStaticJoint() && m_btCollisionShape)
597  {
598  //If this is a static part then we actually need to call the resize on the parent so it
599  //is all recalculated correctly.
600  // Only attempt to do this if a collision shape is already present for it to resize.
601  BlRigidBody *lpOsgParent = dynamic_cast<BlRigidBody *>(m_lpThisRB->Parent());
602  if(lpOsgParent)
603  lpOsgParent->ResizePhysicsGeometry();
604  }
605  else
606  {
607  //Then delete the physics for this part
608  DeletePhysics(false);
609 
610  //Now recreate the collision geometry for this part.
611  CreatePhysicsGeometry();
612 
613  //Now recreate the part itself.
614  SetupPhysics();
615 
616  //Then recreate all the attached joints.
617  RecreateAttachedJointPhysics();
618  }
619 }
620 
631 {
632  //Get the world matrix for this part and then reset its translation to 0 so we only have rotations.
633  osg::Matrix rotMT = GetWorldMatrix();
634  rotMT.setTrans(osg::Vec3d(0, 0, 0));
635 
636  osg::Vec4d vArea(m_vArea.x, m_vArea.y, m_vArea.z, 0);
637  osg::Vec4d vRotatedArea = rotMT * vArea;
638 
639  m_vRotatedArea.Set(fabs(vRotatedArea[0]), fabs(vRotatedArea[1]), fabs(vRotatedArea[2]));
640 }
641 
642 bool BlRigidBody::NeedCollision(BlRigidBody *lpTest)
643 {
644  //If we find this objects rigid body in the list of collision exclusions then we want to skip this collision.
645  if(m_lpThisRB->FindCollisionExclusionBody(lpTest->m_lpThisRB, false))
646  return false;
647  else
648  return true;
649 }
650 
651 void BlRigidBody::Physics_ContactSensorAdded(ContactSensor *lpSensor)
652 {
653  if(m_btPart)
654  {
655  int iFlags = m_btPart->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK;
656  m_btPart->setCollisionFlags(iFlags);
657  }
658 }
659 
660 void BlRigidBody::Physics_ContactSensorRemoved()
661 {
662  if(m_btPart)
663  {
664  int iFlags = m_btPart->getCollisionFlags() & ~btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK;
665  m_btPart->setCollisionFlags(iFlags);
666  }
667 }
668 
669 void BlRigidBody::Physics_ChildBodyAdded(RigidBody *lpChild)
670 {
671  if(lpChild && lpChild->HasStaticJoint())
672  ResizePhysicsGeometry();
673 }
674 
675 void BlRigidBody::Physics_ChildBodyRemoved(bool bHasStaticJoint)
676 {
677  if(bHasStaticJoint)
678  ResizePhysicsGeometry();
679 }
680 
681 btAnimatGeneric6DofConstraint *BlRigidBody::AddDynamicJoint(BlRigidBody *lpParent, BlRigidBody *lpChild)
682 {
683  osg::Matrix mtParent = lpParent->GetWorldMatrix();
684  osg::Matrix mtChild = lpChild->GetWorldMatrix();
685 
686  osg::Matrix mtChildRelToParent = mtChild * osg::Matrix::inverse(mtParent);
687 
688  btTransform mtJointRelToParent = osgbCollision::asBtTransform(mtChildRelToParent);
689  btTransform mtJointRelToChild = osgbCollision::asBtTransform(osg::Matrixd::identity());
690 
691  btAnimatGeneric6DofConstraint *btStickyLock = new btAnimatGeneric6DofConstraint(*lpParent->Part(), *lpChild->Part(), mtJointRelToParent, mtJointRelToChild, false);
692 
693  //Lock the linear and angular limits to prevent movement
694  btVector3 vLowerLimit, vUpperLimit;
695 
696  //enable translation limits
697  vLowerLimit[0] = vLowerLimit[1] = vLowerLimit[2] = 0;
698  vUpperLimit[0] = vUpperLimit[1] = vUpperLimit[2] = 0;
699 
700  btStickyLock->setLinearLowerLimit(vLowerLimit);
701  btStickyLock->setLinearUpperLimit(vUpperLimit);
702  btStickyLock->setAngularLowerLimit(vLowerLimit);
703  btStickyLock->setAngularUpperLimit(vUpperLimit);
704 
705  GetBlSimulator()->DynamicsWorld()->addConstraint(btStickyLock, true);
706 
707  return btStickyLock;
708 }
709 
710 void BlRigidBody::CreateStickyLock()
711 {
712  static bool bDisabledColls = false;
713  BlRigidBody *lpParent = dynamic_cast<BlRigidBody *>(m_lpThisRB->Parent());
714  BlRigidBody *lpChild = m_aryContactPoints[0]->m_lpContacted;
715 
716  if(lpChild && lpParent)
717  {
718  BlRigidBody *lpRightGrip = dynamic_cast<BlRigidBody *>(GetSimulator()->FindByID("ac233f7b-8f8f-4d03-9d4f-21e363a19bc2"));
719  BlRigidBody *lpLeftGrip = dynamic_cast<BlRigidBody *>(GetSimulator()->FindByID("35b1ffff-ebbc-4bdb-8108-5d44aea2a1c5"));
720 
721  m_btStickyLock = AddDynamicJoint(lpLeftGrip, lpChild);
722  //m_btStickyLock2 = AddDynamicJoint(lpRightGrip, lpChild);
723 
724  //lpRightGrip->Part()->addConstraintRef(m_btStickyLock);
725  //lpChild->Part()->addConstraintRef(m_btStickyLock);
726  //lpRightGrip->m_lpThisRB->DisableCollision(lpChild->m_lpThisRB);
727 
728  m_lpThisRB->StickyChild(lpChild->m_lpThisRB);
729 
730  //if(!bDisabledColls)
731  //{
732  // RigidBody *lpRightGrip = dynamic_cast<RigidBody *>(GetSimulator()->FindByID("ac233f7b-8f8f-4d03-9d4f-21e363a19bc2"));
733  // RigidBody *lpBlock1 = dynamic_cast<RigidBody *>(GetSimulator()->FindByID("110be62c-6c10-4a4e-aef7-983cd8fb457d"));
734  // RigidBody *lpBlock2 = dynamic_cast<RigidBody *>(GetSimulator()->FindByID("71fe27fb-121a-4007-aafa-2771ee816558"));
735  // RigidBody *lpBall = dynamic_cast<RigidBody *>(GetSimulator()->FindByID("5586751b-3da0-4956-ac1d-1b77b41442b1"));
736  // lpRightGrip->DisableCollision(lpBlock1);
737  // lpRightGrip->DisableCollision(lpBlock2);
738  // lpRightGrip->DisableCollision(lpBall);
739  // bDisabledColls = true;
740  //}
741  }
742 
743 }
744 
745 void BlRigidBody::Physics_DeleteStickyLock()
746 {
747  if(m_btStickyLock)
748  {
749  if(GetBlSimulator() && GetBlSimulator()->DynamicsWorld())
750  {
751  if(m_lpThisRB->StickyChild())
752  {
753  BlRigidBody *lpRightGrip = dynamic_cast<BlRigidBody *>(GetSimulator()->FindByID("ac233f7b-8f8f-4d03-9d4f-21e363a19bc2"));
754  //lpRightGrip->Part()->removeConstraintRef(m_btStickyLock);
755  //Part()->removeConstraintRef(m_btStickyLock);
756 
757  m_lpThisRB->StickyChild(NULL);
758 
759  /*lpRightGrip->m_lpThisRB->EnableCollision(m_lpThisRB->StickyChild());
760 
761  lpParent->m_lpThisRB->EnableCollision(m_lpThisRB->StickyChild());
762  m_lpThisRB->StickyChild(NULL);
763 
764  RigidBody *lpTest = dynamic_cast<RigidBody *>(GetSimulator()->FindByID("ac233f7b-8f8f-4d03-9d4f-21e363a19bc2"));
765  lpTest->DisableCollision(m_lpThisRB->StickyChild());*/
766  }
767 
768  GetBlSimulator()->DynamicsWorld()->removeConstraint(m_btStickyLock);
769 
770  delete m_btStickyLock;
771  m_btStickyLock = NULL;
772  }
773  }
774 
775  if(m_btStickyLock2)
776  {
777  if(GetBlSimulator() && GetBlSimulator()->DynamicsWorld())
778  {
779  GetBlSimulator()->DynamicsWorld()->removeConstraint(m_btStickyLock2);
780 
781  delete m_btStickyLock2;
782  m_btStickyLock2 = NULL;
783  }
784  }
785 }
786 
787 void BlRigidBody::SetSurfaceContactCount()
788 {
789  if(m_lpThisRB)
790  {
791  m_lpThisRB->SetSurfaceContactCount(m_aryContactPoints.size());
792 
793  if(m_lpThisRB->IsStickyPart() && m_aryContactPoints.size() > 0 && m_aryContactPoints[0]->m_lpContacted && m_lpThisRB->Parent())
794  {
795  //If we have a lock and the sticky on value goes below 1 then disable it by removing the lock
796  if(m_btStickyLock && m_lpThisRB->StickyOn() < 1)
797  Physics_DeleteStickyLock();
798  //If we do not have a lock and sticky on goes to 1 or above then create a new lock.
799  else if(!m_btStickyLock && m_lpThisRB->StickyOn() >= 1)
800  CreateStickyLock();
801  }
802  }
803 }
804 
805 void BlRigidBody::ProcessContacts()
806 {
807  ContactSensor *lpSensor = m_lpThisRB->GetContactSensor();
808 
809  if(lpSensor)
810  lpSensor->ClearCurrents();
811 
812  //If this is a contact sensor then we do not care about processing the force and position.
813  //We only care about the contact number.
814  if(m_lpThisRB->IsContactSensor())
815  SetSurfaceContactCount(); //m_lpThisRB->SetSurfaceContactCount(m_aryContactPoints.size());
816  else if(m_aryContactPoints.size() > 0 && m_btPart && lpSensor)
817  {
818  int iPartIdx=0;
819  StdVector3 vBodyPos;
820  float fltForceMag = 0;
821  float fDisUnits = m_lpThisAB->GetSimulator()->DistanceUnits();
822  float fMassUnits = m_lpThisAB->GetSimulator()->MassUnits();
823  float fltPhysicsDt = m_lpThisAB->GetSimulator()->PhysicsTimeStep();
824  float fltRatio = (fMassUnits * fDisUnits) / fltPhysicsDt;
825 
827  //if(m_lpThisRB->GetSimulator()->Time() >= 6.758)
828  // fltForceMag = 0;
829 
830  int iCount=m_aryContactPoints.size();
831  for(int iIdx=0; iIdx<iCount; iIdx++)
832  {
833  BlContactPoint *lpContactPoint = m_aryContactPoints[iIdx];
834 
835  if(lpContactPoint && lpContactPoint->m_lpCP)
836  {
837  lpContactPoint->m_lpCP->m_localPointB;
838 
839  if(lpContactPoint->m_bIsBodyA)
840  {
841  vBodyPos[0] = lpContactPoint->m_lpCP->m_localPointA[0];
842  vBodyPos[1] = lpContactPoint->m_lpCP->m_localPointA[1];
843  vBodyPos[2] = lpContactPoint->m_lpCP->m_localPointA[2];
844  }
845  else
846  {
847  vBodyPos[0] = lpContactPoint->m_lpCP->m_localPointB[0];
848  vBodyPos[1] = lpContactPoint->m_lpCP->m_localPointB[1];
849  vBodyPos[2] = lpContactPoint->m_lpCP->m_localPointB[2];
850  }
851 
852  fltForceMag = lpContactPoint->m_lpCP->m_appliedImpulse * fltRatio;
853 
854  if(fltForceMag > 0)
855  lpSensor->ProcessContact(vBodyPos, fltForceMag);
856  }
857  }
858 
859  }
860 
861  //Clear the contact points for the next simulation step.
862  m_aryContactPoints.Clear();
863 }
864 
865 void BlRigidBody::Physics_CollectData()
866 {
867  OsgSimulator *lpSim = GetOsgSimulator();
868  btVector3 vData;
869 
870  if(m_osgbMotion)
871  {
872  //Update the world matrix for this part
873  btTransform trans;
874  m_osgbMotion->getWorldTransform(trans);
875  m_osgWorldMatrix = osgbCollision::asOsgMatrix(trans);
876 
877  //Then update the absolute position and rotation.
878  btVector3 vPos = trans.getOrigin();
879  osg::Vec3 vCom = m_osgbMotion->getCenterOfMass();
880 
881  float fltX = (vPos.x()-vCom.x());
882  float fltY = (vPos.y()-vCom.y());
883  float fltZ = (vPos.z()-vCom.z());
884 
885  m_lpThisMI->AbsolutePosition(fltX, fltY, fltZ);
886 
887  m_osgWorldMatrix(3,0) = fltX;
888  m_osgWorldMatrix(3,1) = fltY;
889  m_osgWorldMatrix(3,2) = fltZ;
890 
891  CStdFPoint vRot = OsgMatrixUtil::EulerRotationFromMatrix_Static(m_osgWorldMatrix);
892  m_lpThisMI->ReportRotation(vRot[0], vRot[1], vRot[2]);
893  }
894  else
895  {
896  if(m_btCollisionObject)
897  m_btCollisionObject->setWorldTransform( osgbCollision::asBtTransform( GetOSGWorldMatrix(true) ) );
898 
899  //If we are here then we did not have a physics component, just and OSG one.
900  Physics_UpdateAbsolutePosition();
901 
902  CStdFPoint vRot = OsgMatrixUtil::EulerRotationFromMatrix_Static(m_osgWorldMatrix);
903  m_lpThisMI->ReportRotation(vRot[0], vRot[1], vRot[2]);
904  }
905 
906 
907  if(m_lpThisRB->GetContactSensor() || m_lpThisRB->IsContactSensor())
908  ProcessContacts();
909 }
910 
911 void BlRigidBody::Physics_CollectExtraData()
912 {
913  float fDisUnits = m_lpThisAB->GetSimulator()->DistanceUnits();
914  float fMassUnits = m_lpThisAB->GetSimulator()->MassUnits();
915  OsgSimulator *lpSim = GetOsgSimulator();
916  btVector3 vData;
917 
918  if(m_btPart && lpSim)
919  {
920  float m_vPrevLinearVelocity[3];
921  float m_vPrevAngularVelocity[3];
922 
923  //Store off the previoius linear and angular velocities for calculation of accelerations
924  m_vPrevLinearVelocity[0] = m_vLinearVelocity[0];
925  m_vPrevLinearVelocity[1] = m_vLinearVelocity[1];
926  m_vPrevLinearVelocity[2] = m_vLinearVelocity[2];
927 
928  m_vPrevAngularVelocity[0] = m_vAngularVelocity[0];
929  m_vPrevAngularVelocity[1] = m_vAngularVelocity[1];
930  m_vPrevAngularVelocity[2] = m_vAngularVelocity[2];
931 
932  vData = m_btPart->getLinearVelocity();
933  m_vLinearVelocity[0] = vData[0] * fDisUnits;
934  m_vLinearVelocity[1] = vData[1] * fDisUnits;
935  m_vLinearVelocity[2] = vData[2] * fDisUnits;
936 
937  vData = m_btPart->getAngularVelocity();
938  m_vAngularVelocity[0] = vData[0];
939  m_vAngularVelocity[1] = vData[1];
940  m_vAngularVelocity[2] = vData[2];
941 
942  vData = m_btPart->getTotalForce();
943  float fltRatio = fMassUnits * fDisUnits;
944  m_vForce[0] = vData[0] * fltRatio;
945  m_vForce[1] = vData[1] * fltRatio;
946  m_vForce[2] = vData[2] * fltRatio;
947 
948  vData = m_btPart->getTotalTorque();
949  fltRatio = fMassUnits * fDisUnits * fDisUnits;
950  m_vTorque[0] = vData[0] * fltRatio;
951  m_vTorque[1] = vData[1] * fltRatio;
952  m_vTorque[2] = vData[2] * fltRatio;
953 
954  float fltDt = lpSim->PhysicsTimeStep();
955 
956  if(fltDt > 0)
957  {
958  //Bullet has no methods to directly get these accelerations, so we need to calculate them ourselves
959  m_vLinearAcceleration[0] = (m_vLinearVelocity[0] - m_vPrevLinearVelocity[0])/fltDt;
960  m_vLinearAcceleration[1] = (m_vLinearVelocity[1] - m_vPrevLinearVelocity[1])/fltDt;
961  m_vLinearAcceleration[2] = (m_vLinearVelocity[2] - m_vPrevLinearVelocity[2])/fltDt;
962 
963  m_vAngularAcceleration[0] = (m_vAngularVelocity[0] - m_vPrevAngularVelocity[0])/fltDt;
964  m_vAngularAcceleration[1] = (m_vAngularVelocity[1] - m_vPrevAngularVelocity[1])/fltDt;
965  m_vAngularAcceleration[2] = (m_vAngularVelocity[2] - m_vPrevAngularVelocity[2])/fltDt;
966  }
967  }
968 }
969 
970 void BlRigidBody::Physics_ResetSimulation()
971 {
972  OsgRigidBody::Physics_ResetSimulation();
973 
974  if(m_btPart)
975  {
976  m_btPart->clearForces();
977  btVector3 zeroVector(0,0,0);
978  m_btPart->setLinearVelocity(zeroVector);
979  m_btPart->setAngularVelocity(zeroVector);
980  }
981 
982  Physics_WakeDynamics();
983 
984  for(int i=0; i<3; i++)
985  {
986  m_vTorque[i] = 0;
987  m_vForce[i] = 0;
988  m_vLinearVelocity[i] = 0;
989  m_vAngularVelocity[i] = 0;
990  m_vLinearAcceleration[i] = 0;
991  m_vAngularAcceleration[i] = 0;
992  }
993 
994  Physics_DeleteStickyLock();
995 }
996 
997 void BlRigidBody::Physics_EnableCollision(RigidBody *lpBody)
998 {
999  if(m_lpBulletData && m_lpThisRB->GetExclusionCollisionSet()->size() == 0)
1000  m_lpBulletData->m_bExclusionProcessing = false;
1001 }
1002 
1003 void BlRigidBody::Physics_DisableCollision(RigidBody *lpBody)
1004 {
1005  if(m_lpBulletData && m_lpThisRB->GetExclusionCollisionSet()->size() > 0)
1006  m_lpBulletData->m_bExclusionProcessing = true;
1007 }
1008 
1009 void BlRigidBody::Physics_AddBodyForceAtLocalPos(float fltPx, float fltPy, float fltPz, float fltFx, float fltFy, float fltFz, bool bScaleUnits)
1010 {
1011  if(m_btPart && (fltFx || fltFy || fltFz) && !m_lpThisRB->Freeze())
1012  {
1013  btVector3 fltF, fltP;
1014  if(bScaleUnits)
1015  {
1016  fltF[0] = fltFx * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1017  fltF[1] = fltFy * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1018  fltF[2] = fltFz * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1019  }
1020  else
1021  {
1022  fltF[0] = fltFx;
1023  fltF[1] = fltFy;
1024  fltF[2] = fltFz;
1025  }
1026 
1027  fltP[0] = fltPx;
1028  fltP[1] = fltPy;
1029  fltP[2] = fltPz;
1030 
1031  Physics_WakeDynamics();
1032  m_btPart->applyForce(fltF, fltP);
1033  }
1034 }
1035 
1036 void BlRigidBody::Physics_AddBodyForceAtWorldPos(float fltPx, float fltPy, float fltPz, float fltFx, float fltFy, float fltFz, bool bScaleUnits)
1037 {
1038  if(m_btPart && (fltFx || fltFy || fltFz) && !m_lpThisRB->Freeze())
1039  {
1040  btVector3 fltF, fltP;
1041  if(bScaleUnits)
1042  {
1043  fltF[0] = fltFx * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1044  fltF[1] = fltFy * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1045  fltF[2] = fltFz * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1046  }
1047  else
1048  {
1049  fltF[0] = fltFx;
1050  fltF[1] = fltFy;
1051  fltF[2] = fltFz;
1052  }
1053 
1054  //Bullet force application position is relative to the center of mass of the part.
1055  btVector3 vCOM = m_btPart->getCenterOfMassPosition();
1056 
1057  fltP[0] = fltPx - vCOM[0];
1058  fltP[1] = fltPy - vCOM[1];
1059  fltP[2] = fltPz - vCOM[2];
1060 
1061  Physics_WakeDynamics();
1062  m_btPart->applyForce(fltF, fltP);
1063  }
1064 }
1065 
1066 void BlRigidBody::Physics_AddBodyTorque(float fltTx, float fltTy, float fltTz, bool bScaleUnits)
1067 {
1068  if(m_btPart && (fltTx || fltTy || fltTz))
1069  {
1070  btVector3 fltT;
1071  if(bScaleUnits)
1072  {
1073  fltT[0] = fltTx * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1074  fltT[1] = fltTy * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1075  fltT[2] = fltTz * (m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
1076  }
1077  else
1078  {
1079  fltT[0] = fltTx;
1080  fltT[1] = fltTy;
1081  fltT[2] = fltTz;
1082  }
1083 
1084  m_btPart->applyTorque(fltT);
1085  }
1086 }
1087 
1088 CStdFPoint BlRigidBody::Physics_GetVelocityAtPoint(float x, float y, float z)
1089 {
1090  CStdFPoint linVel(0,0,0);
1091  btVector3 vLinVel(0,0,0);
1092  btVector3 vPoint(x,y,z);
1093 
1094  //if this is a contact sensor then return nothing.
1095  if(m_btPart)
1096  {
1097  vLinVel = m_btPart->getVelocityInLocalPoint(vPoint);
1098  linVel.Set(vLinVel[0], vLinVel[1], vLinVel[2]);
1099  }
1100 
1101  return linVel;
1102 }
1103 
1104 bool BlRigidBody::Physics_HasCollisionGeometry()
1105 {
1106  if(m_btCollisionShape)
1107  return true;
1108  else
1109  return false;
1110 }
1111 
1112 void BlRigidBody::Physics_StepHydrodynamicSimulation()
1113 {
1114  Simulator *lpSim = GetSimulator();
1115  BlSimulator *lpBlSim = GetBlSimulator();
1116  if(m_btPart && lpSim && lpBlSim && m_lpThisRB && !m_lpThisRB->Freeze())
1117  {
1118  float fltDepth = m_lpThisRB->AbsolutePosition().y;
1119  FluidPlane *lpPlane = lpBlSim->FindFluidPlaneForDepth(fltDepth);
1120 
1121  if(lpPlane)
1122  {
1123  m_fltBuoyancy = -(lpPlane->Density() * m_lpThisRB->Volume() * lpSim->Gravity() * m_lpThisRB->BuoyancyScale());
1124  m_fltReportBuoyancy = m_fltBuoyancy * lpSim->MassUnits() * lpSim->DistanceUnits();
1125 
1126  btVector3 vbtLinVel = m_btPart->getLinearVelocity();
1127  btVector3 vbtAngVel = m_btPart->getAngularVelocity();
1128 
1129  CStdFPoint vLinearVel(vbtLinVel[0], vbtLinVel[1], vbtLinVel[2]);
1130  CStdFPoint vAngularVel(vbtAngVel[0], vbtAngVel[1], vbtAngVel[2]);
1131  CStdFPoint vSignLinear(Std_Sign(vbtLinVel[0], 1), Std_Sign(vbtLinVel[1], 1), Std_Sign(vbtLinVel[2], 1));
1132  CStdFPoint vSignAngular(Std_Sign(vAngularVel[0], 1), Std_Sign(vAngularVel[1], 1), Std_Sign(vAngularVel[2], 1));
1133 
1135 
1136  CStdFPoint vLinearDragForce = (m_lpThisRB->LinearDrag() * m_vRotatedArea * vLinearVel * vLinearVel * vSignLinear) * (lpPlane->Density() * -0.5);
1137  CStdFPoint vAngularDragTorque = (m_lpThisRB->AngularDrag() * m_vRotatedArea * vAngularVel * vAngularVel * vSignAngular) * (lpPlane->Density() * -0.5);
1138  float fltMaxForce = m_lpThisRB->MaxHydroForce();
1139  float fltMaxTorque = m_lpThisRB->MaxHydroTorque();
1140  for(int i=0; i<3; i++)
1141  {
1142  m_vLinearDragForce[i] = vLinearDragForce[i] * lpSim->MassUnits() * lpSim->DistanceUnits();
1143  m_vAngularDragTorque[i] = vAngularDragTorque[i] * lpSim->MassUnits() * lpSim->DistanceUnits() * lpSim->DistanceUnits();
1144 
1145  if(vLinearDragForce[i] > fltMaxForce)
1146  vLinearDragForce[i] = fltMaxForce;
1147 
1148  if(vLinearDragForce[i] < -fltMaxForce)
1149  vLinearDragForce[i] = -fltMaxForce;
1150 
1151  if(m_vAngularDragTorque[i] > fltMaxTorque)
1152  vAngularDragTorque[i] = fltMaxTorque;
1153 
1154  if(m_vAngularDragTorque[i] < -fltMaxTorque)
1155  vAngularDragTorque[i] = -fltMaxTorque;
1156  }
1157 
1158  Physics_WakeDynamics();
1159  m_btPart->applyCentralForce(btVector3(vLinearDragForce.x, (vLinearDragForce.y+m_fltBuoyancy), vLinearDragForce.z));
1160  m_btPart->applyTorque(btVector3(vAngularDragTorque.x, vAngularDragTorque.y, vAngularDragTorque.z));
1161  }
1162  else
1163  {
1164  m_fltBuoyancy = 0;
1165  m_fltReportBuoyancy = 0;
1166  for(int iIdx=0; iIdx<3; iIdx++)
1167  {
1168  m_vLinearDragForce[iIdx] = 0;
1169  m_vAngularDragTorque[iIdx] = 0;
1170  }
1171  }
1172  }
1173 
1174 }
1175 
1176 float *BlRigidBody::Physics_GetDataPointer(const std::string &strDataType)
1177 {
1178  std::string strType = Std_CheckString(strDataType);
1179  RigidBody *lpBody = dynamic_cast<RigidBody *>(this);
1180 
1181  if(strType == "BODYBUOYANCY")
1182  return (&m_fltReportBuoyancy);
1183 
1184  if(strType == "BODYDRAGFORCEX")
1185  return (&m_vLinearDragForce[0]);
1186 
1187  if(strType == "BODYDRAGFORCEY")
1188  return (&m_vLinearDragForce[1]);
1189 
1190  if(strType == "BODYDRAGFORCEZ")
1191  return (&m_vLinearDragForce[2]);
1192 
1193  if(strType == "BODYDRAGTORQUEX")
1194  return (&m_vAngularDragTorque[0]);
1195 
1196  if(strType == "BODYDRAGTORQUEY")
1197  return (&m_vAngularDragTorque[1]);
1198 
1199  if(strType == "BODYDRAGTORQUEZ")
1200  return (&m_vAngularDragTorque[2]);
1201 
1202  return OsgRigidBody::Physics_GetDataPointer(strDataType);
1203 }
1204 
1205  } // Environment
1206 } //BulletAnimatSim
virtual void AddRigidBodyAssociation(RigidBody *lpBody)
Associates a rigid body with this material type. This is used when you change something about this ma...
virtual float FrictionAngularPrimaryConverted()
Gets the angular primary friction coefficient converted to match vortex values.
virtual void SetupOffsetCOM(const CStdFPoint &vCom)
Changes this body to use a btCompoundShape and adds the btCollision shape offset from -COM...
float m_vAngularDragTorque[3]
This is the drag forces applied to this body.
Definition: BlRigidBody.h:122
A common class for all joint data specific to vortex.
Definition: BlJoint.h:29
A common class for all rigid body data specific to vortex.
Definition: BlRigidBody.h:87
float m_vLinearDragForce[3]
This is the drag forces applied to this body.
Definition: BlRigidBody.h:119
virtual void CalculateRotatedAreas()
Rotates the axis area values by the amount that this part is rotated by. This is used by the hydrodyn...
int Std_Sign(float fltVal)
Determines the sign of a number.
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
virtual FluidPlane * FindFluidPlaneForDepth(float fltDepth)
Searches the fluid planes starting at the lowest height and working its way up to find the first one ...
virtual float Restitution()
Gets the restitution for collisions between RigidBodies with these two materials. ...
virtual float FrictionLinearPrimary()
Gets the primary friction coefficient.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
BlMaterialType * m_lpMaterial
The pointer to the material for this body.
Definition: BlRigidBody.h:131
float m_fltReportBuoyancy
The buoyancy force reported to the GUI.
Definition: BlRigidBody.h:116
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
float m_fltBuoyancy
The buoyancy force applied to this part.
Definition: BlRigidBody.h:113
virtual void RemoveRigidBodyAssociation(RigidBody *lpBody)
Removes the rigid body association described by lpBody from this material.
virtual float FrictionAngularPrimary()
Gets the angular primary friction coefficient.