Isis 3 Programmer Reference
BulletDskShape.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 
8 #include "BulletDskShape.h"
9 
10 #include <iostream>
11 #include <iomanip>
12 #include <numeric>
13 #include <sstream>
14 
15 #include "NaifDskApi.h"
16 
17 #include <QMutexLocker>
18 #include <QTime>
19 
20 #include "FileName.h"
21 #include "IException.h"
22 #include "IString.h"
23 #include "Pvl.h"
24 #include "NaifDskPlateModel.h"
25 #include "NaifStatus.h"
26 
27 using namespace std;
28 
29 namespace Isis {
30 
34  BulletDskShape::BulletDskShape() : m_mesh() { }
35 
36 
42  BulletDskShape::BulletDskShape(const QString &dskfile) : m_mesh() {
43  loadFromDsk(dskfile);
45  }
46 
47 
52  // Bullet does not clean up the mesh automatically, so we need to delete it manually
53  if (m_mesh) {
54  for (int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
55  btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[i];
56  delete[] v_mesh.m_triangleIndexBase;
57  v_mesh.m_triangleIndexBase = nullptr;
58  delete[] v_mesh.m_vertexBase;
59  v_mesh.m_vertexBase = nullptr;
60  }
61  }
62  }
63 
64 
71  size_t num_triangles = 0;
72 
73  if (m_mesh) {
74  for(int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
75  num_triangles += m_mesh->getIndexedMeshArray()[i].m_numTriangles;
76  }
77  }
78 
79  return num_triangles;
80  }
81 
82 
89  size_t num_vertices = 0;
90 
91  if (m_mesh) {
92  for(int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
93  num_vertices += m_mesh->getIndexedMeshArray()[i].m_numVertices;
94  }
95  }
96 
97  return num_vertices;
98  }
99 
100 
113  btVector3 BulletDskShape::getNormal(const int indexId, const int segment) const {
114  btMatrix3x3 triangle = getTriangle(indexId, segment);
115  btVector3 edge1 = triangle.getRow(1) - triangle.getRow(0);
116  btVector3 edge2 = triangle.getRow(2) - triangle.getRow(0);
117  return ( edge1.cross( edge2 ) );
118  }
119 
120 
130  btMatrix3x3 BulletDskShape::getTriangle(const int index, const int segment) const {
131  btAssert ( index >= 0 );
132  btAssert ( index < getIndexedMeshArray()[segment].m_numTriangles );
133 
134  btAssert ( segment >= 0 );
135  btAssert ( segment < getIndexedMeshArray().size());
136 
137  // Set up pointers to triangle indexes
138  const btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[segment];
139 
140  const int *t_index = static_cast<int32_t *> ((void *) v_mesh.m_triangleIndexBase);
141  int p_index = 3 * index;
142  int vndx0 = t_index[p_index];
143  int vndx1 = t_index[p_index+1];
144  int vndx2 = t_index[p_index+2];
145 
146  const btScalar *t_vertex = static_cast<const btScalar *> ((void *) v_mesh.m_vertexBase);
147 
148  btMatrix3x3 triangle(t_vertex[vndx0+0], t_vertex[vndx0+1], t_vertex[vndx0+2],
149  t_vertex[vndx1+0], t_vertex[vndx1+1], t_vertex[vndx1+2],
150  t_vertex[vndx2+0], t_vertex[vndx2+1], t_vertex[vndx2+2]);
151  return ( triangle );
152  }
153 
154 
162  void BulletDskShape::loadFromDsk(const QString &dskfile) {
163 
165  SpiceInt handle;
166 
167  // Sanity check
168  FileName dskFile(dskfile);
169  if ( !dskFile.fileExists() ) {
170  QString mess = "NAIF DSK file [" + dskfile + "] does not exist.";
171  throw IException(IException::User, mess, _FILEINFO_);
172  }
173 
174  // Open the NAIF Digital Shape Kernel (DSK)
175  dasopr_c( dskFile.expanded().toLatin1().data(), &handle );
177 
178  // Search to the first DLA segment
179  SpiceBoolean found;
180  SpiceDLADescr segment;
181  dlabfs_c( handle, &segment, &found );
183  if ( !found ) {
184  QString mess = "No segments found in DSK file " + dskfile ;
185  throw IException(IException::User, mess, _FILEINFO_);
186  }
187 
188  std::vector<SpiceDLADescr> segments;
189  segments.push_back(segment);
190 
191  // Iterate until you find no more segments.
192  while(found) {
193  dlafns_c(handle, &segments.back(), &segment, &found);
195  if (found)
196  segments.push_back(segment);
197  }
198 
199  // dskgd_c( v_handle, &v_dladsc, &v_dskdsc );
200  // NaifStatus::CheckErrors();
201 
202  // Now allocate a new indexed mesh to contain all the DSK data
203  m_mesh.reset( new btTriangleIndexVertexArray());
204 
205  for (size_t i = 0; i < segments.size(); i++) {
206  SpiceInt nplates;
207  SpiceInt nvertices;
208 
209  btIndexedMesh i_mesh;
210 
211  // Get size/counts
212  dskz02_c( handle, &segments[i], &nvertices, &nplates);
214 
215  m_mesh->addIndexedMesh(i_mesh, PHY_INTEGER);
216 
217  // Get internal mesh reference and set parameters appropriately
218  btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[i];
219  v_mesh.m_vertexType = PHY_DOUBLE;
220 
221  // Set and allocate data for triangle indexes
222  v_mesh.m_numTriangles = nplates;
223  v_mesh.m_triangleIndexBase = new unsigned char[nplates * 3 * sizeof(int)];
224  v_mesh.m_triangleIndexStride = (sizeof(int) * 3);
225 
226  // Set and allocate vertex data
227  v_mesh.m_numVertices = nvertices;
228  v_mesh.m_vertexBase = new unsigned char[nvertices * 3 * sizeof(double)];
229  v_mesh.m_vertexStride = (sizeof(double) * 3);
230 
231  SpiceInt n;
232  (void) dskv02_c(handle, &segments[i], 1, nvertices, &n,
233  ( SpiceDouble(*)[3] ) (v_mesh.m_vertexBase));
235 
236  // Read the indexes from the DSK
237  (void) dskp02_c(handle, &segments[i], 1, nplates, &n,
238  ( SpiceInt(*)[3] ) (v_mesh.m_triangleIndexBase));
240 
241  // Got to reset the vertex indexes to 0-based
242  int *pindex = static_cast<int *> ((void *) v_mesh.m_triangleIndexBase);
243  int nverts = nplates * 3;
244  for (int i = 0 ; i < nverts ; i++) {
245  pindex[i] -= 1;
246  btAssert ( pindex[i] >= 0 );
247  btAssert ( pindex[i] < nvertices );
248  }
249  }
250 
251  // Close DSK
252  dascls_c(handle);
253 
254  bool useQuantizedAabbCompression = true;
255  // bool useQuantizedAabbCompression = false;
256  btBvhTriangleMeshShape *v_triShape = new btBvhTriangleMeshShape(m_mesh.data(),
257  useQuantizedAabbCompression);
258  v_triShape->setUserPointer(this);
259  btCollisionObject *vbody = new btCollisionObject();
260  vbody->setCollisionShape(v_triShape);
261  setTargetBody(vbody);
262 
263  return;
264 
265  }
266 
267 } // namespace Isis
Isis::BulletDskShape::getNormal
virtual btVector3 getNormal(const int indexId, const int segment=0) const
Return normal for a given triangle index.
Definition: BulletDskShape.cpp:113
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::BulletDskShape::BulletDskShape
BulletDskShape()
Default empty constructor.
Definition: BulletDskShape.cpp:34
Isis::FileName::fileExists
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:449
Isis::BulletDskShape::getNumTriangles
int getNumTriangles() const
Return the number of triangles in the shape.
Definition: BulletDskShape.cpp:70
Isis::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::BulletTargetShape::setMaximumDistance
void setMaximumDistance()
Calculate and save the maximum distance across the body.
Definition: BulletTargetShape.cpp:54
Isis::BulletDskShape::getTriangle
virtual btMatrix3x3 getTriangle(const int index, const int segment=0) const
Get the vertices of a triangle in the mesh.
Definition: BulletDskShape.cpp:130
Isis::BulletDskShape::loadFromDsk
void loadFromDsk(const QString &dskfile)
! Triangular mesh representation of the target shape.
Definition: BulletDskShape.cpp:162
Isis::BulletTargetShape::setTargetBody
void setTargetBody(btCollisionObject *body)
Set the Bullet shape object to this object instance
Definition: BulletTargetShape.cpp:156
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::BulletDskShape::getNumVertices
int getNumVertices() const
Return the number of verticies in the shape.
Definition: BulletDskShape.cpp:88
std
Namespace for the standard library.
Isis::BulletDskShape::~BulletDskShape
virtual ~BulletDskShape()
Desctructor.
Definition: BulletDskShape.cpp:51
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126