AnimatLab  2
Test
OsgRigidBody.cpp
1 // OsgRigidBody.cpp: implementation of the OsgRigidBody class.
2 //
4 
5 #include "StdAfx.h"
6 #include "OsgMovableItem.h"
7 #include "OsgBody.h"
8 #include "OsgRigidBody.h"
9 #include "OsgJoint.h"
10 #include "OsgStructure.h"
11 #include "OsgSimulator.h"
12 #include "OsgUserData.h"
13 #include "OsgUserDataVisitor.h"
14 #include "OsgDragger.h"
15 
16 namespace OsgAnimatSim
17 {
18  namespace Environment
19  {
20 
22 // Construction/Destruction
24 
25 OsgRigidBody::OsgRigidBody()
26 {
27  for(int i=0; i<3; i++)
28  {
29  m_vTorque[i] = 0;
30  m_vForce[i] = 0;
31  m_vLinearVelocity[i] = 0;
32  m_vAngularVelocity[i] = 0;
33  m_vLinearAcceleration[i] = 0;
34  m_vAngularAcceleration[i] = 0;
35  }
36 }
37 
38 OsgRigidBody::~OsgRigidBody()
39 {
40 
41 try
42 {
43  //int i= 5;
44 }
45 catch(...)
46 {Std_TraceMsg(0, "Caught Error in desctructor of OsgRigidBody\r\n", "", -1, false, true);}
47 }
48 
49 void OsgRigidBody::SetThisPointers()
50 {
51  OsgBody::SetThisPointers();
52  m_lpThisRB = dynamic_cast<RigidBody *>(this);
53  if(!m_lpThisRB)
54  THROW_TEXT_ERROR(Osg_Err_lThisPointerNotDefined, Osg_Err_strThisPointerNotDefined, "m_lpThisRB, " + m_lpThisAB->Name());
55 
56  m_lpThisRB->PhysicsBody(this);
57 }
58 
59 void OsgRigidBody::Physics_UpdateMatrix()
60 {
61  OsgMovableItem::Physics_UpdateMatrix();
62  StartGripDrag();
63  EndGripDrag();
64 }
65 
66 void OsgRigidBody::UpdatePositionAndRotationFromMatrix()
67 {
68  if(m_lpThisRB)
69  m_lpThisRB->UpdatePhysicsPosFromGraphics();
70  else
71  OsgBody::UpdatePositionAndRotationFromMatrix();
72 }
73 
74 void OsgRigidBody::Physics_SetColor()
75 {
76  if(m_lpThisRB)
77  SetColor(*m_lpThisRB->Ambient(), *m_lpThisRB->Diffuse(), *m_lpThisRB->Specular(), m_lpThisRB->Shininess());
78 }
79 
80 void OsgRigidBody::Physics_TextureChanged()
81 {
82  if(m_lpThisRB)
83  SetTexture(m_lpThisRB->Texture());
84 }
85 
86 
87 
88 //The way bullet is operating is making do things a bit wonky for moving them in real time in the editor.
89 //Bullet insists that all OSG objects be relative to the world and attached to the root. If I try and use
90 //the dragger to move of those then it will only move that part, and not all the child parts, and this looks
91 //bad and is definetly different than how it previously worked. To get around this what I am doing is first
92 //deleting the physics fo this part and all child joints. I am deleting all child graphics (but not this ones
93 //graphics or the dragger would not work anymore). I am then recreating the graphics. However, when StartGripDrag
94 //is called in the drag handler it sets a sim property InDrag to true. If InDrag is true then the method AddOsgNodeToParent
95 //returns true. If this method is false then parts are added directly to root, if not then they are added to the
96 //parent part. So essentially, I am deleting the osg tree node that has everything connected to root, and then recreating
97 //it with everything connected to the parent object being dragged. When the grip drag is over I have to reset things
98 //back going against root. Annoying.
99 void OsgRigidBody::StartGripDrag()
100 {
101  //Delete the physics and graphics
102  DeletePhysics(true);
103  DeleteChildGraphics(true);
104 
105  //The recreate the graphics with AddOsgNodeToParent returning true for all parts.
106  //This will recreate the graphics with each node attached to its parent instead of
107  //everything connected to the root node like what is required for bullet to work.
108  SetupChildGraphics(true);
109 }
110 
111 
112 void OsgRigidBody::EndGripDrag()
113 {
114  //If this is a static part then we need to call EndGripDrag on its parent part so it can recreate
115  //the entire static part instead of calling it on this one.
116  if(m_lpThisRB && m_lpThisRB->HasStaticJoint())
117  {
118  OsgBody::UpdatePositionAndRotationFromMatrix();
119 
120  OsgRigidBody *lpOsgParent = dynamic_cast<OsgRigidBody *>(m_lpThisRB->Parent());
121  if(lpOsgParent)
122  {
123  //If we called StartGripDrag on the parent when the child was started dragging then we would
124  //be deleting the child graphics object during the drag, and that would be bad. So lets call
125  //start on the parent here to delete all the required things, and then end to recreate them.
126  lpOsgParent->DeletePhysics(true);
127  lpOsgParent->DeleteChildGraphics(true);
128 
129  lpOsgParent->EndGripDrag();
130  }
131  }
132  else
133  {
134  //We must recreate the physics geometry here in order for the code that calculates positions to work correctly
135  //because it performs check to make sure it has valid physics geometry.
136  CreatePhysicsGeometry();
137 
138  OsgBody::UpdatePositionAndRotationFromMatrix();
139 
140  DeleteChildGraphics(true);
141 
142  SetupPhysics();
143 
144  //Completely recreate the child parts and joints
145  if(m_lpThisRB)
146  {
147  //Recreate the child parts.
148  m_lpThisRB->CreateChildParts();
149 
150  //Recreate the joint from this part to its parent if one exists
151  if(m_lpThisRB->JointToParent())
152  m_lpThisRB->JointToParent()->CreateJoint();
153 
154  //Recreate the joint between this part and its parent
155  m_lpThisRB->CreateChildJoints();
156  }
157  }
158 
159  if(m_lpThisRB && m_lpThisRB->IsRoot())
160  {
161  OsgMovableItem *lpOsgStruct = dynamic_cast<OsgMovableItem *>(m_lpThisRB->GetStructure());
162  if(lpOsgStruct)
163  lpOsgStruct->FinalMatrix(m_osgFinalMatrix);
164  Physics_UpdateAbsolutePosition();
165  }
166 }
167 
168 
169 void OsgRigidBody::SetupChildGraphics(bool bRoot)
170 {
171  if(!bRoot)
172  {
173  InitializeGraphicsGeometry();
174  SetupGraphics();
175  }
176 
177  OsgJoint *lpVsJoint = dynamic_cast<OsgJoint *>(m_lpThisRB->JointToParent());
178 
179  if(lpVsJoint)
180  lpVsJoint->SetupGraphics();
181 
182  int iCount = m_lpThisRB->ChildParts()->GetSize();
183  for(int iIdx=0; iIdx<iCount; iIdx++)
184  {
185  RigidBody *lpChild = m_lpThisRB->ChildParts()->at(iIdx);
186  if(lpChild)
187  {
188  OsgRigidBody *lpVsChild = dynamic_cast<OsgRigidBody *>(lpChild);
189  if(lpVsChild)
190  lpVsChild->SetupChildGraphics(false);
191  }
192  }
193 }
194 
195 void OsgRigidBody::DeleteChildGraphics(bool bRoot)
196 {
197  if(!bRoot)
198  DeleteGraphics();
199 
200  OsgJoint *lpVsJoint = dynamic_cast<OsgJoint *>(m_lpThisRB->JointToParent());
201 
202  if(lpVsJoint)
203  lpVsJoint->DeleteGraphics();
204 
205  int iCount = m_lpThisRB->ChildParts()->GetSize();
206  for(int iIdx=0; iIdx<iCount; iIdx++)
207  {
208  RigidBody *lpChild = m_lpThisRB->ChildParts()->at(iIdx);
209  if(lpChild)
210  {
211  OsgRigidBody *lpVsChild = dynamic_cast<OsgRigidBody *>(lpChild);
212  if(lpVsChild)
213  lpVsChild->DeleteChildGraphics(false);
214  }
215  }
216 }
217 
218 void OsgRigidBody::Physics_Resize()
219 {
220  //First lets get rid of the current current geometry and then put new geometry in place.
221  if(m_osgNode.valid())
222  {
223  osg::Geode *osgGroup = NULL;
224  if(m_osgGeometryRotationMT.valid())
225  osgGroup = dynamic_cast<osg::Geode *>(m_osgGeometryRotationMT->getChild(0));
226  else
227  osgGroup = dynamic_cast<osg::Geode *>(m_osgNode.get());
228 
229  if(!osgGroup)
230  THROW_TEXT_ERROR(Osg_Err_lNodeNotGeode, Osg_Err_strNodeNotGeode, m_lpThisAB->Name());
231 
232  if(osgGroup && osgGroup->containsDrawable(m_osgGeometry.get()))
233  osgGroup->removeDrawable(m_osgGeometry.get());
234 
235  m_osgGeometry.release();
236 
237  //Create a new box geometry with the new sizes.
238  CreateGraphicsGeometry();
239  if(m_lpThisAB)
240  m_osgGeometry->setName(m_lpThisAB->Name() + "_Geometry");
241 
242  //Add it to the geode.
243  osgGroup->addDrawable(m_osgGeometry.get());
244 
245  //Now lets re-adjust the gripper size.
246  if(m_osgDragger.valid())
247  m_osgDragger->SetupMatrix();
248 
249  //Reset the user data for the new parts.
250  if(m_osgNodeGroup.valid())
251  {
252  osg::ref_ptr<OsgUserDataVisitor> osgVisitor = new OsgUserDataVisitor(this);
253  osgVisitor->traverse(*m_osgNodeGroup);
254  }
255  }
256 
257  if(Physics_IsDefined())
258  {
259  ResizePhysicsGeometry();
260 
261  //We need to reset the density in order for it to recompute the mass and volume.
262  if(m_lpThisRB)
263  Physics_SetDensity(m_lpThisRB->Density());
264 
265  //Now get base values, including mass and volume
266  GetBaseValues();
267  }
268 }
269 
270 void OsgRigidBody::Physics_SelectedVertex(float fltXPos, float fltYPos, float fltZPos)
271 {
272  if(m_lpThisRB->IsCollisionObject() && m_osgSelVertexMT.valid())
273  {
274  osg::Matrix osgMT;
275  osgMT.makeIdentity();
276  osgMT = osgMT.translate(fltXPos, fltYPos, fltZPos);
277 
278  m_osgSelVertexMT->setMatrix(osgMT);
279  }
280 }
281 
282 
283 void OsgRigidBody::ShowSelectedVertex()
284 {
285  if(m_lpThisRB && m_lpThisAB && m_lpThisRB->IsCollisionObject() && m_lpThisAB->Selected() && m_osgMT.valid() && m_osgSelVertexMT.valid())
286  {
287  if(!m_osgMT->containsNode(m_osgSelVertexMT.get()))
288  m_osgMT->addChild(m_osgSelVertexMT.get());
289  }
290 }
291 
292 void OsgRigidBody::HideSelectedVertex()
293 {
294  if(m_lpThisRB->IsCollisionObject() && m_osgMT.valid() && m_osgSelVertexMT.valid())
295  {
296  if(m_osgMT->containsNode(m_osgSelVertexMT.get()))
297  m_osgMT->removeChild(m_osgSelVertexMT.get());
298  }
299 }
300 
301 void OsgRigidBody::Physics_ResizeSelectedReceptiveFieldVertex()
302 {
303  DeleteSelectedVertex();
304  CreateSelectedVertex(m_lpThisAB->Name());
305 }
306 
307 void OsgRigidBody::Initialize()
308 {
309  //GetBaseValues();
310 }
311 
322 {
323  //build the local matrix
324  if(m_lpThisRB && m_lpThisMI && m_lpThisAB)
325  {
326  if(m_lpThisRB->IsRoot())
327  OsgBody::BuildLocalMatrix(m_lpThisAB->GetStructure()->AbsolutePosition(), CStdFPoint(0, 0, 0), m_lpThisMI->Rotation(), m_lpThisAB->Name());
328  else
329  OsgBody::BuildLocalMatrix(m_lpThisMI->Position(), CStdFPoint(0, 0, 0), m_lpThisMI->Rotation(), m_lpThisAB->Name());
330  }
331 }
332 
345 osg::MatrixTransform *OsgRigidBody::ParentOSG()
346 {
347  OsgMovableItem *lpItem = NULL;
348 
349  if(!m_lpThisRB->IsRoot() && m_lpParentVsMI)
350  return m_lpParentVsMI->GetMatrixTransform();
351  else
352  return GetOsgSimulator()->OSGRoot();
353 }
354 
355 osg::Matrix OsgRigidBody::GetComMatrix(bool bInvert)
356 {
357  if(m_lpThisRB)
358  {
359  CStdFPoint vCom = m_lpThisRB->CenterOfMassWithStaticChildren();
360 
361  if(bInvert)
362  vCom *= -1;
363 
364  osg::Matrixd mat = osg::Matrixd::identity();
365  return mat.translate(vCom.x, vCom.y, vCom.z);
366  }
367  else
368  return OsgBody::GetComMatrix();
369 }
370 
371 void OsgRigidBody::CreateGeometry(bool bOverrideStatic)
372 {
373  //Do not try to create the physics geometry here if we have a static joint because it will have already been
374  //created in the parent object.
375  if(m_lpThisRB && (!m_lpThisRB->HasStaticJoint() || bOverrideStatic))
376  {
377  InitializeGraphicsGeometry();
378  CreatePhysicsGeometry();
379  }
380 }
381 
382 void OsgRigidBody::SetupPhysics()
383 {
384  //If no geometry is defined then this part does not have a physics representation.
385  //it is purely an osg node attached to other parts. An example of this is an attachment point or a sensor.
386  if(m_lpThisRB && m_lpThisRB->IsCollisionObject())
387  {
388  //If the parent is not null and the joint is null then that means we need to statically link this part to
389  //its parent. So we do not create a physics part, we just get a link to its parents part.
390  if(m_lpThisRB->IsContactSensor())
391  CreateSensorPart();
392  else if(m_lpThisRB->HasStaticJoint())
393  {
394  //Do nothing here because static parts are created in the parent parts CreateDynamicPart method.
395  //The reason is that all the static parts and geometries for a compound shape must already exist
396  // in order to create them in bullet.
397  }
398  else
399  CreateDynamicPart();
400  }
401 }
402 
403 bool OsgRigidBody::AddOsgNodeToParent()
404 {
405  if(!m_lpThisRB || !m_lpThisRB->IsCollisionObject() || m_lpThisRB->IsContactSensor() || GetOsgSimulator()->InDrag() || m_lpThisRB->HasStaticJoint())
406  return true;
407  else
408  return false;
409 }
410 
411 float *OsgRigidBody::Physics_GetDataPointer(const std::string &strDataType)
412 {
413  std::string strType = Std_CheckString(strDataType);
414  RigidBody *lpBody = dynamic_cast<RigidBody *>(this);
415 
416  if(strType == "BODYTORQUEX")
417  {
418  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
419  return (&m_vTorque[0]);
420  }
421 
422  if(strType == "BODYTORQUEY")
423  {
424  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
425  return (&m_vTorque[1]);
426  }
427 
428  if(strType == "BODYTORQUEZ")
429  {
430  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
431  return (&m_vTorque[2]);
432  }
433 
434  if(strType == "BODYFORCEX")
435  {
436  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
437  return (&m_vForce[0]);
438  }
439 
440  if(strType == "BODYFORCEY")
441  {
442  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
443  return (&m_vForce[1]);
444  }
445 
446  if(strType == "BODYFORCEZ")
447  {
448  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
449  return (&m_vForce[2]);
450  }
451 
452  if(strType == "BODYLINEARVELOCITYX")
453  {
454  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
455  return (&m_vLinearVelocity[0]);
456  }
457 
458  if(strType == "BODYLINEARVELOCITYY")
459  {
460  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
461  return (&m_vLinearVelocity[1]);
462  }
463 
464  if(strType == "BODYLINEARVELOCITYZ")
465  {
466  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
467  return (&m_vLinearVelocity[2]);
468  }
469 
470  if(strType == "BODYANGULARVELOCITYX")
471  {
472  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
473  return (&m_vAngularVelocity[0]);
474  }
475 
476  if(strType == "BODYANGULARVELOCITYY")
477  {
478  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
479  return (&m_vAngularVelocity[1]);
480  }
481 
482  if(strType == "BODYANGULARVELOCITYZ")
483  {
484  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
485  return (&m_vAngularVelocity[2]);
486  }
487 
488  //if(strType == "BODYBUOYANCY")
489  // {m_bCollectExtraData = true; return (&m_fltReportBuoyancy);}
490 
491  if(strType == "BODYLINEARACCELERATIONX")
492  {
493  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
494  return (&m_vLinearAcceleration[0]);
495  }
496 
497  if(strType == "BODYLINEARACCELERATIONY")
498  {
499  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
500  return (&m_vLinearAcceleration[1]);
501  }
502 
503  if(strType == "BODYLINEARACCELERATIONZ")
504  {
505  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
506  return (&m_vLinearAcceleration[2]);
507  }
508 
509  if(strType == "BODYANGULARACCELERATIONX")
510  {
511  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
512  return (&m_vAngularAcceleration[0]);
513  }
514 
515  if(strType == "BODYANGULARACCELERATIONY")
516  {
517  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
518  return (&m_vAngularAcceleration[1]);
519  }
520 
521  if(strType == "BODYANGULARACCELERATIONZ")
522  {
523  GetOsgSimulator()->AddToExtractExtraData(m_lpThisRB);
524  return (&m_vAngularAcceleration[2]);
525  }
526 
527  return NULL;
528 }
529 
530 
531  } // Environment
532 } //OsgAnimatSim
osg::ref_ptr< osg::MatrixTransform > m_osgGeometryRotationMT
A common class for all rigid body data specific to vortex.
Definition: OsgRigidBody.h:50
virtual void SetupGraphics()
Sets up the graphics for the joint.
Definition: OsgJoint.cpp:196
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
virtual osg::MatrixTransform * ParentOSG()
Gets the parent osg node.
virtual void BuildLocalMatrix()
Builds the local matrix.
A common class for all joint data specific to vortex.
Definition: OsgJoint.h:26
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.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
Declares the vortex structure class.