diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index f3603e011c..c42554becd 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -141,7 +141,8 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector& fingerJoin float sign = (jointIndex == geometry.rightHandJointIndex) ? 1.0f : -1.0f; glm::quat palmRotation; getJointRotation(jointIndex, palmRotation, true); - palmRotation = rotationBetween(palmRotation * geometry.palmDirection, palm.getNormal()) * palmRotation; + applyRotationDelta(jointIndex, rotationBetween(palmRotation * geometry.palmDirection, palm.getNormal())); + getJointRotation(jointIndex, palmRotation, true); // sort the finger indices by raw x, get the average direction QVector fingerIndices; @@ -161,9 +162,9 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector& fingerJoin // rotate palm according to average finger direction float directionLength = glm::length(direction); if (directionLength > EPSILON) { - palmRotation = rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction) * palmRotation; + applyRotationDelta(jointIndex, rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction)); + getJointRotation(jointIndex, palmRotation, true); } - setJointRotation(jointIndex, palmRotation, true); // no point in continuing if there are no fingers if (palm.getNumFingers() == 0 || fingerJointIndices.isEmpty()) { diff --git a/interface/src/renderer/FBXReader.cpp b/interface/src/renderer/FBXReader.cpp index 042692c3e1..46a677c516 100644 --- a/interface/src/renderer/FBXReader.cpp +++ b/interface/src/renderer/FBXReader.cpp @@ -875,9 +875,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) glm::vec3 preRotation, rotation, postRotation; glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f); glm::vec3 scalePivot, rotationPivot; + bool rotationMinX = false, rotationMinY = false, rotationMinZ = false; + bool rotationMaxX = false, rotationMaxY = false, rotationMaxZ = false; + glm::vec3 rotationMin, rotationMax; FBXModel model = { name, -1 }; - model.rotationMin = glm::vec3(-180.0f, -180.0f, -180.0f); - model.rotationMax = glm::vec3(180.0f, 180.0f, 180.0f); foreach (const FBXNode& subobject, object.children) { bool properties = false; QByteArray propertyName; @@ -920,10 +921,28 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) scale = getVec3(property.properties, index); } else if (property.properties.at(0) == "RotationMin") { - model.rotationMin = getVec3(property.properties, index); + rotationMin = getVec3(property.properties, index); } else if (property.properties.at(0) == "RotationMax") { - model.rotationMax = getVec3(property.properties, index); + rotationMax = getVec3(property.properties, index); + + } else if (property.properties.at(0) == "RotationMinX") { + rotationMinX = property.properties.at(index).toBool(); + + } else if (property.properties.at(0) == "RotationMinY") { + rotationMinY = property.properties.at(index).toBool(); + + } else if (property.properties.at(0) == "RotationMinZ") { + rotationMinZ = property.properties.at(index).toBool(); + + } else if (property.properties.at(0) == "RotationMaxX") { + rotationMaxX = property.properties.at(index).toBool(); + + } else if (property.properties.at(0) == "RotationMaxY") { + rotationMaxY = property.properties.at(index).toBool(); + + } else if (property.properties.at(0) == "RotationMaxZ") { + rotationMaxZ = property.properties.at(index).toBool(); } } } @@ -940,6 +959,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) model.postRotation = glm::quat(glm::radians(postRotation)); model.postTransform = glm::translate(-rotationPivot) * glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot); + model.rotationMin = glm::vec3(rotationMinX ? rotationMin.x : -180.0f, + rotationMinY ? rotationMin.y : -180.0f, rotationMinZ ? rotationMin.z : -180.0f); + model.rotationMax = glm::vec3(rotationMaxX ? rotationMax.x : 180.0f, + rotationMaxY ? rotationMax.y : 180.0f, rotationMaxZ ? rotationMax.z : 180.0f); models.insert(getID(object.properties), model); } else if (object.name == "Texture") { diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index cadffe448d..a5c4a1e9c5 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -686,6 +686,21 @@ float Model::getLimbLength(int jointIndex) const { return length; } +void Model::applyRotationDelta(int jointIndex, const glm::quat& delta) { + JointState& state = _jointStates[jointIndex]; + const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex]; + if (joint.rotationMin == glm::vec3(-180.0f, -180.0f, -180.0f) && joint.rotationMax == glm::vec3(180.0f, 180.0f, 180.0f)) { + // no constraints + state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation; + state.combinedRotation = delta * state.combinedRotation; + return; + } + glm::quat newRotation = glm::quat(glm::radians(glm::clamp(safeEulerAngles(state.rotation * + glm::inverse(state.combinedRotation) * delta * state.combinedRotation), joint.rotationMin, joint.rotationMax))); + state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation; + state.rotation = newRotation; +} + void Model::setJointTranslation(int jointIndex, int parentIndex, int childIndex, const glm::vec3& translation) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); JointState& state = _jointStates[jointIndex]; @@ -705,21 +720,6 @@ void Model::setJointTranslation(int jointIndex, int parentIndex, int childIndex, ::setTranslation(state.transform, translation); } -void Model::applyRotationDelta(int jointIndex, const glm::quat& delta) { - JointState& state = _jointStates[jointIndex]; - const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex]; - if (joint.rotationMin == glm::vec3(-180.0f, -180.0f, -180.0f) && joint.rotationMax == glm::vec3(180.0f, 180.0f, 180.0f)) { - // no constraints - state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation; - state.combinedRotation = delta * state.combinedRotation; - return; - } - glm::quat newRotation = glm::quat(glm::radians(glm::clamp(safeEulerAngles(state.rotation * - glm::inverse(state.combinedRotation) * delta * state.combinedRotation), joint.rotationMin, joint.rotationMax))); - state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation; - state.rotation = newRotation; -} - void Model::deleteGeometry() { foreach (Model* attachment, _attachments) { delete attachment; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index c99788b03f..327baa6b6b 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -156,10 +156,11 @@ protected: /// first free ancestor. float getLimbLength(int jointIndex) const; + void applyRotationDelta(int jointIndex, const glm::quat& delta); + private: void setJointTranslation(int jointIndex, int parentIndex, int childIndex, const glm::vec3& translation); - void applyRotationDelta(int jointIndex, const glm::quat& delta); void deleteGeometry();