diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index aed313f54e..79bd7431cc 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -300,8 +300,6 @@ QString getString(const QVariant& value) { return list.isEmpty() ? value.toString() : list.at(0).toString(); } -typedef std::vector ShapeVertices; - class AnimationCurve { public: QVector values; @@ -1352,8 +1350,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const } // NOTE: shapeVertices are in joint-frame - std::vector shapeVertices; - shapeVertices.resize(std::max(1, hfmModel.joints.size()) ); + hfmModel.shapeVertices.resize(std::max(1, hfmModel.joints.size()) ); hfmModel.bindExtents.reset(); hfmModel.meshExtents.reset(); @@ -1527,7 +1524,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const HFMJoint& joint = hfmModel.joints[jointIndex]; 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); @@ -1601,7 +1598,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const // 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)); @@ -1621,54 +1618,6 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const 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::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 cd1bdf01d4..8c60169289 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; // The version of the Draco mesh binary data itself. See also: FBX_DRACO_MESH_VERSION in FBX.h static const int DRACO_MESH_VERSION = 2; @@ -327,10 +329,12 @@ public: /// given a meshIndex this will return the name of the model that mesh belongs to if known QString getModelNameOfMesh(int meshIndex) const; + void computeKdops(); QList blendshapeChannelNames; QMap jointRotationOffsets; + std::vector shapeVertices; FlowData flowData; }; diff --git a/libraries/model-baker/src/model-baker/Baker.cpp b/libraries/model-baker/src/model-baker/Baker.cpp index 536255a841..70269c6401 100644 --- a/libraries/model-baker/src/model-baker/Baker.cpp +++ b/libraries/model-baker/src/model-baker/Baker.cpp @@ -113,6 +113,7 @@ namespace baker { hfmModelOut->jointRotationOffsets = input.get3(); hfmModelOut->jointIndices = input.get4(); hfmModelOut->flowData = input.get5(); + hfmModelOut->computeKdops(); output = hfmModelOut; } }; diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index a5f1a0598f..247550a9d0 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; }