From 79b7a3d28de7894ce3f29be4abcda89d6a784920 Mon Sep 17 00:00:00 2001
From: luiscuenca <luiscuenca@outboxcode.com>
Date: Mon, 4 Mar 2019 13:15:15 -0700
Subject: [PATCH] Apply kdop computation after reading the joint rotation
 offsets

---
 libraries/fbx/src/FBXSerializer.cpp           | 57 +------------------
 libraries/hfm/src/hfm/HFM.cpp                 | 52 +++++++++++++++++
 libraries/hfm/src/hfm/HFM.h                   |  4 ++
 .../model-baker/src/model-baker/Baker.cpp     |  1 +
 libraries/physics/src/CharacterController.cpp |  2 +-
 5 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp
index 9e7f422b40..43ff8ee459 100644
--- a/libraries/fbx/src/FBXSerializer.cpp
+++ b/libraries/fbx/src/FBXSerializer.cpp
@@ -301,8 +301,6 @@ QString getString(const QVariant& value) {
     return list.isEmpty() ? value.toString() : list.at(0).toString();
 }
 
-typedef std::vector<glm::vec3> ShapeVertices;
-
 class AnimationCurve {
 public:
     QVector<float> values;
@@ -1319,8 +1317,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
     }
 
     // NOTE: shapeVertices are in joint-frame
-    std::vector<ShapeVertices> shapeVertices;
-    shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
+    hfmModel.shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
 
     hfmModel.bindExtents.reset();
     hfmModel.meshExtents.reset();
@@ -1511,7 +1508,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
                 }
 
                 glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
-                ShapeVertices& points = shapeVertices.at(jointIndex);
+                ShapeVertices& points = hfmModel.shapeVertices.at(jointIndex);
 
                 for (int j = 0; j < cluster.indices.size(); j++) {
                     int oldIndex = cluster.indices.at(j);
@@ -1580,7 +1577,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
 
             // transform cluster vertices to joint-frame and save for later
             glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
-            ShapeVertices& points = shapeVertices.at(jointIndex);
+            ShapeVertices& points = hfmModel.shapeVertices.at(jointIndex);
             foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
                 const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertex);
                 points.push_back(extractTranslation(vertexTransform));
@@ -1600,54 +1597,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
         meshIDsToMeshIndices.insert(it.key(), meshIndex);
     }
 
-    const float INV_SQRT_3 = 0.57735026918f;
-    ShapeVertices cardinalDirections = {
-        Vectors::UNIT_X,
-        Vectors::UNIT_Y,
-        Vectors::UNIT_Z,
-        glm::vec3(INV_SQRT_3,  INV_SQRT_3,  INV_SQRT_3),
-        glm::vec3(INV_SQRT_3, -INV_SQRT_3,  INV_SQRT_3),
-        glm::vec3(INV_SQRT_3,  INV_SQRT_3, -INV_SQRT_3),
-        glm::vec3(INV_SQRT_3, -INV_SQRT_3, -INV_SQRT_3)
-    };
-
-    // now that all joints have been scanned compute a k-Dop bounding volume of mesh
-    for (int i = 0; i < hfmModel.joints.size(); ++i) {
-        HFMJoint& joint = hfmModel.joints[i];
-
-        // NOTE: points are in joint-frame
-        ShapeVertices& points = shapeVertices.at(i);
-        if (points.size() > 0) {
-            // compute average point
-            glm::vec3 avgPoint = glm::vec3(0.0f);
-            for (uint32_t j = 0; j < points.size(); ++j) {
-                avgPoint += points[j];
-            }
-            avgPoint /= (float)points.size();
-            joint.shapeInfo.avgPoint = avgPoint;
-
-            // compute a k-Dop bounding volume
-            for (uint32_t j = 0; j < cardinalDirections.size(); ++j) {
-                float maxDot = -FLT_MAX;
-                float minDot = FLT_MIN;
-                for (uint32_t k = 0; k < points.size(); ++k) {
-                    float kDot = glm::dot(cardinalDirections[j], points[k] - avgPoint);
-                    if (kDot > maxDot) {
-                        maxDot = kDot;
-                    }
-                    if (kDot < minDot) {
-                        minDot = kDot;
-                    }
-                }
-                joint.shapeInfo.points.push_back(avgPoint + maxDot * cardinalDirections[j]);
-                joint.shapeInfo.dots.push_back(maxDot);
-                joint.shapeInfo.points.push_back(avgPoint + minDot * cardinalDirections[j]);
-                joint.shapeInfo.dots.push_back(-minDot);
-            }
-            generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
-        }
-    }
-
     // attempt to map any meshes to a named model
     for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
             m != meshIDsToMeshIndices.constEnd(); m++) {
diff --git a/libraries/hfm/src/hfm/HFM.cpp b/libraries/hfm/src/hfm/HFM.cpp
index f0fc97c5c7..e930f30d1a 100644
--- a/libraries/hfm/src/hfm/HFM.cpp
+++ b/libraries/hfm/src/hfm/HFM.cpp
@@ -154,3 +154,55 @@ QString HFMModel::getModelNameOfMesh(int meshIndex) const {
     }
     return QString();
 }
