void SkeletonModel::setJointStates(QVector<JointState> states) { Model::setJointStates(states); // Determine the default eye position for avatar scale = 1.0 int headJointIndex = _geometry->getFBXGeometry().headJointIndex; if (0 <= headJointIndex && headJointIndex < _jointStates.size()) { glm::vec3 leftEyePosition, rightEyePosition; getEyeModelPositions(leftEyePosition, rightEyePosition); glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f; int rootJointIndex = _geometry->getFBXGeometry().rootJointIndex; glm::vec3 rootModelPosition; getJointPosition(rootJointIndex, rootModelPosition); _defaultEyeModelPosition = midEyePosition - rootModelPosition; _defaultEyeModelPosition.z = -_defaultEyeModelPosition.z; // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; } // the SkeletonModel override of updateJointState() will clear the translation part // of its root joint and we need that done before we try to build shapes hence we // recompute all joint transforms at this time. for (int i = 0; i < _jointStates.size(); i++) { updateJointState(i); } clearShapes(); if (_enableShapes) { buildShapes(); } }
void SkeletonModel::initJointStates(QVector<JointState> states) { Model::initJointStates(states); // Determine the default eye position for avatar scale = 1.0 int headJointIndex = _geometry->getFBXGeometry().headJointIndex; if (0 <= headJointIndex && headJointIndex < _jointStates.size()) { glm::vec3 leftEyePosition, rightEyePosition; getEyeModelPositions(leftEyePosition, rightEyePosition); glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f; int rootJointIndex = _geometry->getFBXGeometry().rootJointIndex; glm::vec3 rootModelPosition; getJointPosition(rootJointIndex, rootModelPosition); _defaultEyeModelPosition = midEyePosition - rootModelPosition; _defaultEyeModelPosition.z = -_defaultEyeModelPosition.z; // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; } // the SkeletonModel override of updateJointState() will clear the translation part // of its root joint and we need that done before we try to build shapes hence we // recompute all joint transforms at this time. for (int i = 0; i < _jointStates.size(); i++) { updateJointState(i); } clearShapes(); if (_enableShapes) { buildShapes(); } Extents meshExtents = getMeshExtents(); _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z); _headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP); _owningAvatar->rebuildSkeletonBody(); emit skeletonLoaded(); }
void SkeletonModel::stretchArm(int jointIndex, const glm::vec3& position) { // find out where the hand is pointing glm::quat handRotation; getJointRotation(jointIndex, handRotation, true); const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::vec3 forwardVector(jointIndex == geometry.rightHandJointIndex ? -1.0f : 1.0f, 0.0f, 0.0f); glm::vec3 handVector = handRotation * forwardVector; // align elbow with hand const FBXJoint& joint = geometry.joints.at(jointIndex); if (joint.parentIndex == -1) { return; } glm::quat elbowRotation; getJointRotation(joint.parentIndex, elbowRotation, true); applyRotationDelta(joint.parentIndex, rotationBetween(elbowRotation * forwardVector, handVector), false); // set position according to normal length float scale = extractUniformScale(_scale); glm::vec3 handPosition = position - _translation; glm::vec3 elbowPosition = handPosition - handVector * joint.distanceToParent * scale; // set shoulder orientation to point to elbow const FBXJoint& parentJoint = geometry.joints.at(joint.parentIndex); if (parentJoint.parentIndex == -1) { return; } glm::quat shoulderRotation; getJointRotation(parentJoint.parentIndex, shoulderRotation, true); applyRotationDelta(parentJoint.parentIndex, rotationBetween(shoulderRotation * forwardVector, elbowPosition - extractTranslation(_jointStates.at(parentJoint.parentIndex).transform)), false); // update the shoulder state updateJointState(parentJoint.parentIndex); // adjust the elbow's local translation setJointTranslation(joint.parentIndex, elbowPosition); }