AnimatLab  2
Test
VsMeshBase.cpp
1 // VsMeshBase.cpp: implementation of the VsMeshBase class.
2 //
4 
5 #include "StdAfx.h"
6 #include "VsMovableItem.h"
7 #include "VsBody.h"
8 #include "VsJoint.h"
9 #include "VsMotorizedJoint.h"
10 #include "VsRigidBody.h"
11 #include "VsMeshBase.h"
12 #include "VsSimulator.h"
13 #include "VsDragger.h"
14 #include "VsOsgUserDataVisitor.h"
15 
16 namespace VortexAnimatSim
17 {
18  namespace Environment
19  {
20  namespace Bodies
21  {
22 
24 // Construction/Destruction
26 
27 VsMeshBase::VsMeshBase()
28 {
29 }
30 
31 VsMeshBase::~VsMeshBase()
32 {
33 
34 try
35 {
36 }
37 catch(...)
38 {Std_TraceMsg(0, "Caught Error in desctructor of VsMeshBase\r\n", "", -1, false, true);}
39 }
40 
41 void VsMeshBase::SetThisPointers()
42 {
43  VsRigidBody::SetThisPointers();
44  m_lpThisMesh = dynamic_cast<Mesh *>(this);
45  if(!m_lpThisMesh)
46  THROW_TEXT_ERROR(Vs_Err_lThisPointerNotDefined, Vs_Err_strThisPointerNotDefined, "m_lpThisMesh, " + m_lpThisAB->Name());
47 }
48 
49 void VsMeshBase::CreateGraphicsGeometry()
50 {
51  m_osgGeometry = CreateBoxGeometry(1, 1, 1, 1, 1, 1);
52 }
53 
54 void VsMeshBase::LoadMeshNode()
55 {
56  std::string strPath = m_lpThisAB->GetSimulator()->ProjectPath();
57  std::string strMeshFile;
58 
59  if(m_lpThisRB->IsCollisionObject() && m_lpThisMesh->CollisionMeshType() == "CONVEX")
60  strMeshFile = m_lpThisMesh->ConvexMeshFile();
61  else
62  strMeshFile = m_lpThisMesh->MeshFile();
63 
64  std::string strFile = AnimatSim::GetFilePath(strPath, strMeshFile);
65  m_osgBaseMeshNode = GetVsSimulator()->MeshMgr()->LoadMesh(strFile);
66 
67  if(!m_osgBaseMeshNode.valid())
68  CreateDefaultMesh();
69 
70  m_osgBaseMeshNode->setName(m_lpThisAB->Name() + "_MeshNodeBase");
71 
72  //Enforce turning on of lighting for this object. Some meshes have this turned off by default (3DS in particular)
73  //This did not fix the problem.
74  //m_osgBaseMeshNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON );
75 
76  CStdFPoint vScale(1, 1, 1);
77 
78  //If this is a convex collision object then it does not get scaled here. That is done
79  //when it is converted into a collision mesh by the editor. Otherwise use the scaling.
80  if( !(m_lpThisMesh->IsCollisionObject() && m_lpThisMesh->CollisionMeshType() == "CONVEX") )
81  vScale= m_lpThisMesh->Scale();
82 
83  osg::Matrix osgScaleMatrix = osg::Matrix::identity();
84  osgScaleMatrix.makeScale(vScale.x, vScale.y, vScale.z);
85 
86  m_osgMeshNode = new osg::MatrixTransform(osgScaleMatrix);
87 
88  m_osgMeshNode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
89 
90  m_osgMeshNode->addChild(m_osgBaseMeshNode.get());
91  m_osgMeshNode->setName(m_lpThisAB->Name() + "_MeshNode");
92 }
93 
94 void VsMeshBase::CreateDefaultMesh()
95 {
96  CreateGraphicsGeometry();
97  m_osgGeometry->setName(m_lpThisAB->Name() + "_Geometry");
98 
99  osg::Geode *osgGroup = new osg::Geode;
100  osgGroup->addDrawable(m_osgGeometry.get());
101 
102  m_osgBaseMeshNode = osgGroup;
103 }
104 
105 void VsMeshBase::CreateGeometry()
106 {
107  LoadMeshNode();
108 
109  //For the mesh stuff we need to create it immediately after the mesh is loaded, and before we add it to
110  //the matrix transforms. This is because when vortex creates the collision geometry it was using the attached
111  //matrix transform when setting up the vertex positions and this was causing the mesh to appear in the wrong
112  //position relative to the collision mesh
113  CreatePhysicsGeometry();
114 
115  //Now add it to the nodes.
116  osg::Group *osgNodeGroup = NULL;
117  if(m_osgNode.valid())
118  osgNodeGroup = dynamic_cast<osg::Group *>(m_osgNode.get());
119  else
120  {
121  osgNodeGroup = new osg::Group;
122  m_osgNode = osgNodeGroup;
123  }
124 
125  if(!osgNodeGroup)
126  THROW_TEXT_ERROR(Vs_Err_lMeshOsgNodeGroupNotDefined, Vs_Err_strMeshOsgNodeGroupNotDefined, "Body: " + m_lpThisAB->Name() + " Mesh: " + AnimatSim::GetFilePath(m_lpThisAB->GetSimulator()->ProjectPath(), m_lpThisMesh->MeshFile()));
127 
128  osgNodeGroup->addChild(m_osgMeshNode.get());
129 }
130 
131 void VsMeshBase::CalculateEstimatedMassAndVolume()
132 {
133  if(m_lpThisRB)
134  {
135  AnimatSim::BoundingBox bb = m_lpThisRB->GetBoundingBox();
136 
137  float fltVolume = (bb.Width() * bb.Height() * bb.Length());
138  m_fltEstimatedVolume = fltVolume*pow(m_lpThisRB->GetSimulator()->DistanceUnits(), (float) 3.0);
139  m_fltEstimatedMass = (m_lpThisRB->Density() * fltVolume) * m_lpThisRB->GetSimulator()->DisplayMassUnits();
140  }
141 }
142 
143 void VsMeshBase::CreatePhysicsGeometry()
144 {
145  if(m_lpThisRB->IsCollisionObject())
146  {
147  if(m_lpThisMesh->CollisionMeshType() == "CONVEX")
148  m_vxGeometry = GetVsSimulator()->CreateConvexMeshFromOsg(m_osgMeshNode.get());
149  else
150  m_vxGeometry = GetVsSimulator()->CreatTriangleMeshFromOsg(m_osgMeshNode.get());
151 
152  if(!m_vxGeometry)
153  THROW_TEXT_ERROR(Vs_Err_lCreatingGeometry, Vs_Err_strCreatingGeometry, "Body: " + m_lpThisAB->Name() + " Mesh: " + AnimatSim::GetFilePath(m_lpThisAB->GetSimulator()->ProjectPath(), m_lpThisMesh->MeshFile()));
154  }
155 
156  CalculateEstimatedMassAndVolume();
157 }
158 
159 
160 void VsMeshBase::ResizePhysicsGeometry()
161 {
162  if(m_vxGeometry && m_vxCollisionGeometry && m_vxSensor)
163  {
164  if(!m_vxSensor->removeCollisionGeometry(m_vxCollisionGeometry))
165  THROW_PARAM_ERROR(Vs_Err_lRemovingCollisionGeometry, Vs_Err_strRemovingCollisionGeometry, "ID: ", m_lpThisAB->ID());
166 
167  delete m_vxCollisionGeometry;
168  m_vxCollisionGeometry = NULL;
169 
170  int iMaterialID = m_lpThisAB->GetSimulator()->GetMaterialID(m_lpThisRB->MaterialID());
171  CollisionGeometry(m_vxSensor->addGeometry(m_vxGeometry, iMaterialID, 0, m_lpThisRB->Density()));
172 
173  CalculateEstimatedMassAndVolume();
174  }
175 }
176 
177 void VsMeshBase::Physics_Resize()
178 {
179  //First lets get rid of the current current geometry and then put new geometry in place.
180  if(m_osgNode.valid() && m_osgMeshNode.valid())
181  {
182  osg::Group *osgGroup = dynamic_cast<osg::Group *>(m_osgNode.get());
183 
184  if(osgGroup && osgGroup->containsNode(m_osgMeshNode.get()))
185  osgGroup->removeChild(m_osgMeshNode.get());
186 
187  m_osgGeometry.release();
188  m_osgMeshNode.release();
189  m_osgBaseMeshNode.release();
190 
191  //Create a new box geometry with the new sizes.
192  CreateGeometry();
193 
194  //Now lets re-adjust the gripper size.
195  if(m_osgDragger.valid())
196  m_osgDragger->SetupMatrix();
197 
198  //Reset the user data for the new parts.
199  if(m_osgNodeGroup.valid())
200  {
201  osg::ref_ptr<VsOsgUserDataVisitor> osgVisitor = new VsOsgUserDataVisitor(this);
202  osgVisitor->traverse(*m_osgNodeGroup);
203  }
204  }
205 
206  if(m_vxGeometry)
207  {
208  ResizePhysicsGeometry();
209 
210  //We need to reset the density in order for it to recompute the mass and volume.
211  Physics_SetDensity(m_lpThisRB->Density());
212 
213  //Now get base values, including mass and volume
214  GetBaseValues();
215  }
216 }
217 
218 
219  } //Bodies
220  } // Environment
221 } //VortexAnimatSim
float m_fltEstimatedVolume
The estimated volume. See m_fltEstimatedMass desciption.
Definition: VsRigidBody.h:92
float Width()
Gets the width = (Max.z - Min.z).
Definition: BoundingBox.cpp:51
float Length()
Gets the length = (Max.x - Min.x).
Definition: BoundingBox.cpp:46
Bounding box class for geometric objects.
Definition: BoundingBox.h:17
float Height()
Gets the height = (Max.y - Min.y).
Definition: BoundingBox.cpp:56
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
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.