AnimatLab  2
Test
OsgDragger.cpp
1 #include "StdAfx.h"
2 
3 #include "OsgMovableItem.h"
4 #include "OsgBody.h"
5 #include "OsgRigidBody.h"
6 #include "OsgJoint.h"
7 #include "OsgStructure.h"
8 #include "OsgUserData.h"
9 #include "OsgDragger.h"
10 #include "OsgTrackballDragger.h"
11 #include "OsgTranslateAxisDragger.h"
12 #include "OsgSimulator.h"
13 
14 namespace OsgAnimatSim
15 {
16  namespace Visualization
17  {
18 
19 OsgDragger::OsgDragger(OsgMovableItem *lpParent, bool bAllowTranslateX, bool bAllowTranslateY, bool bAllowTranslateZ,
20  bool bAllowRotateX, bool bAllowRotateY, bool bAllowRotateZ, float fltUserDefinedRadius)
21 {
22  if(!lpParent)
23  THROW_ERROR(Al_Err_lParentNotDefined, Al_Err_strParentNotDefined);
24 
25  if(fltUserDefinedRadius <= 0)
26  m_fltUserDefinedRadius = -1;
27  else
28  m_fltUserDefinedRadius = fltUserDefinedRadius;
29 
30  m_lpVsParent = lpParent;
31 
32  //Create the gripperMT and default it to loc=0, rot=0
33  m_osgGripperMT = new osg::MatrixTransform();
34  osg::Matrix osgMT; osgMT.makeIdentity();
35  m_osgGripperMT->setMatrix(osgMT);
36  m_osgGripperMT->addChild(this);
37 
38  //_autoTransform = new osg::AutoTransform;
39  //_autoTransform->setAutoScaleToScreen(true);
40  //addChild(_autoTransform.get());
41 
42  //_sizeTransform = new osg::MatrixTransform;
44  //_sizeTransform->setMatrix(osg::Matrix::scale(100, 100, 100));
45  //_autoTransform->addChild(_sizeTransform.get());
46 
47  _tbDragger = new OsgTrackballDragger(bAllowRotateX, bAllowRotateY, bAllowRotateZ);
48  _tbDragger->setName("TrackballDragger");
49  addChild(_tbDragger.get());
50  //_sizeTransform->addChild(_tbDragger.get());
51 
52  _transDragger = new OsgTranslateAxisDragger(bAllowTranslateX, bAllowTranslateY, bAllowTranslateZ);
53  _transDragger->setName("TranslateAxisDragger");
54  addChild(_transDragger.get());
55  //_sizeTransform->addChild(_transDragger.get());
56 
57  this->addDragger(_tbDragger.get());
58  this->addDragger(_transDragger.get());
59  this->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
60  this->setParentDragger(getParentDragger());
61 }
62 
63 OsgDragger::~OsgDragger(void)
64 {
65 }
66 
67 
69 {
70  _tbDragger->setupDefaultGeometry();
71  _transDragger->setupDefaultGeometry();
72 
73  SetupMatrix();
74 }
75 
76 void OsgDragger::AddToScene()
77 {
78  SetupMatrix();
79  if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
80  if(!m_lpVsParent->RootGroup()->containsNode(m_osgGripperMT.get()))
81  m_lpVsParent->RootGroup()->addChild(m_osgGripperMT.get());
82 }
83 
84 void OsgDragger::RemoveFromScene()
85 {
86  if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
87  if(m_lpVsParent->RootGroup()->containsNode(m_osgGripperMT.get()))
88  m_lpVsParent->RootGroup()->removeChild(m_osgGripperMT.get());
89 }
90 
91 bool OsgDragger::IsInScene()
92 {
93  if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
94  if(m_lpVsParent->RootGroup()->containsNode(m_osgGripperMT.get()))
95  return true;
96 
97  return false;
98 }
99 
100 void OsgDragger::SetupMatrix()
101 {
102  if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
103  {
104  //This gives the radius of the boundign sphere for the selected part.
105  //We will multiply that by 2 and then scale the entire dragger by that amount.
106  //We will also use that setting for the minimum scale of the autotransform.
107  float fltMaxDim = m_lpVsParent->Physics_GetBoundingRadius();
108 
109  Simulator *lpSim = GetSimulator();
110  if(fltMaxDim > (lpSim->InverseDistanceUnits()/2.0f))
111  fltMaxDim = (lpSim->InverseDistanceUnits()/2.0f);
112 
113  //Use an equation to calculate the radius here. This seemed to work best.
114  //I tried several size values and found a good radius scale that fit it. Then
115  //I did a regression to find this equation of the line for the radius.
116  float fltRadius;
117 
118  if(m_fltUserDefinedRadius > 0)
119  fltRadius = m_fltUserDefinedRadius;
120  else
121  fltRadius = fltMaxDim*0.501794454f + fltMaxDim;
122 
123  //We are dividing the number by 100 because we are using a _sizeTransform that scales it up by 100.
124  //_autoTransform->setMinimumScale( (fltRadius*0.01f) );
125 
126  //We use the final matrix here instead of local matrix because the joint can have an additional offset that
127  //must be taken into account when setting up the dragger.
128  m_osgGripperMT->setMatrix(m_lpVsParent->FinalMatrix());
129 
130  //Set the matrix for the dragger back to default.
131  osg::Matrix mtNull = osg::Matrix::identity();
132  mtNull *= osg::Matrix::scale(fltRadius,fltRadius,fltRadius);
133  this->setMatrix(mtNull);
134 
135  //Lets setup the grip to zero out the rotation of the body so that it points
136  //to the default axis of the parent it is connected to.
137  osg::Matrix tempMT = m_lpVsParent->LocalMatrix(), invMT;
138  tempMT.setTrans(osg::Vec3f(0, 0, 0));
139  invMT.invert(tempMT);
140 
141  //We want to scale the translate axis to be 1.5 times as big as the rotate axis dragger.
142  // Scale the translate dragger up a bit, otherwise the axes
143  // will be in the trackball dragger's sphere and we won't be
144  // able to pick them.
145  float axesScale = 1.5;
146  invMT = invMT * osg::Matrix::scale(axesScale,axesScale,axesScale);
147 
148  _transDragger->setMatrix(invMT);
149  }
150 }
151 
152  }// end Visualization
153 }// end OsgAnimatSim
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
Declares the vortex structure class.