NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgHillyGround.cpp
Go to the documentation of this file.
1 
26 //This Module
27 #include "tgHillyGround.h"
28 
29 //Bullet Physics
30 #include "BulletCollision/CollisionShapes/btBoxShape.h"
31 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
32 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
33 #include "BulletDynamics/Dynamics/btRigidBody.h"
34 #include "LinearMath/btDefaultMotionState.h"
35 #include "LinearMath/btTransform.h"
36 
37 // The C++ Standard Library
38 #include <cassert>
39 #include <iostream>
40 
41 tgHillyGround::Config::Config(btVector3 eulerAngles,
42  double friction,
43  double restitution,
44  btVector3 size,
45  btVector3 origin,
46  std::size_t nx,
47  std::size_t ny,
48  double margin,
49  double triangleSize,
50  double waveHeight,
51  double offset) :
52  m_eulerAngles(eulerAngles),
53  m_friction(friction),
54  m_restitution(restitution),
55  m_size(size),
56  m_origin(origin),
57  m_nx(nx),
58  m_ny(ny),
59  m_margin(margin),
60  m_triangleSize(triangleSize),
61  m_waveHeight(waveHeight),
62  m_offset(offset)
63 {
64  assert((m_friction >= 0.0) && (m_friction <= 1.0));
65  assert((m_restitution >= 0.0) && (m_restitution <= 1.0));
66  assert((m_size[0] >= 0.0) && (m_size[1] >= 0.0) && (m_size[2] >= 0.0));
67  assert(m_nx > 0);
68  assert(m_ny > 0);
69  assert(m_margin >= 0.0);
70  assert(m_triangleSize >= 0.0);
71  assert(m_waveHeight >= 0.0);
72  assert(m_offset >= 0.0);
73 }
74 
76  m_config(Config())
77 {
78  // @todo make constructor aux to avoid repeated code
79  pGroundShape = hillyCollisionShape();
80 }
81 
83  m_config(config)
84 {
85  pGroundShape = hillyCollisionShape();
86 }
87 
89 {
90  delete m_pMesh;
91  delete[] m_pIndices;
92  delete[] m_vertices;
93 }
94 
96 {
97  std::cout << "Hilly ground " << std::endl;
98  const btScalar mass = 0.0;
99 
100  btTransform groundTransform;
101  groundTransform.setIdentity();
102  groundTransform.setOrigin(m_config.m_origin);
103 
104  btQuaternion orientation;
105  orientation.setEuler(m_config.m_eulerAngles[0], // Yaw
106  m_config.m_eulerAngles[1], // Pitch
107  m_config.m_eulerAngles[2]); // Roll
108  groundTransform.setRotation(orientation);
109 
110  // Using motionstate is recommended
111  // It provides interpolation capabilities, and only synchronizes 'active' objects
112  btDefaultMotionState* const pMotionState =
113  new btDefaultMotionState(groundTransform);
114 
115  const btVector3 localInertia(0, 0, 0);
116 
117  btRigidBody::btRigidBodyConstructionInfo const rbInfo(mass, pMotionState, pGroundShape, localInertia);
118 
119  btRigidBody* const pGroundBody = new btRigidBody(rbInfo);
120 
121  assert(pGroundBody);
122  return pGroundBody;
123 }
124 
126  btCollisionShape * pShape = 0;
127  // The number of vertices in the mesh
128  // Hill Paramenters: Subject to Change
129  const std::size_t vertexCount = m_config.m_nx * m_config.m_ny;
130 
131  if (vertexCount > 0) {
132  // The number of triangles in the mesh
133  const std::size_t triangleCount = 2 * (m_config.m_nx - 1) * (m_config.m_ny - 1);
134 
135  // A flattened array of all vertices in the mesh
136  m_vertices = new btVector3[vertexCount];
137 
138  // Supplied by the derived class
139  setVertices(m_vertices);
140  // A flattened array of indices for each corner of each triangle
141  m_pIndices = new int[triangleCount * 3];
142 
143  // Supplied by the derived class
144  setIndices(m_pIndices);
145 
146  // Create the mesh object
147  m_pMesh = createMesh(triangleCount, m_pIndices, vertexCount, m_vertices);
148 
149  // Create the shape object
150  pShape = createShape(m_pMesh);
151 
152  // Set the margin
153  pShape->setMargin(m_config.m_margin);
154  // DO NOT deallocate vertices, indices or pMesh until simulation is over!
155  // The shape owns them, but will not delete them
156  }
157 
158  assert(pShape);
159  return pShape;
160 }
161 
162 btTriangleIndexVertexArray *tgHillyGround::createMesh(std::size_t triangleCount, int indices[], std::size_t vertexCount, btVector3 vertices[]) {
163  const int vertexStride = sizeof(btVector3);
164  const int indexStride = 3 * sizeof(int);
165 
166  btTriangleIndexVertexArray* const pMesh =
167  new btTriangleIndexVertexArray(triangleCount,
168  indices,
169  indexStride,
170  vertexCount,
171  (btScalar*) &vertices[0].x(),
172  vertexStride);
173  return pMesh;
174 }
175 
176 btCollisionShape *tgHillyGround::createShape(btTriangleIndexVertexArray *pMesh) {
177  const bool useQuantizedAabbCompression = true;
178  btCollisionShape *const pShape =
179  new btBvhTriangleMeshShape(pMesh, useQuantizedAabbCompression);
180  return pShape;
181 }
182 
183 void tgHillyGround::setVertices(btVector3 vertices[]) {
184  for (std::size_t i = 0; i < m_config.m_nx; i++)
185  {
186  for (std::size_t j = 0; j < m_config.m_ny; j++)
187  {
188  const btScalar x = (i - (m_config.m_nx * 0.5)) * m_config.m_triangleSize;
189  const btScalar y = (m_config.m_waveHeight * sin((double)i) * cos((double)j) +
190  m_config.m_offset);
191  const btScalar z = (j - (m_config.m_ny * 0.5)) * m_config.m_triangleSize;
192  vertices[i + (j * m_config.m_nx)].setValue(x, y, z);
193  }
194  }
195 }
196 
197 void tgHillyGround::setIndices(int indices[]) {
198  int index = 0;
199  for (std::size_t i = 0; i < m_config.m_nx - 1; i++)
200  {
201  for (std::size_t j = 0; j < m_config.m_ny - 1; j++)
202  {
203  indices[index++] = (j * m_config.m_nx) + i;
204  indices[index++] = (j * m_config.m_nx) + i + 1;
205  indices[index++] = ((j + 1) * m_config.m_nx) + i + 1;
206 
207  indices[index++] = (j * m_config.m_nx) + i;
208  indices[index++] = ((j + 1) * m_config.m_nx) + i + 1;
209  indices[index++] = ((j + 1) * m_config.m_nx) + i;
210  }
211  }
212 }
213 
virtual ~tgHillyGround()
Contains the definition of class tgHillyGround.
virtual btRigidBody * getGroundRigidBody() const
btCollisionShape * hillyCollisionShape()