AnimatLab  2
Test
VsMovableItem.cpp
1 #include "StdAfx.h"
2 #include <stdarg.h>
3 #include "VsMovableItem.h"
4 #include "VsBody.h"
5 #include "VsJoint.h"
6 #include "VsMotorizedJoint.h"
7 #include "VsRigidBody.h"
8 #include "VsOrganism.h"
9 #include "VsStructure.h"
10 #include "VsClassFactory.h"
11 #include "VsSimulator.h"
12 #include "VsOsgUserData.h"
13 #include "VsOsgUserDataVisitor.h"
14 
15 //#include "VsSimulationRecorder.h"
16 #include "VsMouseSpring.h"
17 #include "VsLight.h"
18 #include "VsCameraManipulator.h"
19 #include "VsDragger.h"
20 
21 namespace VortexAnimatSim
22 {
23  namespace Environment
24  {
25 
27 // Construction/Destruction
29 
30 VsMovableItem::VsMovableItem()
31 {
32  m_bCullBackfaces = false; //No backface culling by default.
33  m_eTextureMode = GL_TEXTURE_2D;
34 
35  m_lpThisAB = NULL;
36  m_lpThisMI = NULL;
37  m_lpThisVsMI = NULL;
38  m_lpParentVsMI = NULL;
39 
40  m_fltNullReport = 0;
41 }
42 
43 
44 VsMovableItem::~VsMovableItem()
45 {
46 }
47 
48 VsSimulator *VsMovableItem::GetVsSimulator()
49 {
50  VsSimulator *lpVsSim = dynamic_cast<VsSimulator *>(m_lpThisAB->GetSimulator());
51  //if(!lpVsSim)
52  // THROW_ERROR(Vs_Err_lUnableToConvertToVsSimulator, Vs_Err_strUnableToConvertToVsSimulator);
53  return lpVsSim;
54 }
55 
56 void VsMovableItem::SetThisPointers()
57 {
58  m_lpThisAB = dynamic_cast<AnimatBase *>(this);
59  if(!m_lpThisAB)
60  THROW_TEXT_ERROR(Vs_Err_lThisPointerNotDefined, Vs_Err_strThisPointerNotDefined, "m_lpThisAB");
61 
62  m_lpThisMI = dynamic_cast<MovableItem *>(this);
63  if(!m_lpThisMI)
64  THROW_TEXT_ERROR(Vs_Err_lThisPointerNotDefined, Vs_Err_strThisPointerNotDefined, "m_lpThisMI, " + m_lpThisAB->Name());
65 
66  m_lpThisVsMI = dynamic_cast<VsMovableItem *>(this);
67  if(!m_lpThisVsMI)
68  THROW_TEXT_ERROR(Vs_Err_lThisPointerNotDefined, Vs_Err_strThisPointerNotDefined, "m_lpThisVsMI, " + m_lpThisAB->Name());
69 
70  m_lpThisMI->PhysicsMovableItem(this);
71 }
72 
73 std::string VsMovableItem::Physics_ID()
74 {
75  if(m_lpThisAB)
76  return m_lpThisAB->ID();
77  else
78  return "";
79 }
80 
81 #pragma region Selection-Code
82 
83 void VsMovableItem::Physics_Selected(bool bValue, bool bSelectMultiple)
84 {
85  if(m_osgNodeGroup.valid() && m_osgDragger.valid() && m_osgSelectedGroup.valid())
86  {
87  bool bIsReceptiveFieldMode = (m_lpThisAB->GetSimulator()->VisualSelectionMode() & RECEPTIVE_FIELD_SELECTION_MODE);
88 
89  //If selecting and not already selected then select it
90  bool bNodeFound = m_osgNodeGroup->containsNode(m_osgSelectedGroup.get());
91  if(bValue && !bNodeFound)
92  {
93  m_osgNodeGroup->addChild(m_osgSelectedGroup.get());
94  if(!bIsReceptiveFieldMode)
95  m_osgDragger->AddToScene();
96  else
97  ShowSelectedVertex();
98  }
99  //if de-selecting and selected then de-select the node
100  else if(!bValue && bNodeFound)
101  {
102  m_osgNodeGroup->removeChild(m_osgSelectedGroup.get());
103  m_osgDragger->RemoveFromScene();
104  HideSelectedVertex();
105  }
106  }
107 }
108 
109 void VsMovableItem::CreateSelectedGraphics(std::string strName)
110 {
111  m_osgSelectedGroup = new osg::Group();
112  m_osgSelectedGroup->setName(strName + "_SelectedGroup");
113  m_osgSelectedGroup->addChild(m_osgNode.get());
114 
115  // set up the state so that the underlying color is not seen through
116  // and that the drawing mode is changed to wireframe, and a polygon offset
117  // is added to ensure that we see the wireframe itself, and turn off
118  // so texturing too.
119  osg::StateSet* stateset = new osg::StateSet;
120  osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
121  polyoffset->setFactor(-1.0f);
122  polyoffset->setUnits(-1.0f);
123  osg::PolygonMode* polymode = new osg::PolygonMode;
124  polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
125  stateset->setAttributeAndModes(polyoffset,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
126  stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
127 
128  osg::Material* material = new osg::Material;
129  stateset->setAttributeAndModes(material,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
130  stateset->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
131 
132  stateset->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
133 
134  m_osgSelectedGroup->setStateSet(stateset);
135 
136  CreateDragger(strName);
137  CreateSelectedVertex(strName);
138 }
139 
140 void VsMovableItem::CreateDragger(std::string strName)
141 {
142  std::string strVers = osgGetSOVersion();
143 
144  if(m_lpThisAB->GetSimulator())
145  {
146  if(GetVsSimulator()->OsgCmdMgr())
147  {
148  if(m_osgDragger.valid())
149  m_osgDragger.release();
150 
151  m_osgDragger = new VsDragger(this, m_lpThisMI->AllowTranslateDragX(), m_lpThisMI->AllowTranslateDragY(), m_lpThisMI->AllowTranslateDragX(),
152  m_lpThisMI->AllowRotateDragX(), m_lpThisMI->AllowRotateDragY(), m_lpThisMI->AllowRotateDragZ(),
153  m_lpThisMI->UserDefinedDraggerRadius());
154  m_osgDragger->setName(strName + "_Dragger");
155 
156  m_osgDragger->setupDefaultGeometry();
157 
158  GetVsSimulator()->OsgCmdMgr()->connect(*m_osgDragger, *m_osgMT);
159 
160  //Add pointers to this object to the grip so it will no which body part to
161  //call the EndGripDrag method on when the drag is finished.
162  m_osgDragger->setUserData(new VsOsgUserData(this));
163  }
164  }
165 }
166 
167 void VsMovableItem::CreateSelectedVertex(std::string strName)
168 {
169  if(!m_osgSelVertexNode.valid())
170  {
171  m_osgSelVertexNode = new osg::Geode();
172  m_osgSelVertexNode->setName(strName + "SelVertex");
173  float fltRadius = m_lpThisAB->GetSimulator()->RecFieldSelRadius();
174  osg::ShapeDrawable *osgDraw = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0, 0, 0), fltRadius));
175  osgDraw->setColor(osg::Vec4(0, 1, 0, 0));
176  m_osgSelVertexNode->addDrawable(osgDraw);
177  }
178 
179  if(!m_osgSelVertexMT.valid())
180  {
181  m_osgSelVertexMT = new osg::MatrixTransform();
182 
183  //Initially have it at the center. It will get moved as vertices are picked.
184  osg::Matrix osgMT;
185  osgMT.makeIdentity();
186  m_osgSelVertexMT->setMatrix(osgMT);
187 
188  m_osgSelVertexMT->addChild(m_osgSelVertexNode.get());
189  }
190 }
191 
192 void VsMovableItem::DeleteSelectedVertex()
193 {
194  HideSelectedVertex();
195 
196  if(m_osgSelVertexNode.valid()) m_osgSelVertexNode.release();
197  if(m_osgSelVertexMT.valid()) m_osgSelVertexMT.release();
198 }
199 
200 #pragma endregion
201 
202 float *VsMovableItem::Physics_GetDataPointer(const std::string &strDataType) {return NULL;}
203 
204 void VsMovableItem::LocalMatrix(osg::Matrix osgLocalMT)
205 {
206  m_osgLocalMatrix = osgLocalMT;
207  m_osgFinalMatrix = osgLocalMT;
208  UpdateWorldMatrix();
209 }
210 
211 void VsMovableItem::GeometryRotationMatrix(osg::Matrix osgGeometryMT)
212 {
213  if(!m_osgGeometryRotationMT.valid())
214  {
215  m_osgGeometryRotationMT = new osg::MatrixTransform;
216  m_osgGeometryRotationMT->setName(m_lpThisAB->Name() + "_GeometryMT");
217  }
218  m_osgGeometryRotationMT->setMatrix(osgGeometryMT);
219 }
220 
221 void VsMovableItem::AttachedPartMovedOrRotated(std::string strID)
222 {
223  Physics_ResetGraphicsAndPhysics();
224 }
225 
226 void VsMovableItem::CreateGraphicsGeometry() {}
227 
228 void VsMovableItem::CreatePhysicsGeometry() {}
229 
230 void VsMovableItem::ResizePhysicsGeometry() {}
231 
232 void VsMovableItem::CreateGeometry()
233 {
234  CreateGraphicsGeometry();
235  m_osgGeometry->setName(m_lpThisAB->Name() + "_Geometry");
236 
237  osg::Geode *osgGroup = new osg::Geode;
238  osgGroup->addDrawable(m_osgGeometry.get());
239  osgGroup->setName(m_lpThisAB->Name() + "_Node");
240 
241  //If ther is a geometry rotation then apply it first, otherwise
242  //just use the node straight out.
243  if(m_osgGeometryRotationMT.valid())
244  {
245  m_osgGeometryRotationMT->addChild(osgGroup);
246  m_osgNode = m_osgGeometryRotationMT.get();
247  }
248  else
249  m_osgNode = osgGroup;
250 
251  CreatePhysicsGeometry();
252 }
253 
254 void VsMovableItem::SetupGraphics()
255 {
256  m_osgParent = ParentOSG();
257 
258  if(m_osgParent.valid())
259  {
260  BuildLocalMatrix();
261 
262  SetColor(*m_lpThisMI->Ambient(), *m_lpThisMI->Diffuse(), *m_lpThisMI->Specular(), m_lpThisMI->Shininess());
263  SetTexture(m_lpThisMI->Texture());
264  SetCulling();
265  SetVisible(m_lpThisMI->IsVisible());
266 
267  //Add it to the scene graph.
268  m_osgParent->addChild(m_osgRoot.get());
269 
270  //Set the position with the world coordinates.
271  Physics_UpdateAbsolutePosition();
272 
273  //We need to set the UserData on the OSG side so we can do picking.
274  //We need to use a node visitor to set the user data for all drawable nodes in all geodes for the group.
275  osg::ref_ptr<VsOsgUserDataVisitor> osgVisitor = new VsOsgUserDataVisitor(this);
276  osgVisitor->traverse(*m_osgMT);
277  }
278 }
279 
280 void VsMovableItem::DeleteGraphics()
281 {
282  if(m_osgParent.valid() && m_osgRoot.valid())
283  {
284  if(m_osgParent->containsNode(m_osgRoot.get()))
285  m_osgParent->removeChild(m_osgRoot.get());
286  }
287 
288  if(m_osgSelVertexNode.valid()) m_osgSelVertexNode.release();
289  if(m_osgSelVertexMT.valid()) m_osgSelVertexMT.release();
290 
291  if(m_osgCull.valid()) m_osgCull.release();
292  if(m_osgTexture.valid()) m_osgTexture.release();
293  if(m_osgStateSet.valid()) m_osgStateSet.release();
294  if(m_osgMaterial.valid()) m_osgMaterial.release();
295 
296  if(m_osgGeometry.valid()) m_osgGeometry.release();
297  if(m_osgNode.valid()) m_osgNode.release();
298  if(m_osgSelectedGroup.valid()) m_osgSelectedGroup.release();
299  if(m_osgNodeGroup.valid()) m_osgNodeGroup.release();
300  if(m_osgGeometryRotationMT.valid()) m_osgGeometryRotationMT.release();
301  if(m_osgMT.valid()) m_osgMT.release();
302  if(m_osgRoot.valid()) m_osgRoot.release();
303  if(m_osgParent.valid()) m_osgParent.release();
304 }
305 
306 VsMovableItem *VsMovableItem::VsParent()
307 {
308  return m_lpParentVsMI;
309 }
310 
311 osg::Matrix VsMovableItem::GetWorldMatrix()
312 {
313  return m_osgWorldMatrix;
314 }
315 
316 osg::Matrix VsMovableItem::GetParentWorldMatrix()
317 {
318  if(m_lpParentVsMI)
319  return m_lpParentVsMI->GetWorldMatrix();
320 
321  osg::Matrix osgMatrix;
322  osgMatrix.makeIdentity();
323  return osgMatrix;
324 }
325 
326 void VsMovableItem::UpdateWorldMatrix()
327 {
328  osg::Matrix osgParentMatrix = GetParentWorldMatrix();
329 
330  //Multiply the two matrices together to get the new world location.
331  m_osgWorldMatrix = m_osgFinalMatrix * osgParentMatrix;
332 }
333 
334 CStdFPoint VsMovableItem::GetOSGWorldCoords()
335 {
336  UpdateWorldMatrix();
337  osg::Vec3 vCoord = m_osgWorldMatrix.getTrans();
338  CStdFPoint vPoint(vCoord[0], vCoord[1], vCoord[2]);
339 
340  return vPoint;
341 }
342 
343 osg::Matrix VsMovableItem::GetOSGWorldMatrix(bool bUpdate)
344 {
345  if(bUpdate)
346  UpdateWorldMatrix();
347 
348  return m_osgWorldMatrix;
349 }
350 
351 bool VsMovableItem::Physics_CalculateLocalPosForWorldPos(float fltWorldX, float fltWorldY, float fltWorldZ, CStdFPoint &vLocalPos)
352 {
353  VsMovableItem *lpParent = m_lpThisVsMI->VsParent();
354 
355  if(lpParent)
356  {
357  fltWorldX *= m_lpThisAB->GetSimulator()->InverseDistanceUnits();
358  fltWorldY *= m_lpThisAB->GetSimulator()->InverseDistanceUnits();
359  fltWorldZ *= m_lpThisAB->GetSimulator()->InverseDistanceUnits();
360 
361  CStdFPoint vPos(fltWorldX, fltWorldY, fltWorldZ), vRot(0, 0, 0);
362  osg::Matrix osgWorldPos = SetupMatrix(vPos, vRot);
363 
364  //Get the parent object.
365  osg::Matrix osgInverse = osg::Matrix::inverse(lpParent->GetWorldMatrix());
366 
367  osg::Matrix osgCalc = osgWorldPos * osgInverse;
368 
369  osg::Vec3 vCoord = osgCalc.getTrans();
370  vLocalPos.Set(vCoord[0] * m_lpThisAB->GetSimulator()->DistanceUnits(),
371  vCoord[1] * m_lpThisAB->GetSimulator()->DistanceUnits(),
372  vCoord[2] * m_lpThisAB->GetSimulator()->DistanceUnits());
373 
374  return true;
375  }
376 
377  return false;
378 }
379 
380 /*
381 CStdFPoint VsMovableItem::GetOSGWorldCoords()
382 {
383  CStdFPoint vTemp = GetMyOSGWorldCoords();
384 
385  CStdFPoint vOld = GetOSGWorldCoords(GetMatrixTransform());
386 
387  int iDiff = 0;
388  if(vOld != vTemp)
389  iDiff = 1;
390 
391  return vOld;
392 }
393 
394 CStdFPoint VsMovableItem::GetOSGWorldCoords(osg::MatrixTransform *osgMT)
395 {
396  WorldCoordinateNodeVisitor ncv;
397  osgMT->accept(ncv);
398  osg::Vec3 vCoord = ncv.MatrixTransform().getTrans();
399  CStdFPoint vPoint(vCoord[0], vCoord[1], vCoord[2]);
400  return vPoint;
401 }
402 
403 osg::Matrix VsMovableItem::GetOSGWorldMatrix()
404 {
405  return GetOSGWorldMatrix(GetMatrixTransform());
406 }
407 
408 osg::Matrix VsMovableItem::GetOSGWorldMatrix(osg::MatrixTransform *osgMT)
409 {
410  WorldCoordinateNodeVisitor ncv;
411  osgMT->accept(ncv);
412  return ncv.MatrixTransform();
413 }
414 */
415 
416 void VsMovableItem::WorldToBodyCoords(VxReal3 vWorld, StdVector3 &vLocalPos)
417 {
418  osg::Vec3f vWorldPos;
419  osg::Vec3f vLocal;
420 
421  vLocalPos[0] = vWorld[0]; vLocalPos[1] = vWorld[1]; vLocalPos[2] = vWorld[2];
422  vWorldPos[0] = vWorld[0]; vWorldPos[1] = vWorld[1]; vWorldPos[2] = vWorld[2];
423 
424  if(m_osgNode.valid())
425  {
426  osg::NodePathList paths = m_osgNode->getParentalNodePaths();
427  osg::Matrix worldToLocal = osg::computeWorldToLocal(paths.at(0));
428  vLocal = vWorldPos * worldToLocal;
429  }
430 
431  vLocalPos[0] = vLocal[0]; vLocalPos[1] = vLocal[1]; vLocalPos[2] = vLocal[2];
432 }
433 
434 osg::MatrixTransform* VsMovableItem::GetMatrixTransform()
435 {
436  return m_osgMT.get();
437 }
438 
455 {
456  if(m_osgGeometryRotationMT.valid())
457  return m_osgGeometryRotationMT.get();
458  else
459  return m_osgMT.get();
460 }
461 
462 void VsMovableItem::UpdatePositionAndRotationFromMatrix()
463 {
464  UpdatePositionAndRotationFromMatrix(m_osgMT->getMatrix());
465 }
466 
467 void VsMovableItem::UpdatePositionAndRotationFromMatrix(osg::Matrix osgMT)
468 {
469  LocalMatrix(osgMT);
470 
471  //Lets get the current world coordinates for this body part and then recalculate the
472  //new local position for the part and then finally reset its new local position.
473  osg::Vec3 vL = osgMT.getTrans();
474  CStdFPoint vLocal(vL.x(), vL.y(), vL.z());
475  vLocal.ClearNearZero();
476  m_lpThisMI->Position(vLocal, false, true, false);
477 
478  //Now lets get the euler angle rotation
479  Vx::VxReal44 vxTM;
480  VxOSG::copyOsgMatrix_to_VxReal44(osgMT, vxTM);
481  Vx::VxTransform vTrans(vxTM);
482  Vx::VxReal3 vEuler;
483  vTrans.getRotationEulerAngles(vEuler);
484  CStdFPoint vRot(vEuler[0], vEuler[1] ,vEuler[2]);
485  vRot.ClearNearZero();
486  m_lpThisMI->Rotation(vRot, true, false);
487 
488  if(m_osgDragger.valid())
489  m_osgDragger->SetupMatrix();
490 
491  //Test the matrix to make sure they match. I will probably get rid of this code after full testing.
492  osg::Matrix osgTest = SetupMatrix(vLocal, vRot);
493  if(!OsgMatricesEqual(osgTest, m_osgLocalMatrix))
494  THROW_ERROR(Vs_Err_lUpdateMatricesDoNotMatch, Vs_Err_strUpdateMatricesDoNotMatch);
495 }
496 
497 void VsMovableItem::Physics_UpdateMatrix()
498 {
499  if(m_osgMT.valid())
500  {
501  LocalMatrix(SetupMatrix(m_lpThisMI->Position(), m_lpThisMI->Rotation()));
502  m_osgMT->setMatrix(m_osgLocalMatrix);
503 
504  if(m_osgDragger.valid())
505  m_osgDragger->SetupMatrix();
506 
507  Physics_UpdateAbsolutePosition();
508  }
509 }
510 
511 void VsMovableItem::Physics_UpdateAbsolutePosition()
512 {
513  //If we are here then we did not have a physics component, just and OSG one.
514  CStdFPoint vPos = VsMovableItem::GetOSGWorldCoords();
515  vPos.ClearNearZero();
516  m_lpThisMI->AbsolutePosition(vPos.x, vPos.y, vPos.z);
517 }
518 
519 void VsMovableItem::BuildLocalMatrix()
520 {
521  //build the local matrix
522  BuildLocalMatrix(m_lpThisMI->Position(), m_lpThisMI->Rotation(), m_lpThisAB->Name());
523 }
524 
525 void VsMovableItem::BuildLocalMatrix(CStdFPoint localPos, CStdFPoint localRot, std::string strName)
526 {
527  if(!m_osgMT.valid())
528  {
529  m_osgMT = new osgManipulator::Selection;
530  m_osgMT->setName(strName + "_MT");
531  }
532 
533  if(!m_osgRoot.valid())
534  {
535  m_osgRoot = new osg::Group;
536  m_osgRoot->setName(strName + "_Root");
537  }
538 
539  if(!m_osgRoot->containsNode(m_osgMT.get()))
540  m_osgRoot->addChild(m_osgMT.get());
541 
542  LocalMatrix(SetupMatrix(localPos, localRot));
543 
544  //set the matrix to the matrix transform node
545  m_osgMT->setMatrix(m_osgLocalMatrix);
546 
547  //First create the node group. The reason for this is so that we can add other decorated groups on to this node.
548  //This is used to add the selected overlays.
549  if(!m_osgNodeGroup.valid() && m_osgNode.valid())
550  {
551  m_osgNodeGroup = new osg::Group();
552  m_osgNodeGroup->addChild(m_osgNode.get());
553  m_osgNodeGroup->setName(strName + "_NodeGroup");
554 
555  m_osgMT->addChild(m_osgNodeGroup.get());
556 
557  CreateSelectedGraphics(strName);
558  }
559 }
560 
561 void VsMovableItem::Physics_LoadLocalTransformMatrix(CStdXml &oXml)
562 {
563  osg::Matrix osgMT = LoadMatrix(oXml, "LocalMatrix");
564  UpdatePositionAndRotationFromMatrix(osgMT);
565 }
566 
567 void VsMovableItem::Physics_SaveLocalTransformMatrix(CStdXml &oXml)
568 {
569  SaveMatrix(oXml, "LocalMatrix", m_osgMT->getMatrix());
570 }
571 
572 std::string VsMovableItem::Physics_GetLocalTransformMatrixString()
573 {
574  if(m_osgMT.valid())
575  return SaveMatrixString(m_osgMT->getMatrix());
576  else
577  return SaveMatrixString(osg::Matrixf::identity());
578 }
579 
580 void VsMovableItem::Physics_ResizeDragHandler(float fltRadius)
581 {
582  bool bInScene = false;
583  if(m_osgDragger.valid() && m_osgDragger->IsInScene())
584  {
585  m_osgDragger->RemoveFromScene();
586  bInScene = true;
587  }
588 
589  CreateDragger(m_lpThisAB->Name());
590 
591  if(bInScene)
592  m_osgDragger->AddToScene();
593 }
594 
595 void VsMovableItem::Physics_ResetGraphicsAndPhysics()
596 {
597  BuildLocalMatrix();
598 
599  SetupPhysics();
600 }
601 
602 void VsMovableItem::Physics_PositionChanged()
603 {
604  Physics_UpdateMatrix();
605 }
606 
607 void VsMovableItem::Physics_RotationChanged()
608 {
609  Physics_UpdateMatrix();
610 }
611 
612 BoundingBox VsMovableItem::Physics_GetBoundingBox()
613 {
614  BoundingBox abb;
615 
616  osg::BoundingBox bb;
617  osg::Geode *osgGroup = dynamic_cast<osg::Geode *>(m_osgNode.get());
618  if(osgGroup)
619  {
620  bb = osgGroup->getBoundingBox();
621  abb.Set(bb.xMin(), bb.yMin(), bb.zMin(), bb.xMax(), bb.yMax(), bb.zMax());
622  }
623  else if(m_osgNode.valid())
624  {
625  osg::BoundingSphere osgBound = m_osgNode->getBound();
626  abb.Set(-osgBound.radius(), -osgBound.radius(), -osgBound.radius(), osgBound.radius(), osgBound.radius(), osgBound.radius());
627  }
628  else
629  {
630  abb.Set(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5);
631  }
632 
633  return abb;
634 }
635 
636 float VsMovableItem::Physics_GetBoundingRadius()
637 {
638  BoundingBox bb = Physics_GetBoundingBox();
639  return bb.MaxDimension();
640 
641  //if(m_osgNode.valid())
642  //{
643  // osg::BoundingSphere osgBound = m_osgNode->getBound();
644  // return osgBound.radius();
645  //}
646 
647  //return 0.5f;
648 }
649 
650 void VsMovableItem::SetTexture(std::string strTexture)
651 {
652  if(m_osgNode.valid())
653  {
654  if(!Std_IsBlank(strTexture))
655  {
656  std::string strFile = AnimatSim::GetFilePath(m_lpThisAB->GetSimulator()->ProjectPath(), strTexture);
657  osg::ref_ptr<osg::Image> image = osgDB::readImageFile(strFile);
658  if(!image)
659  THROW_PARAM_ERROR(Vs_Err_lTextureLoad, Vs_Err_strTextureLoad, "Image File", strFile);
660 
661  osg::StateSet* state = m_osgNode->getOrCreateStateSet();
662  m_osgTexture = new osg::Texture2D(image.get());
663  m_osgTexture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
664 
665  m_osgTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
666  m_osgTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
667 
668  state->setTextureAttributeAndModes(0, m_osgTexture.get());
669  state->setTextureMode(0, m_eTextureMode, osg::StateAttribute::ON);
670  state->setMode(GL_BLEND,osg::StateAttribute::ON);
671 
672  //state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
673  }
674  else if(m_osgTexture.valid()) //If we have already set it and we are clearing it then reset the state
675  {
676  m_osgTexture.release();
677  osg::StateSet* state = m_osgNode->getOrCreateStateSet();
678  state->setTextureAttributeAndModes(0, NULL);
679  state->setTextureMode(0, m_eTextureMode, osg::StateAttribute::OFF);
680  }
681  }
682 }
683 
684 void VsMovableItem::Physics_CollectData()
685 {
686  //If we are here then we did not have a physics component, just and OSG one.
687  Physics_UpdateAbsolutePosition();
688 
689  //TODO: Get Rotation
690  //m_lpThis->ReportRotation(QuaterionToEuler(m_osgLocalMatrix.getRotate());
691 }
692 
693 void VsMovableItem::Physics_ResetSimulation()
694 {
695  if(m_osgMT.valid())
696  {
697  BuildLocalMatrix();
698 
699  //Set the position with the world coordinates.
700  Physics_UpdateAbsolutePosition();
701  m_lpThisMI->ReportRotation(m_lpThisMI->Rotation());
702  }
703 }
704 
705 
706 void VsMovableItem::SetCulling()
707 {
708  if(m_osgMT.valid())
709  {
710  if(m_bCullBackfaces)
711  {
712  if(!m_osgCull.valid())
713  {
714  m_osgCull = new osg::CullFace();
715  m_osgCull->setMode(osg::CullFace::BACK);
716  }
717  osg::StateSet* ss = m_osgMT->getOrCreateStateSet();
718  ss->setAttributeAndModes(m_osgCull.get(), osg::StateAttribute::ON);
719  }
720  else if(m_osgCull.valid())
721  {
722  osg::StateSet* ss = m_osgMT->getOrCreateStateSet();
723  ss->setAttributeAndModes(m_osgCull.get(), osg::StateAttribute::OFF);
724  }
725  }
726 }
727 
728 void VsMovableItem::ShowSelectedVertex() {}
729 
730 void VsMovableItem::HideSelectedVertex() {}
731 
732 void VsMovableItem::SetAlpha()
733 {
734  switch (m_lpThisAB->GetSimulator()->VisualSelectionMode())
735  {
736  case GRAPHICS_SELECTION_MODE:
737  m_lpThisMI->Alpha(m_lpThisMI->GraphicsAlpha());
738  HideSelectedVertex();
739  break;
740 
741  case COLLISION_SELECTION_MODE:
742  m_lpThisMI->Alpha(m_lpThisMI->CollisionsAlpha());
743  HideSelectedVertex();
744  break;
745 
746  case JOINT_SELECTION_MODE:
747  m_lpThisMI->Alpha(m_lpThisMI->JointsAlpha());
748  HideSelectedVertex();
749  break;
750 
751  case RECEPTIVE_FIELD_SELECTION_MODE:
752  m_lpThisMI->Alpha(m_lpThisMI->ReceptiveFieldsAlpha());
753  ShowSelectedVertex();
754  break;
755 
756  case SIMULATION_SELECTION_MODE:
757  m_lpThisMI->Alpha(m_lpThisMI->SimulationAlpha());
758  HideSelectedVertex();
759  break;
760 
761  default:
762  m_lpThisMI->Alpha(m_lpThisMI->GraphicsAlpha());
763  HideSelectedVertex();
764  break;
765  }
766 
767  if(m_osgMaterial.valid() && m_osgStateSet.valid())
768  SetMaterialAlpha(m_osgMaterial.get(), m_osgStateSet.get(), m_lpThisMI->Alpha());
769 }
770 
771 void VsMovableItem::SetMaterialAlpha(osg::Material *osgMat, osg::StateSet *ss, float fltAlpha)
772 {
773  osgMat->setAlpha(osg::Material::FRONT_AND_BACK, fltAlpha);
774 
775  if(fltAlpha < 1)
776  ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
777  else
778  ss->setRenderingHint(osg::StateSet::OPAQUE_BIN);
779 }
780 
781 void VsMovableItem::SetColor(CStdColor &vAmbient, CStdColor &vDiffuse, CStdColor &vSpecular, float fltShininess)
782 {
783  if(m_osgNode.valid())
784  {
785 
786  //create a material to use with this node
787  if(!m_osgMaterial)
788  m_osgMaterial = new osg::Material();
789 
790  //create a stateset for this node
791  m_osgStateSet = m_osgNode->getOrCreateStateSet();
792 
793  //set the diffuse property of this node to the color of this body
794  m_osgMaterial->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(vAmbient[0], vAmbient[1], vAmbient[2], 1));
795  m_osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(vDiffuse[0], vDiffuse[1], vDiffuse[2], vDiffuse[3]));
796  m_osgMaterial->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(vSpecular[0], vSpecular[1], vSpecular[2], 1));
797  m_osgMaterial->setShininess(osg::Material::FRONT_AND_BACK, fltShininess);
798  m_osgStateSet->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
799  SetAlpha();
800 
801  //apply the material
802  m_osgStateSet->setAttribute(m_osgMaterial.get(), osg::StateAttribute::ON);
803  }
804 }
805 
806 void VsMovableItem::SetVisible(osg::Node *osgNode, bool bVisible)
807 {
808  if(osgNode)
809  {
810  if(bVisible)
811  osgNode->setNodeMask(0x1);
812  else
813  osgNode->setNodeMask(0x0);
814  }
815 }
816 
817 void VsMovableItem::SetVisible(bool bVisible)
818 {
819  SetVisible(m_osgNode.get(), bVisible);
820 }
821 
822 void VsMovableItem::CreateItem()
823 {
824  m_lpThisAB->Initialize();
825  SetupGraphics();
826  SetupPhysics();
827 }
828 
829 void VsMovableItem::EndGripDrag()
830 {
831  this->UpdatePositionAndRotationFromMatrix();
832 }
833 //
834 //osg::Vec3 VsMovableItem::FindPointOnSurface(osg::Vec3 vDirection)
835 //{
836 // //If the parent object is not set then we cannot do orientation.
837 // if(!m_lpThisMI)
838 // return osg::Vec3(0, 0, 0);
839 //
840 // CStdFPoint vAbsPos = m_lpThisMI->AbsolutePosition();
841 // osg::Vec3 vPos(vAbsPos.x, vAbsPos.y, vAbsPos.z);
842 //
843 // osg::Vec3 vStart = vPos - (vDirection*10);
844 // osg::Vec3 vEnd = vPos + (vDirection*10);
845 //
846 // osg::LineSegment* osgLine = new osg::LineSegment();
847 // osgLine->set(vStart, vEnd);
848 //
849 // osgUtil::IntersectVisitor findIntersectVisitor;
850 // findIntersectVisitor.addLineSegment(osgLine);
851 // findIntersectVisitor.apply(*m_osgNodeGroup.get()); //
852 //
853 // osgUtil::IntersectVisitor::HitList tankIntersectHits;
854 // tankIntersectHits = findIntersectVisitor.getHitList(osgLine);
855 // osgUtil::Hit heightTestResults;
856 // if ( tankIntersectHits.empty() )
857 // return osg::Vec3(0, 0, 0);
858 //
859 // heightTestResults = tankIntersectHits.front();
860 // osg::Vec3d vIntersect = heightTestResults.getLocalIntersectPoint();;
861 //
862 // return vIntersect;
863 //}
864 //
865 //void VsMovableItem::Physics_OrientNewPart(float fltXPos, float fltYPos, float fltZPos, float fltXNorm, float fltYNorm, float fltZNorm)
866 //{
867 // //If the parent object is not set then we cannot do orientation.
868 // if(!m_lpThisMI || !m_lpThisMI->Parent())
869 // return;
870 //
871 // osg::Vec3 vClickPos(fltXPos, fltYPos, fltZPos), vClickNormal(fltXNorm, fltYNorm, fltZNorm);
872 // osg::Vec3 vPointOnSurf = FindPointOnSurface(vClickNormal);
873 //
874 // osg::Vec3 vWorldPos = vClickPos + vPointOnSurf;
875 //
876 // CStdFPoint vParentPos = m_lpThisMI->Parent()->AbsolutePosition();
877 // osg::Vec3 vParent(vParentPos.x, vParentPos.y, vParentPos.z);
878 //
879 // osg::Vec3 vLocalPos = vWorldPos - vParent;
880 //
881 //
882 // osg::Vec3 vInitDir(0, 0, 1);
883 // float fltDot = vInitDir * vClickNormal;
884 // float fltAngle = acos(fltDot);
885 // osg::Vec3 vAxis = vInitDir ^ vClickNormal;
886 //
887 // //Setup the new local matrix.
888 // osg::Matrix osgM;
889 // osgM.makeIdentity();
890 // osgM.makeRotate(fltAngle, vAxis);
891 // osgM.makeTranslate(vLocalPos);
892 //
893 // UpdatePositionAndRotationFromMatrix(osgM);
894 //
895 // //rbNewPart.DxLocation = v + rbNewPart.FindPointOnSurface(new Vector3(), -rbParent.FaceNormal);
896 //
897 // //Vector3 v3InitDir = new Vector3(0,0,1);
898 // //
899 // //float fltAngle = (float)Math.Acos(Vector3.Dot(v3InitDir,Direction));
900 //
901 // //Vector3 v3Axis = Vector3.Cross(v3InitDir, Direction);
902 //
903 // //m_mtxOrientation.RotateAxis(v3Axis,fltAngle);
904 //}
905 
906 
907 void VsMovableItem::Physics_OrientNewPart(float fltXPos, float fltYPos, float fltZPos, float fltXNorm, float fltYNorm, float fltZNorm)
908 {
909  //If the parent object is not set then we cannot do orientation.
910  if(!m_lpThisMI || !m_lpThisMI->Parent())
911  return;
912 
913  CStdFPoint vParentPos = m_lpThisMI->Parent()->AbsolutePosition();
914  osg::Vec3 vParent(vParentPos.x, vParentPos.y, vParentPos.z);
915 
916  osg::Vec3 vClickPos(fltXPos, fltYPos, fltZPos), vClickNormal(fltXNorm, fltYNorm, fltZNorm);
917 
918  //Lets get the bounding radius for this part
919  float fltRadius = Physics_GetBoundingRadius();
920 
921  //Now add the part at the specified position, but a radius away.
922  osg::Vec3 vWorldPos = vClickPos + (vClickNormal*fltRadius);
923 
924  //Calculate the local position relative to the parent.
925  osg::Vec3 vLocalPos = vWorldPos - vParent;
926 
927  //Now reset our position
928  m_lpThisMI->Position(vLocalPos[0], vLocalPos[1], vLocalPos[2], false, true, true);
929 }
930 
931  } // Environment
932 //} //VortexAnimatSim
933 
934 }
float m_fltNullReport
This is used to report back 0 from GetDataPointer for items that are not supported in vortex...
Definition: VsMovableItem.h:40
virtual osg::MatrixTransform * GetCameraMatrixTransform()
Gets the matrix transform used by the camera for the mouse spring.
Declares the vortex organism class.
osg::ref_ptr< osg::MatrixTransform > m_osgGeometryRotationMT
Definition: VsMovableItem.h:46
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.
Declares the vortex Light class.
Declares the vortex structure class.