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
27using namespace std;
28
29namespace Isis {
30
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
int getNumTriangles() const
Return the number of triangles in the shape.
virtual btMatrix3x3 getTriangle(const int index, const int segment=0) const
Get the vertices of a triangle in the mesh.
virtual ~BulletDskShape()
Desctructor.
int getNumVertices() const
Return the number of verticies in the shape.
virtual btVector3 getNormal(const int indexId, const int segment=0) const
Return normal for a given triangle index.
BulletDskShape()
Default empty constructor.
void loadFromDsk(const QString &dskfile)
! Triangular mesh representation of the target shape.
void setTargetBody(btCollisionObject *body)
Set the Bullet shape object to this object instance
void setMaximumDistance()
Calculate and save the maximum distance across the body.
File name manipulation and expansion.
Definition FileName.h:100
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
Namespace for the standard library.