Commit 707d2a01 authored by Kelvin Rodriguez's avatar Kelvin Rodriguez Committed by Jesse Mapel
Browse files

Multisegment DSK support for Bullet engine (#2791)

* Merged multisegment DSKs for Bullet

* basic tests

* removed original tests
parent 776a65e3
Loading
Loading
Loading
Loading
+102 −88
Original line number Diff line number Diff line
@@ -157,12 +157,7 @@ namespace Isis {
  void BulletDskShape::loadFromDsk(const QString &dskfile) {

    /** NAIF DSK parameter setup   */
    SpiceInt      v_handle;   //!< The DAS file handle of the DSK file.
    SpiceDLADescr v_dladsc;   /**< The DLA descriptor of the DSK segment representing the 
                                   target surface.*/
    SpiceDSKDescr v_dskdsc;   //!< The DSK descriptor.
    SpiceInt      v_plates;   //!< Number of Plates in the model.
    SpiceInt      v_vertices; //!< Number of vertices defining the plate.
    SpiceInt                   handle;   //!< The DAS file handle of the DSK file.

    // Sanity check
    FileName dskFile(dskfile);
@@ -172,65 +167,84 @@ namespace Isis {
    }

    // Open the NAIF Digital Shape Kernel (DSK)
    dasopr_c( dskFile.expanded().toLatin1().data(), &v_handle );
    dasopr_c( dskFile.expanded().toLatin1().data(), &handle );
    NaifStatus::CheckErrors();

    // Search to the first DLA segment
    SpiceBoolean  found;
    dlabfs_c( v_handle, &v_dladsc, &found );
    SpiceDLADescr segment;
    dlabfs_c( handle, &segment, &found );
    NaifStatus::CheckErrors();
    if ( !found ) {
      QString mess = "No segments found in DSK file " + dskfile ;
      throw IException(IException::User, mess, _FILEINFO_);
    }

    dskgd_c( v_handle, &v_dladsc, &v_dskdsc );
    NaifStatus::CheckErrors();
    std::vector<SpiceDLADescr> segments;
    segments.push_back(segment);

    // Get size/counts
    dskz02_c( v_handle, &v_dladsc, &v_vertices, &v_plates );
    // Iterate until you find no more segments.
    while(found) {
      dlafns_c(handle, &segments.back(), &segment, &found);
      NaifStatus::CheckErrors();

      segments.push_back(segment);
    }

    // dskgd_c( v_handle, &v_dladsc, &v_dskdsc );
    // NaifStatus::CheckErrors();

    // Now allocate a new indexed mesh to contain all the DSK data
    btIndexedMesh i_mesh;
    m_mesh.reset( new btTriangleIndexVertexArray());

    for (size_t i = 0; i < segments.size(); i++) {
      SpiceInt nplates;
      SpiceInt nvertices;

      btIndexedMesh i_mesh;

      // Get size/counts
      dskz02_c( handle, &segments[i], &nvertices, &nplates);
      NaifStatus::CheckErrors();

      m_mesh->addIndexedMesh(i_mesh, PHY_INTEGER);

      // Get internal mesh reference and set parameters appropriately
    btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[0];
      btIndexedMesh &v_mesh = m_mesh->getIndexedMeshArray()[i];
      v_mesh.m_vertexType = PHY_DOUBLE;

      // Set and allocate data for triangle indexes
    v_mesh.m_numTriangles = v_plates;
    v_mesh.m_triangleIndexBase = new unsigned char[v_plates * 3 * sizeof(int)];
      v_mesh.m_numTriangles = nplates;
      v_mesh.m_triangleIndexBase = new unsigned char[nplates * 3 * sizeof(int)];
      v_mesh.m_triangleIndexStride = (sizeof(int) * 3);

      // Set and allocate vertex data
    v_mesh.m_numVertices = v_vertices;
    v_mesh.m_vertexBase = new unsigned char[v_vertices * 3 * sizeof(double)];
      v_mesh.m_numVertices = nvertices;
      v_mesh.m_vertexBase = new unsigned char[nvertices * 3 * sizeof(double)];
      v_mesh.m_vertexStride = (sizeof(double) * 3);

      SpiceInt n;
    (void) dskv02_c(v_handle, &v_dladsc, 1, v_vertices, &n, 
      (void) dskv02_c(handle, &segments[i], 1, nvertices, &n,
                      ( SpiceDouble(*)[3] ) (v_mesh.m_vertexBase));
      NaifStatus::CheckErrors();

      // Read the indexes from the DSK
    (void) dskp02_c(v_handle, &v_dladsc, 1, v_plates, &n, 
      (void) dskp02_c(handle, &segments[i], 1, nplates, &n,
                      ( SpiceInt(*)[3] ) (v_mesh.m_triangleIndexBase));
      NaifStatus::CheckErrors();

    // Ok, close the DSK...
    dascls_c(v_handle);

      // Got to reset the vertex indexes to 0-based
      int *pindex = static_cast<int *> ((void *) v_mesh.m_triangleIndexBase);
    int nverts = v_plates * 3;
      int nverts = nplates * 3;
      for (int i = 0 ; i < nverts ; i++) {
        pindex[i] -= 1;
        btAssert ( pindex[i] >= 0 );
      btAssert ( pindex[i] < v_vertices );
        btAssert ( pindex[i] < nvertices );
      }
    }

    // Close DSK
    dascls_c(handle);

    bool useQuantizedAabbCompression = true;
    // bool useQuantizedAabbCompression = false;
+0 −29
Original line number Diff line number Diff line
Testing BulletDskShape


Testing default constructor

Target name:  ""
Maximum distance in kilometers:  0
btCollisionBody pointer is valid?  false
Number of triangles:  0
Number of vertices:  0


Testing DSK file constructor
Testing with  "$base/testData/hay_a_amica_5_itokawashape_v1_0_64q.bds" ...

Target name:  ""
Maximum distance in kilometers:  0.683956
btCollisionBody pointer is valid?  true
Number of triangles:  49152
Number of vertices:  25350

Vertices for triangle 0: ( -0.15153 ,  0.08183 ,  0.07523 )
                         ( -0.05653 ,  0.08832 ,  0.08776 )
                         ( 0.08183 ,  0.07523 ,  -0.14726 )
Normal for triangle 0: ( -0.00136126 ,  0.0240606 ,  -0.00214151 )


Testing loading non-existant file
**USER ERROR** NAIF DSK file [not_a_file] does not exist.
+0 −90
Original line number Diff line number Diff line
/**
 * @file
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are public
 *   domain. See individual third-party library and package descriptions for
 *   intellectual property information,user agreements, and related information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or implied,
 *   is made by the USGS as to the accuracy and functioning of such software
 *   and related material nor shall the fact of distribution constitute any such
 *   warranty, and no responsibility is assumed by the USGS in connection
 *   therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html in a browser or see
 *   the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */

#include <QDebug>

#include "BulletDskShape.h"
#include "IException.h"
#include "Preference.h"

using namespace Isis;

/**
 * Unit test for the BulletDskShape class
 */
int main(int argc, char *argv[]) {
  try {
    Preference::Preferences(true);

    qDebug() << "Testing BulletDskShape";
    qDebug() << endl;

    qDebug() << "Testing default constructor";
    qDebug() << "";
    BulletDskShape defaultDskShape;
    qDebug() << "Target name: " << defaultDskShape.name();
    qDebug() << "Maximum distance in kilometers: " << defaultDskShape.maximumDistance();
    qDebug() << "btCollisionBody pointer is valid? " << (bool) defaultDskShape.body();
    qDebug() << "Number of triangles: " << defaultDskShape.getNumTriangles();
    qDebug() << "Number of vertices: " << defaultDskShape.getNumVertices();
    qDebug() << endl;

    qDebug() << "Testing DSK file constructor";
    QString dskfile("$base/testData/hay_a_amica_5_itokawashape_v1_0_64q.bds");
    qDebug() << "Testing with " << dskfile << "...";
    qDebug() << "";
    BulletDskShape itokawaShape(dskfile);
    qDebug() << "Target name: " << itokawaShape.name();
    qDebug() << "Maximum distance in kilometers: " << itokawaShape.maximumDistance();
    qDebug() << "btCollisionBody pointer is valid? " << (bool) itokawaShape.body();
    qDebug() << "Number of triangles: " << itokawaShape.getNumTriangles();
    qDebug() << "Number of vertices: " << itokawaShape.getNumVertices();
    qDebug() << "";
    btMatrix3x3 triangle = itokawaShape.getTriangle(0);
    qDebug() << "Vertices for triangle 0: (" << triangle[0].x() << ", "
                                            << triangle[0].y() << ", "
                                            << triangle[0].z() << ")";
    qDebug() << "                         (" << triangle[1].x() << ", "
                                            << triangle[1].y() << ", "
                                            << triangle[1].z() << ")";
    qDebug() << "                         (" << triangle[2].x() << ", "
                                            << triangle[2].y() << ", "
                                            << triangle[2].z() << ")";
    btVector3 normal = itokawaShape.getNormal(0);
    qDebug() << "Normal for triangle 0: (" << normal.x() << ", "
                                          << normal.y() << ", "
                                          << normal.z() << ")";
    qDebug() << endl;

    qDebug() << "Testing loading non-existant file";
    try {
      BulletDskShape badShape("not_a_file");
    }
    catch (IException &e) {
      e.print();
    }
  }
  catch (IException &e) {
    qDebug() << "";
    qDebug() << "";
    QString msg = "**************** UNIT TEST FAILED! **************** ";
    IException(e, IException::Unknown, msg, _FILEINFO_).print();
  }
}
+65 −0
Original line number Diff line number Diff line
#include "BulletDskShape.h"
#include "IException.h"
#include "SpecialPixel.h"

#include <gtest/gtest.h>

using namespace Isis;

TEST(BulletDskShapeTests, DefaultConstructor) {
  BulletDskShape defaultDskShape;
  EXPECT_EQ(defaultDskShape.name(), "");
  EXPECT_FALSE((bool) defaultDskShape.body());
  EXPECT_EQ(defaultDskShape.getNumTriangles(), 0);
  EXPECT_EQ(defaultDskShape.getNumVertices(), 0);
}

TEST(BulletDskShapeTests, SingleSegment) {
  QString dskfile("$base/testData/hay_a_amica_5_itokawashape_v1_0_64q.bds");

  BulletDskShape itokawaShape(dskfile);
  EXPECT_EQ(itokawaShape.name(), "");
  EXPECT_DOUBLE_EQ(itokawaShape.maximumDistance(), 0.68395571742620886);
  EXPECT_TRUE((bool) itokawaShape.body());
  EXPECT_EQ(itokawaShape.getNumTriangles(), 49152);
  EXPECT_EQ(itokawaShape.getNumVertices(), 25350);

  btMatrix3x3 truthTriangle(-0.15153, 0.08183, 0.07523,
                            -0.05653, 0.08832, 0.08776,
                             0.08183, 0.07523, -0.14726);
  btMatrix3x3 triangle = itokawaShape.getTriangle(0);
  EXPECT_TRUE(triangle == truthTriangle);

  btVector3 truthNormal(-0.0013612620999999992,
                         0.024060550800000004,
                        -0.0021415063999999989);
  btVector3 normal = itokawaShape.getNormal(0);
  EXPECT_TRUE(normal == truthNormal);
}

TEST(BulletDskShapeTests, BadFile) {
  EXPECT_THROW(BulletDskShape("not_a_file"), IException);
}


TEST(BulletDskShapeTests, MutiSegment) {
  QString dskfile("$base/testData/test_shape.bds");

  BulletDskShape multiseg(dskfile);
  EXPECT_EQ(multiseg.name(), "");
  EXPECT_DOUBLE_EQ(multiseg.maximumDistance(), 7.3484692283495345);
  EXPECT_TRUE((bool) multiseg.body());
  EXPECT_EQ(multiseg.getNumTriangles(), 14);
  EXPECT_EQ(multiseg.getNumVertices(), 13);

  btMatrix3x3 truthTriangle(0, 0, 6,
                            0, 6, 1,
                            0, 5, 2);
  btMatrix3x3 triangle = multiseg.getTriangle(0);
  EXPECT_TRUE(triangle == truthTriangle);


  btVector3 truthNormal(1, 0, 0);
  btVector3 normal = multiseg.getNormal(0);
  EXPECT_TRUE(normal == truthNormal);
}