AnimatLab  2
Test
BlTerrain.cpp
1 // BlTerrain.cpp: implementation of the BlTerrain class.
2 //
4 
5 #include "StdAfx.h"
6 #include "BlOsgGeometry.h"
7 #include "BlJoint.h"
8 #include "BlMotorizedJoint.h"
9 #include "BlRigidBody.h"
10 #include "BlMeshBase.h"
11 #include "BlTerrain.h"
12 #include "BlSimulator.h"
13 
14 namespace BulletAnimatSim
15 {
16  namespace Environment
17  {
18  namespace Bodies
19  {
20 
22 // Construction/Destruction
24 
25 BlTerrain::BlTerrain()
26 {
27  SetThisPointers();
28  m_bCullBackfaces = true; //we want back face culling on by default for Terrains.
29  m_osgHeightField = NULL;
30  m_btMotionState = NULL;
33  m_fltTerrainHeightAdjust = 0;
34  m_aryHeightData = NULL;
35 }
36 
37 BlTerrain::~BlTerrain()
38 {
39  try
40  {
41  DeleteGraphics();
42  DeletePhysics(false);
43  }
44  catch(...)
45  {Std_TraceMsg(0, "Caught Error in desctructor of BlTerrain/\r\n", "", -1, false, true);}
46 }
47 
48 void BlTerrain::CreateGraphicsGeometry()
49 {
50  m_osgGeometry = CreatePlaneGeometry(-1, -1, 2, 2, 2, 2, false);
51 }
52 
53 void BlTerrain::SetTexture(std::string strTexture)
54 {
55  if(m_osgMeshNode.valid())
56  {
57  if(!Std_IsBlank(strTexture))
58  {
59  std::string strFile = AnimatSim::GetFilePath(m_lpThisAB->GetSimulator()->ProjectPath(), strTexture);
60  osg::ref_ptr<osg::Image> image = osgDB::readImageFile(strFile);
61  if(!image)
62  THROW_PARAM_ERROR(Bl_Err_lTextureLoad, Bl_Err_strTextureLoad, "Image File", strFile);
63 
64  osg::StateSet* state = m_osgMeshNode->getOrCreateStateSet();
65  m_osgTexture = new osg::Texture2D(image.get());
66  m_osgTexture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
67 
68  m_osgTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_LINEAR);
69  m_osgTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
70  m_osgTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
71  m_osgTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
72 
73  osg::Matrixd matrix;
74  matrix.makeScale(osg::Vec3(m_iTextureLengthSegments, m_iTextureWidthSegments, 1.0));
75 
76  osg::ref_ptr<osg::TexMat> matTexture = new osg::TexMat;
77  matTexture->setMatrix(matrix);
78 
79  state->setTextureAttributeAndModes(0, m_osgTexture.get());
80  state->setTextureAttributeAndModes(0, matTexture.get(), osg::StateAttribute::ON);
81 
82  state->setTextureMode(0, m_eTextureMode, osg::StateAttribute::ON);
83  state->setMode(GL_BLEND,osg::StateAttribute::ON);
84 
85  //state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
86  }
87  else if(m_osgTexture.valid()) //If we have already set it and we are clearing it then reset the state
88  {
89  m_osgTexture.release();
90  osg::StateSet* state = m_osgMeshNode->getOrCreateStateSet();
91  state->setTextureAttributeAndModes(0, NULL);
92  state->setTextureMode(0, m_eTextureMode, osg::StateAttribute::OFF);
93  }
94  }
95 }
96 
97 //Terrains can never have fluid interactions/dynamics.
98 void BlTerrain::Physics_FluidDataChanged()
99 {}
100 
101 void BlTerrain::LoadMeshNode()
102 {
103  std::string strPath = m_lpThisAB->GetSimulator()->ProjectPath();
104  std::string strMeshFile = m_lpThisMesh->MeshFile();
105  std::string strFile = AnimatSim::GetFilePath(strPath, strMeshFile);
106 
107  //Get the terrain node loaded in.
108  m_osgBaseMeshNode = CreateHeightField(strFile, m_fltSegmentWidth, m_fltSegmentLength, m_fltMaxHeight, &m_osgHeightField, true);
109 
110  osg::Matrix osgScaleMatrix = osg::Matrix::identity();
111  //Not sure why, but the osg terrain and the bullet terrain are off by a half segment length in registration. So I am moving the
112  //graphics over by a bit to compensate so they are correctly registered.
113  osgScaleMatrix = osgScaleMatrix.translate((m_fltSegmentWidth/2), (m_fltSegmentLength/2), 0);
114  m_osgMeshNode = new osg::MatrixTransform(osgScaleMatrix);
115 
116  m_osgMeshNode->addChild(m_osgBaseMeshNode.get());
117  m_osgMeshNode->setName(m_lpThisAB->Name() + "_MeshNode");
118 
119  SetTexture(m_lpThisRB->Texture());
120 }
121 
122 void BlTerrain::CreatePhysicsGeometry()
123 {
124  if(m_osgHeightField)
125  {
126  DeleteCollisionGeometry();
127 
128  //Mass of a terrain is always zero because it is always static.
129  m_fltMass = 0;
130  m_btHeightField = CreateBtHeightField(m_osgHeightField, m_fltSegmentWidth, m_fltSegmentLength, m_fltMinTerrainHeight, m_fltMaxTerrainHeight, &m_aryHeightData);
131  m_fltTerrainHeightAdjust = (m_fltMaxTerrainHeight - m_fltMinTerrainHeight)/2.0 + m_fltMinTerrainHeight;
132  m_eBodyType = TERRAIN_SHAPE_PROXYTYPE;
133  m_btCollisionShape = m_btHeightField;
134  }
135 
136  m_eControlType = DynamicsControlType::ControlNode; //This is not a dynamic part.
137 
138  if(!m_btHeightField)
139  THROW_TEXT_ERROR(Bl_Err_lCreatingGeometry, Bl_Err_strCreatingGeometry, "Body: " + m_lpThisAB->Name() + " Mesh: " + AnimatSim::GetFilePath(m_lpThisAB->GetSimulator()->ProjectPath(), m_lpThisMesh->MeshFile()));
140 }
141 
143 {
144  CreateGeometry();
145 
146  BlMeshBase::CreateItem();
147  Terrain::CreateParts();
148 }
149 
151 {
154 
155  Terrain::CreateJoints();
156  BlMeshBase::Initialize();
157 }
158 
159 void BlTerrain::CreateDynamicPart()
160 {
161  BlSimulator *lpSim = GetBlSimulator();
162 
163  if(lpSim && m_lpThisRB && m_lpThisAB && m_btCollisionShape && m_lpMaterial)
164  {
165  btScalar mass( m_lpThisRB->GetMassValueWithStaticChildren() );
166  btVector3 localInertia( 0, 0, 0 );
167  const bool isDynamic = ( mass != 0.f );
168  if( isDynamic )
169  m_btCollisionShape->calculateLocalInertia( mass, localInertia );
170 
171  //Keep a copy of the matrix transform for osgMT so I can reset it back later
172  osg::Vec3d vPos = m_osgMT->getMatrix().getTrans();
173 
174  btTransform tr;
175  tr.setIdentity();
176  tr.setOrigin(btVector3(vPos[0], vPos[1], vPos[2]));
177  m_btMotionState = new btDefaultMotionState(tr);
178 
179  // Finally, create rigid body.
180  btRigidBody::btRigidBodyConstructionInfo rbInfo( mass, m_btMotionState, m_btCollisionShape, localInertia );
181  rbInfo.m_friction = m_lpMaterial->FrictionLinearPrimary();
182  rbInfo.m_rollingFriction = m_lpMaterial->FrictionAngularPrimaryConverted();
183  rbInfo.m_restitution = m_lpMaterial->Restitution();
184  rbInfo.m_linearDamping = m_lpThisRB->LinearVelocityDamping();
185  rbInfo.m_angularDamping = m_lpThisRB->AngularVelocityDamping();
186 
187  m_btPart = new btRigidBody( rbInfo );
188  m_btPart->setUserPointer((void *) m_lpThisRB);
189  m_btPart->setContactProcessingThreshold(10000);
190 
191  if(!m_lpBulletData)
192  m_lpBulletData = new BlBulletData(this, false);
193 
194  m_btPart->setUserPointer((void *) m_lpBulletData);
195  m_btPart->setActivationState(0);
196 
197  lpSim->DynamicsWorld()->addRigidBody( m_btPart, AnimatCollisionTypes::RIGID_BODY, ALL_COLLISIONS );
198 
199  GetBaseValues();
200  }
201 }
202 
203 void BlTerrain::DeleteDynamicPart()
204 {
205  if(m_btMotionState)
206  {delete m_btMotionState; m_btMotionState = NULL;}
207 
208  if(m_aryHeightData)
209  {
210  delete m_aryHeightData;
211  m_aryHeightData = NULL;
212  }
213 
214  BlRigidBody::DeleteDynamicPart();
215 }
216 
217  } //Bodies
218  } // Environment
219 } //BulletAnimatSim
virtual float FrictionAngularPrimaryConverted()
Gets the angular primary friction coefficient converted to match vortex values.
btScalar * m_aryHeightData
The array of height data used by the btHeightfieldTerrainShape.
Definition: BlTerrain.h:31
float m_fltMass
The mass of the object.
Definition: RigidBody.h:85
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
virtual void CreateJoint()
Creates the joint.
Definition: Joint.cpp:602
float m_fltMaxTerrainHeight
The maximum height returned by the CreateHeightField method.
Definition: BlTerrain.h:24
float m_fltMinTerrainHeight
The minimum height returned by the CreateHeightField method.
Definition: BlTerrain.h:21
virtual void CreateParts()
Allows the rigid body to create its parts using the chosen physics engine.
Definition: BlTerrain.cpp:142
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
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.
btDefaultMotionState * m_btMotionState
Standard bullet motion state pointer.
Definition: BlTerrain.h:18
virtual void CreateJoints()
Allows the rigid body to create its joints using the chosen physics engine.
Definition: BlTerrain.cpp:150