From bacd6445f28fd10434815edae2707b1a254e6057 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 31 Mar 2015 16:59:13 -0700 Subject: [PATCH 1/5] pull comments that get used as scaling hints into a hash table --- libraries/fbx/src/OBJReader.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index c87a942baa..7e71ba07f7 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -21,9 +21,12 @@ #include "Shape.h" +QHash COMMENT_SCALE_HINTS; + + class OBJTokenizer { public: - OBJTokenizer(QIODevice* device) : _device(device), _pushedBackToken(-1) { } + OBJTokenizer(QIODevice* device); enum SpecialToken { NO_TOKEN = -1, NO_PUSHBACKED_TOKEN = -1, @@ -46,6 +49,15 @@ private: }; +OBJTokenizer::OBJTokenizer(QIODevice* device) : _device(device), _pushedBackToken(-1) { + // This is a list of comments that exports use to hint at scaling + if (COMMENT_SCALE_HINTS.isEmpty()) { + COMMENT_SCALE_HINTS["This file uses centimeters as units"] = 1.0f / 100.0f; + COMMENT_SCALE_HINTS["This file uses millimeters as units"] = 1.0f / 1000.0f; + } +} + + int OBJTokenizer::nextToken() { if (_pushedBackToken != NO_PUSHBACKED_TOKEN) { int token = _pushedBackToken; @@ -60,7 +72,7 @@ int OBJTokenizer::nextToken() { } switch (ch) { case '#': { - _comment = _device->readLine(); // skip the comment + _comment = _device->readLine(); // stash comment for a future call to getComment qDebug() << "COMMENT:" << _comment; return COMMENT_TOKEN; } @@ -136,11 +148,15 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, while (true) { int tokenType = tokenizer.nextToken(); if (tokenType == OBJTokenizer::COMMENT_TOKEN) { - if (tokenizer.getComment().contains("This file uses centimeters as units")) { - scaleGuess = 1.0f / 100.0f; - } - if (tokenizer.getComment().contains("This file uses millimeters as units")) { - scaleGuess = 1.0f / 1000.0f; + // loop through the list of known comments which suggest a scaling factor. + // if we find one, save the scaling hint into scaleGuess + QString comment = tokenizer.getComment(); + QHashIterator i(COMMENT_SCALE_HINTS); + while (i.hasNext()) { + i.next(); + if (comment.contains(i.key())) { + scaleGuess = i.value(); + } } continue; } From 05cb0b830c004ed8623fefc8f1ada06add03ccf5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 31 Mar 2015 16:59:43 -0700 Subject: [PATCH 2/5] make max collision size be 1000x1000x1000 rather than 100x100x100 --- libraries/physics/src/ShapeManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index b4d322a4a3..1dd4b981d8 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -35,7 +35,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { // Very small or large objects are not supported. float diagonal = 4.0f * glm::length2(info.getHalfExtents()); const float MIN_SHAPE_DIAGONAL_SQUARED = 3.0e-4f; // 1 cm cube - const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e4f; // 100 m cube + const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e6f; // 100 m cube if (diagonal < MIN_SHAPE_DIAGONAL_SQUARED || diagonal > MAX_SHAPE_DIAGONAL_SQUARED) { // qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; return NULL; From 5cc12b8b4762bbb43d69758cffee1c4d5dd2b954 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 31 Mar 2015 17:00:36 -0700 Subject: [PATCH 3/5] allow for quads in the model which is being used as the template for generating the collision shape. added a flag to run the fatten-face code --- tools/vhacd/src/VHACDUtil.cpp | 37 +++++++++++++++++++++++++------- tools/vhacd/src/VHACDUtil.h | 3 ++- tools/vhacd/src/VHACDUtilApp.cpp | 13 +++++------ 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/tools/vhacd/src/VHACDUtil.cpp b/tools/vhacd/src/VHACDUtil.cpp index 4f2cb0e2b8..faec01ef14 100644 --- a/tools/vhacd/src/VHACDUtil.cpp +++ b/tools/vhacd/src/VHACDUtil.cpp @@ -54,9 +54,24 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, vhacd::LoadFBXResults *re //get the triangle indices for each mesh QVector triangles; - foreach(FBXMeshPart part, mesh.parts){ - QVector indices = part.triangleIndices; + foreach(FBXMeshPart meshPart, mesh.parts){ + QVector indices = meshPart.triangleIndices; triangles += indices; + + unsigned int quadCount = meshPart.quadIndices.size() / 4; + for (unsigned int i = 0; i < quadCount; i++) { + unsigned int p0Index = meshPart.quadIndices[i*4]; + unsigned int p1Index = meshPart.quadIndices[i*4+1]; + unsigned int p2Index = meshPart.quadIndices[i*4+2]; + unsigned int p3Index = meshPart.quadIndices[i*4+3]; + // split each quad into two triangles + triangles.append(p0Index); + triangles.append(p1Index); + triangles.append(p2Index); + triangles.append(p0Index); + triangles.append(p2Index); + triangles.append(p3Index); + } } //only read meshes with triangles @@ -148,21 +163,26 @@ void vhacd::VHACDUtil::fattenMeshes(vhacd::LoadFBXResults *meshes, vhacd::LoadFB -bool vhacd::VHACDUtil::computeVHACD(vhacd::LoadFBXResults *meshes, VHACD::IVHACD::Parameters params, +bool vhacd::VHACDUtil::computeVHACD(vhacd::LoadFBXResults *inMeshes, VHACD::IVHACD::Parameters params, vhacd::ComputeResults *results, - int startMeshIndex, int endMeshIndex, float minimumMeshSize) const { + int startMeshIndex, int endMeshIndex, float minimumMeshSize, + bool fattenFaces) const { - // vhacd::LoadFBXResults *meshes = new vhacd::LoadFBXResults; + vhacd::LoadFBXResults *meshes = new vhacd::LoadFBXResults; // combineMeshes(inMeshes, meshes); // vhacd::LoadFBXResults *meshes = new vhacd::LoadFBXResults; - // fattenMeshes(inMeshes, meshes); + + if (fattenFaces) { + fattenMeshes(inMeshes, meshes); + } else { + meshes = inMeshes; + } VHACD::IVHACD * interfaceVHACD = VHACD::CreateVHACD(); int meshCount = meshes->meshCount; int count = 0; - std::cout << "Performing V-HACD computation on " << meshCount << " meshes ..... " << std::endl; if (startMeshIndex < 0) { startMeshIndex = 0; @@ -171,6 +191,8 @@ bool vhacd::VHACDUtil::computeVHACD(vhacd::LoadFBXResults *meshes, VHACD::IVHACD endMeshIndex = meshCount; } + std::cout << "Performing V-HACD computation on " << endMeshIndex - startMeshIndex << " meshes ..... " << std::endl; + for (int i = startMeshIndex; i < endMeshIndex; i++){ qDebug() << "--------------------"; std::vector vertices = meshes->perMeshVertices.at(i).toStdVector(); @@ -211,7 +233,6 @@ bool vhacd::VHACDUtil::computeVHACD(vhacd::LoadFBXResults *meshes, VHACD::IVHACD } hull.m_points = m_points_copy; - int *m_triangles_copy = new int[hull.m_nTriangles * 3]; // std::copy(std::begin(hull.m_triangles), std::end(hull.m_triangles), std::begin(m_triangles_copy)); for (unsigned int i=0; i Date: Tue, 31 Mar 2015 17:20:16 -0700 Subject: [PATCH 4/5] fix comment --- libraries/physics/src/ShapeManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 1dd4b981d8..2c30887e3e 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -35,7 +35,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { // Very small or large objects are not supported. float diagonal = 4.0f * glm::length2(info.getHalfExtents()); const float MIN_SHAPE_DIAGONAL_SQUARED = 3.0e-4f; // 1 cm cube - const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e6f; // 100 m cube + const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e6f; // 1000 m cube if (diagonal < MIN_SHAPE_DIAGONAL_SQUARED || diagonal > MAX_SHAPE_DIAGONAL_SQUARED) { // qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; return NULL; From 23903570f0a507e622bf1d3f442a7e300169e83c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 1 Apr 2015 09:19:34 -0700 Subject: [PATCH 5/5] added more options to v-hacd util, messed with fatten-mesh code some more --- tools/vhacd/src/VHACDUtil.cpp | 38 +++++++++++++++++++++++--------- tools/vhacd/src/VHACDUtilApp.cpp | 31 +++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/tools/vhacd/src/VHACDUtil.cpp b/tools/vhacd/src/VHACDUtil.cpp index faec01ef14..804a3562c6 100644 --- a/tools/vhacd/src/VHACDUtil.cpp +++ b/tools/vhacd/src/VHACDUtil.cpp @@ -38,6 +38,15 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, vhacd::LoadFBXResults *re } + std::cout << "-------------------\n"; + foreach (const FBXMesh& mesh, geometry.meshes) { + foreach (const FBXMeshPart &meshPart, mesh.parts) { + std::cout << meshPart.triangleIndices.size() << " "; + } + } + std::cout << "\n"; + + //results->meshCount = geometry.meshes.count(); // qDebug() << "read in" << geometry.meshes.count() << "meshes"; @@ -52,7 +61,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, vhacd::LoadFBXResults *re vertices.append(glm::vec3(mesh.modelTransform * glm::vec4(vertex, 1.0f))); } - //get the triangle indices for each mesh + // get the triangle indices for each mesh QVector triangles; foreach(FBXMeshPart meshPart, mesh.parts){ QVector indices = meshPart.triangleIndices; @@ -60,10 +69,10 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, vhacd::LoadFBXResults *re unsigned int quadCount = meshPart.quadIndices.size() / 4; for (unsigned int i = 0; i < quadCount; i++) { - unsigned int p0Index = meshPart.quadIndices[i*4]; - unsigned int p1Index = meshPart.quadIndices[i*4+1]; - unsigned int p2Index = meshPart.quadIndices[i*4+2]; - unsigned int p3Index = meshPart.quadIndices[i*4+3]; + unsigned int p0Index = meshPart.quadIndices[i * 4]; + unsigned int p1Index = meshPart.quadIndices[i * 4 + 1]; + unsigned int p2Index = meshPart.quadIndices[i * 4 + 2]; + unsigned int p3Index = meshPart.quadIndices[i * 4 + 3]; // split each quad into two triangles triangles.append(p0Index); triangles.append(p1Index); @@ -74,7 +83,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, vhacd::LoadFBXResults *re } } - //only read meshes with triangles + // only read meshes with triangles if (triangles.count() <= 0){ continue; } @@ -146,15 +155,16 @@ void vhacd::VHACDUtil::fattenMeshes(vhacd::LoadFBXResults *meshes, vhacd::LoadFB auto d1 = p2 - p0; auto cp = glm::cross(d0, d1); - cp = 5.0f * glm::normalize(cp); + cp = -2.0f * glm::normalize(cp); auto p3 = p0 + cp; - auto p4 = p1 + cp; - auto p5 = p2 + cp; auto n = results->perMeshVertices.size(); - results->perMeshVertices[i] << p3 << p4 << p5; - results->perMeshTriangleIndices[i] << n << n+1 << n+2; + results->perMeshVertices[i] << p3; + + results->perMeshTriangleIndices[i] << triangles[j] << n << triangles[j + 1]; + results->perMeshTriangleIndices[i] << triangles[j + 1] << n << triangles[j + 2]; + results->perMeshTriangleIndices[i] << triangles[j + 2] << n << triangles[j]; } results->meshCount++; @@ -191,6 +201,12 @@ bool vhacd::VHACDUtil::computeVHACD(vhacd::LoadFBXResults *inMeshes, VHACD::IVHA endMeshIndex = meshCount; } + for (int i = 0; i < meshCount; i++) { + std::cout << meshes->perMeshTriangleIndices.at(i).size() << " "; + } + std::cout << "\n"; + + std::cout << "Performing V-HACD computation on " << endMeshIndex - startMeshIndex << " meshes ..... " << std::endl; for (int i = startMeshIndex; i < endMeshIndex; i++){ diff --git a/tools/vhacd/src/VHACDUtilApp.cpp b/tools/vhacd/src/VHACDUtilApp.cpp index 715aae0d7b..a572f49b80 100644 --- a/tools/vhacd/src/VHACDUtilApp.cpp +++ b/tools/vhacd/src/VHACDUtilApp.cpp @@ -110,6 +110,15 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) : const QCommandLineOption minimumMeshSizeOption("m", "minimum mesh size to consider", "0"); parser.addOption(minimumMeshSizeOption); + const QCommandLineOption vHacdResolutionOption("resolution", "v-hacd resolution", "100000"); + parser.addOption(vHacdResolutionOption); + + const QCommandLineOption vHacdDepthOption("depth", "v-hacd depth", "20"); + parser.addOption(vHacdDepthOption); + + const QCommandLineOption vHacdDeltaOption("delta", "v-hacd delta", "0.05"); + parser.addOption(vHacdDeltaOption); + if (!parser.parse(QCoreApplication::arguments())) { qCritical() << parser.errorText() << endl; @@ -163,13 +172,29 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) : minimumMeshSize = parser.value(minimumMeshSizeOption).toFloat(); } + int vHacdResolution = 100000; + if (parser.isSet(vHacdResolutionOption)) { + vHacdResolution = parser.value(vHacdResolutionOption).toInt(); + } + + int vHacdDepth = 20; + if (parser.isSet(vHacdDepthOption)) { + vHacdDepth = parser.value(vHacdDepthOption).toInt(); + } + + float vHacdDelta = 0.05; + if (parser.isSet(vHacdDeltaOption)) { + vHacdDelta = parser.value(vHacdDeltaOption).toFloat(); + } + + //set parameters for V-HACD params.m_callback = &pCallBack; //progress callback - params.m_resolution = 100000; // 100000 - params.m_depth = 20; // 20 + params.m_resolution = vHacdResolution; // 100000 + params.m_depth = vHacdDepth; // 20 params.m_concavity = 0.001; // 0.001 - params.m_delta = 0.05; // 0.05 + params.m_delta = vHacdDelta; // 0.05 params.m_planeDownsampling = 4; // 4 params.m_convexhullDownsampling = 4; // 4 params.m_alpha = 0.05; // 0.05 // controls the bias toward clipping along symmetry planes