+
+void HFMModel::computeKdops() {
+    const float INV_SQRT_3 = 0.57735026918f;
+    ShapeVertices cardinalDirections = {
+        Vectors::UNIT_X,
+        Vectors::UNIT_Y,
+        Vectors::UNIT_Z,
+        glm::vec3(INV_SQRT_3,  INV_SQRT_3,  INV_SQRT_3),
+        glm::vec3(INV_SQRT_3, -INV_SQRT_3,  INV_SQRT_3),
+        glm::vec3(INV_SQRT_3,  INV_SQRT_3, -INV_SQRT_3),
+        glm::vec3(INV_SQRT_3, -INV_SQRT_3, -INV_SQRT_3)
+    };
+
+    // now that all joints have been scanned compute a k-Dop bounding volume of mesh
+    for (int i = 0; i < joints.size(); ++i) {
+        HFMJoint& joint = joints[i];
+
+        // NOTE: points are in joint-frame
+        ShapeVertices& points = shapeVertices.at(i);
+        glm::quat rotOffset = jointRotationOffsets.contains(i) ? glm::inverse(jointRotationOffsets[i]) : quat();
+        if (points.size() > 0) {
+            // compute average point
+            glm::vec3 avgPoint = glm::vec3(0.0f);
+            for (uint32_t j = 0; j < points.size(); ++j) {
+                points[j] = rotOffset * points[j];
+                avgPoint += points[j];
+            }
+            avgPoint /= (float)points.size();
+            joint.shapeInfo.avgPoint = avgPoint;
+
+            // compute a k-Dop bounding volume
+            for (uint32_t j = 0; j < cardinalDirections.size(); ++j) {
+                float maxDot = -FLT_MAX;
+                float minDot = FLT_MIN;
+                for (uint32_t k = 0; k < points.size(); ++k) {
+                    float kDot = glm::dot(cardinalDirections[j], points[k] - avgPoint);
+                    if (kDot > maxDot) {
+                        maxDot = kDot;
+                    }
+                    if (kDot < minDot) {
+                        minDot = kDot;
+                    }
+                }
+                joint.shapeInfo.points.push_back(avgPoint + maxDot * cardinalDirections[j]);
+                joint.shapeInfo.dots.push_back(maxDot);
+                joint.shapeInfo.points.push_back(avgPoint + minDot * cardinalDirections[j]);
+                joint.shapeInfo.dots.push_back(-minDot);
+            }
+            generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
+        }
+    }
+}
diff --git a/libraries/hfm/src/hfm/HFM.h b/libraries/hfm/src/hfm/HFM.h
index 9f3de3302c..c9df45cde3 100644
--- a/libraries/hfm/src/hfm/HFM.h
+++ b/libraries/hfm/src/hfm/HFM.h
@@ -53,6 +53,8 @@ using ColorType = glm::vec3;
 
 const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048;
 
+using ShapeVertices = std::vector<glm::vec3>;
+
 // High Fidelity Model namespace
 namespace hfm {
 
@@ -319,6 +321,8 @@ public:
     QList<QString> blendshapeChannelNames;
 
     QMap<int, glm::quat> jointRotationOffsets;
+    std::vector<ShapeVertices> shapeVertices;
+    void computeKdops();
 };
 
 };
diff --git a/libraries/model-baker/src/model-baker/Baker.cpp b/libraries/model-baker/src/model-baker/Baker.cpp
index dfb18eef86..ab41914d08 100644
--- a/libraries/model-baker/src/model-baker/Baker.cpp
+++ b/libraries/model-baker/src/model-baker/Baker.cpp
@@ -111,6 +111,7 @@ namespace baker {
             hfmModelOut->joints = QVector<hfm::Joint>::fromStdVector(input.get2());
             hfmModelOut->jointRotationOffsets = input.get3();
             hfmModelOut->jointIndices = input.get4();
+            hfmModelOut->computeKdops();
             output = hfmModelOut;
         }
     };
diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp
index 66ce5f32bf..02dc6e3b4d 100755
--- a/libraries/physics/src/CharacterController.cpp
+++ b/libraries/physics/src/CharacterController.cpp
@@ -436,7 +436,7 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const
     float z = scale.z;
     float radius = 0.5f * sqrtf(0.5f * (x * x + z * z));
     float halfHeight = 0.5f * scale.y - radius;
-    float MIN_HALF_HEIGHT = 0.1f;
+    float MIN_HALF_HEIGHT = 0.0f;
     if (halfHeight < MIN_HALF_HEIGHT) {
         halfHeight = MIN_HALF_HEIGHT;
     }