Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
BulletDskShape.cpp
1
5
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 <QStringList>
19#include <QTime>
20
21#include "FileName.h"
22#include "IException.h"
23#include "IString.h"
24#include "Pvl.h"
25#include "NaifDskPlateModel.h"
26#include "NaifStatus.h"
27
28
29using namespace std;
30
31namespace Isis {
32
37
38
44 BulletDskShape::BulletDskShape(const QString &dskfile) : m_mesh() {
45 loadFromDsk(dskfile);
47 }
48
49
54
61 size_t num_triangles = 0;
62
63 if (m_mesh) {
64 for(int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
65 num_triangles += m_mesh->getIndexedMeshArray()[i].m_numTriangles;
66 }
67 }
68
69 return num_triangles;
70 }
71
72
79 size_t num_vertices = 0;
80
81 if (m_mesh) {
82 for(int i = 0; i < m_mesh->getIndexedMeshArray().size(); i++) {
83 num_vertices += m_mesh->getIndexedMeshArray()[i].m_numVertices;
84 }
85 }
86
87 return num_vertices;
88 }
89
90
103 btVector3 BulletDskShape::getNormal(const int indexId, const int segment) const {
104 btMatrix3x3 triangle = getTriangle(indexId, segment);
105 btVector3 edge1 = triangle.getRow(1) - triangle.getRow(0);
106 btVector3 edge2 = triangle.getRow(2) - triangle.getRow(0);
107 return ( edge1.cross( edge2 ) );
108 }
109
110
120 btMatrix3x3 BulletDskShape::getTriangle(const int index, const int segment) const {
121 btAssert ( index >= 0 );
122 btAssert ( index < getIndexedMeshArray()[segment].m_numTriangles );
123
124 btAssert ( segment >= 0 );
125 btAssert ( segment < getIndexedMeshArray().size());
126
127 // Set up pointers to triangle indexes
128 const btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[segment];
129
130 const int *t_index = static_cast<int32_t *> ((void *) v_mesh.m_triangleIndexBase);
131 int p_index = 3 * index;
132 int vndx0 = t_index[p_index];
133 int vndx1 = t_index[p_index+1];
134 int vndx2 = t_index[p_index+2];
135
136 const btScalar *t_vertex = static_cast<const btScalar *> ((void *) v_mesh.m_vertexBase);
137
138 btMatrix3x3 triangle(t_vertex[vndx0+0], t_vertex[vndx0+1], t_vertex[vndx0+2],
139 t_vertex[vndx1+0], t_vertex[vndx1+1], t_vertex[vndx1+2],
140 t_vertex[vndx2+0], t_vertex[vndx2+1], t_vertex[vndx2+2]);
141 return ( triangle );
142 }
143
144
176 void BulletDskShape::loadFromDsk(const QString &dskfile) {
177
179 SpiceInt handle;
180 SpiceBoolean found;
181 SpiceDLADescr segment;
182
183 // Sanity check
184 FileName dskFile(dskfile);
185 if ( !dskFile.fileExists() ) {
186 QString mess = "NAIF DSK file [" + dskfile + "] does not exist.";
187 throw IException(IException::User, mess, _FILEINFO_);
188 }
189
190 // Open the NAIF Digital Shape Kernel (DSK)
191 dasopr_c( dskFile.expanded().toLatin1().data(), &handle );
193
194 // Search to the first DLA segment
195 dlabfs_c( handle, &segment, &found );
197 if ( !found ) {
198 QString mess = "No segments found in DSK file " + dskfile ;
199 throw IException(IException::User, mess, _FILEINFO_);
200 }
201
202 #if defined(DSK_DEBUG)
203 std::cout << "Maximum Bullet Parts: " << bt_MaxBodyParts() << std::endl;
204 std::cout << "Maximum Triangles/Part: " << bt_MaxTriangles() << std::endl;
205 #endif
206
207 // Now allocate a new indexed mesh to contain all the DSK data
208 // Clear any existing buffers
209 m_mesh.reset( new btTriangleIndexVertexArray() );
210 m_buffers.clear();
211
212 int n_parts = 0;
213 int n_segments = 0;
214
215 while( found ) {
216
217 // Validate last segment found before searching for the next segment
218 SpiceInt s_plates;
219 SpiceInt s_vertices;
220 dskz02_c( handle, &segment, &s_vertices, &s_plates);
222
223#if defined(DSK_DEBUG)
224 std::cout << "\nSegment: " << n_segments << std::endl;
225 std::cout << "#Vertices: " << s_vertices << std::endl;
226 std::cout << "#Plates: " << s_plates << std::endl;
227#endif
228
229 // Initialize the DSK data buffer container
230 DskSegmentBuffer dsk_buffer(n_segments, segment, s_plates, s_vertices );
231
232 SpiceInt n;
233 (void) dskv02_c(handle, &segment, 1, s_vertices, &n,
234 ( SpiceDouble(*)[3] ) ( dsk_buffer.vector_ptr(0)));
236
237 // Read the indexes from the DSK
238 (void) dskp02_c(handle, &segment, 1, s_plates, &n,
239 ( SpiceInt(*)[3] ) (dsk_buffer.index_ptr(0)));
241
242 // Subtract one from the index to make it 0-based and add to Bullet mesh
243 dsk_buffer.add_index_offset( -1 );
244 m_buffers.push_back( dsk_buffer );
245 n_parts += dsk_buffer.addtomesh( *m_mesh );
246 n_segments++;
247
248 // Search for the next segment and retain for next loop (above)
249 dlafns_c(handle, &dsk_buffer.dla(), &segment, &found);
251 }
252
253#if defined(DSK_DEBUG)
254 std::cout << "\n#Segments: " << m_buffers.size() << std::endl;
255 std::cout << "#Parts: " << n_parts << std::endl;
256#endif
257
258 // Close DSK
259 dascls_c(handle);
260
261 // Set up the triange mesh and target object
262 bool useQuantizedAabbCompression = true;
263 if ( n_parts > bt_MaxBodyParts() ) {
264 std::cout << "*** WARNING *** BulletDskShape total mesh parts (" << n_parts
265 << ") exceeds Bullet max (" << bt_MaxBodyParts() << ") - quantized AABB compression disabled"
266 << std::endl;
267
268 // Cannot use quantized compresssio
269 useQuantizedAabbCompression = false;
270 }
271
272 // Note the btCollisionObject is managed in this class, see pointer allocations
273 btBvhTriangleMeshShape *v_triShape = new btBvhTriangleMeshShape(m_mesh.get(),
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
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()
Destructor.
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)
!
void setTargetBody(btCollisionObject *body)
Set the Bullet shape object to this object instance.
void setMaximumDistance()
Calculate and save the maximum distance across the body.
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
unsigned long bt_MaxTriangles()
Maximum number of triangles/part.
Definition IsisBullet.h:84
int bt_MaxBodyParts()
Maximum number of parts/object.
Definition IsisBullet.h:74
Namespace for the standard library.