Isis 3 Programmer Reference
BulletDskShape.cpp
Go to the documentation of this file.
1 
25 #include "BulletDskShape.h"
26 
27 #include <iostream>
28 #include <iomanip>
29 #include <numeric>
30 #include <sstream>
31 
32 #include "NaifDskApi.h"
33 
34 #include <QMutexLocker>
35 #include <QTime>
36 
37 #include "FileName.h"
38 #include "IException.h"
39 #include "IString.h"
40 #include "Pvl.h"
41 #include "NaifDskPlateModel.h"
42 #include "NaifStatus.h"
43 
44 using namespace std;
45 
46 namespace Isis {
47 
51  BulletDskShape::BulletDskShape() : m_mesh() { }
52 
53 
59  BulletDskShape::BulletDskShape(const QString &dskfile) : m_mesh() {
60  loadFromDsk(dskfile);
62  }
63 
64 
69  // Bullet does not clean up the mesh automatically, so we need to delete it manually
70  if (m_mesh) {
71  for (int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
72  btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[i];
73  delete[] v_mesh.m_triangleIndexBase;
74  v_mesh.m_triangleIndexBase = nullptr;
75  delete[] v_mesh.m_vertexBase;
76  v_mesh.m_vertexBase = nullptr;
77  }
78  }
79  }
80 
81 
88  size_t num_triangles = 0;
89 
90  if (m_mesh) {
91  for(int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
92  num_triangles += m_mesh->getIndexedMeshArray()[i].m_numTriangles;
93  }
94  }
95 
96  return num_triangles;
97  }
98 
99 
106  size_t num_vertices = 0;
107 
108  if (m_mesh) {
109  for(int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
110  num_vertices += m_mesh->getIndexedMeshArray()[i].m_numVertices;
111  }
112  }
113 
114  return num_vertices;
115  }
116 
117 
130  btVector3 BulletDskShape::getNormal(const int indexId, const int segment) const {
131  btMatrix3x3 triangle = getTriangle(indexId, segment);
132  btVector3 edge1 = triangle.getRow(1) - triangle.getRow(0);
133  btVector3 edge2 = triangle.getRow(2) - triangle.getRow(0);
134  return ( edge1.cross( edge2 ) );
135  }
136 
137 
147  btMatrix3x3 BulletDskShape::getTriangle(const int index, const int segment) const {
148  btAssert ( index >= 0 );
149  btAssert ( index < getIndexedMeshArray()[segment].m_numTriangles );
150 
151  btAssert ( segment >= 0 );
152  btAssert ( segment < getIndexedMeshArray().size());
153 
154  // Set up pointers to triangle indexes
155  const btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[segment];
156 
157  const int *t_index = static_cast<int32_t *> ((void *) v_mesh.m_triangleIndexBase);
158  int p_index = 3 * index;
159  int vndx0 = t_index[p_index];
160  int vndx1 = t_index[p_index+1];
161  int vndx2 = t_index[p_index+2];
162 
163  const btScalar *t_vertex = static_cast<const btScalar *> ((void *) v_mesh.m_vertexBase);
164 
165  btMatrix3x3 triangle(t_vertex[vndx0+0], t_vertex[vndx0+1], t_vertex[vndx0+2],
166  t_vertex[vndx1+0], t_vertex[vndx1+1], t_vertex[vndx1+2],
167  t_vertex[vndx2+0], t_vertex[vndx2+1], t_vertex[vndx2+2]);
168  return ( triangle );
169  }
170 
171 
179  void BulletDskShape::loadFromDsk(const QString &dskfile) {
180 
182  SpiceInt handle;
183 
184  // Sanity check
185  FileName dskFile(dskfile);
186  if ( !dskFile.fileExists() ) {
187  QString mess = "NAIF DSK file [" + dskfile + "] does not exist.";
188  throw IException(IException::User, mess, _FILEINFO_);
189  }
190 
191  // Open the NAIF Digital Shape Kernel (DSK)
192  dasopr_c( dskFile.expanded().toLatin1().data(), &handle );
194 
195  // Search to the first DLA segment
196  SpiceBoolean found;
197  SpiceDLADescr segment;
198  dlabfs_c( handle, &segment, &found );
200  if ( !found ) {
201  QString mess = "No segments found in DSK file " + dskfile ;
202  throw IException(IException::User, mess, _FILEINFO_);
203  }
204 
205  std::vector<SpiceDLADescr> segments;
206  segments.push_back(segment);
207 
208  // Iterate until you find no more segments.
209  while(found) {
210  dlafns_c(handle, &segments.back(), &segment, &found);
212  if (found)
213  segments.push_back(segment);
214  }
215 
216  // dskgd_c( v_handle, &v_dladsc, &v_dskdsc );
217  // NaifStatus::CheckErrors();
218 
219  // Now allocate a new indexed mesh to contain all the DSK data
220  m_mesh.reset( new btTriangleIndexVertexArray());
221 
222  for (size_t i = 0; i < segments.size(); i++) {
223  SpiceInt nplates;
224  SpiceInt nvertices;
225 
226  btIndexedMesh i_mesh;
227 
228  // Get size/counts
229  dskz02_c( handle, &segments[i], &nvertices, &nplates);
231 
232  m_mesh->addIndexedMesh(i_mesh, PHY_INTEGER);
233 
234  // Get internal mesh reference and set parameters appropriately
235  btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[i];
236  v_mesh.m_vertexType = PHY_DOUBLE;
237 
238  // Set and allocate data for triangle indexes
239  v_mesh.m_numTriangles = nplates;
240  v_mesh.m_triangleIndexBase = new unsigned char[nplates * 3 * sizeof(int)];
241  v_mesh.m_triangleIndexStride = (sizeof(int) * 3);
242 
243  // Set and allocate vertex data
244  v_mesh.m_numVertices = nvertices;
245  v_mesh.m_vertexBase = new unsigned char[nvertices * 3 * sizeof(double)];
246  v_mesh.m_vertexStride = (sizeof(double) * 3);
247 
248  SpiceInt n;
249  (void) dskv02_c(handle, &segments[i], 1, nvertices, &n,
250  ( SpiceDouble(*)[3] ) (v_mesh.m_vertexBase));
252 
253  // Read the indexes from the DSK
254  (void) dskp02_c(handle, &segments[i], 1, nplates, &n,
255  ( SpiceInt(*)[3] ) (v_mesh.m_triangleIndexBase));
257 
258  // Got to reset the vertex indexes to 0-based
259  int *pindex = static_cast<int *> ((void *) v_mesh.m_triangleIndexBase);
260  int nverts = nplates * 3;
261  for (int i = 0 ; i < nverts ; i++) {
262  pindex[i] -= 1;
263  btAssert ( pindex[i] >= 0 );
264  btAssert ( pindex[i] < nvertices );
265  }
266  }
267 
268  // Close DSK
269  dascls_c(handle);
270 
271  bool useQuantizedAabbCompression = true;
272  // bool useQuantizedAabbCompression = false;
273  btBvhTriangleMeshShape *v_triShape = new btBvhTriangleMeshShape(m_mesh.data(),
274  useQuantizedAabbCompression);
275  v_triShape->setUserPointer(this);
276  btCollisionObject *vbody = new btCollisionObject();
277  vbody->setCollisionShape(v_triShape);
278  setTargetBody(vbody);
279 
280  return;
281 
282  }
283 
284 } // namespace Isis
File name manipulation and expansion.
Definition: FileName.h:116
virtual btVector3 getNormal(const int indexId, const int segment=0) const
Return normal for a given triangle index.
Namespace for the standard library.
void setMaximumDistance()
Calculate and save the maximum distance across the body.
void setTargetBody(btCollisionObject *body)
Set the Bullet shape object to this object instance.
virtual btMatrix3x3 getTriangle(const int index, const int segment=0) const
Get the vertices of a triangle in the mesh.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:43
Isis exception class.
Definition: IException.h:107
int getNumTriangles() const
Return the number of triangles in the shape.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
BulletDskShape()
Default empty constructor.
virtual ~BulletDskShape()
Desctructor.
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:465
int getNumVertices() const
Return the number of verticies in the shape.
void loadFromDsk(const QString &dskfile)
! Triangular mesh representation of the target shape.