diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4e58163a86..a056819a82 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -246,7 +246,7 @@ bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) { const float HEAD_SPHERE_RADIUS = 0.1f; glm::vec3 theirLookAt = dynamic_pointer_cast(avatar)->getHead()->getLookAtPosition(); glm::vec3 myEyePosition = getHead()->getEyePosition(); - + return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getScale()); } @@ -496,8 +496,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { eyeDiameter = DEFAULT_EYE_DIAMETER; } - DependencyManager::get()->renderSolidSphereInstance(batch, - Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), + DependencyManager::get()->renderSolidSphereInstance(batch, + Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), glm::vec4(LOOKING_AT_ME_COLOR, alpha)); position = getHead()->getRightEyePosition(); @@ -507,7 +507,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { eyeDiameter = DEFAULT_EYE_DIAMETER; } DependencyManager::get()->renderSolidSphereInstance(batch, - Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), + Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), glm::vec4(LOOKING_AT_ME_COLOR, alpha)); } @@ -555,7 +555,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { auto& frustum = *renderArgs->_viewFrustum; auto textPosition = getDisplayNamePosition(); - + if (frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE) { renderDisplayName(batch, frustum, textPosition); } @@ -611,7 +611,7 @@ void Avatar::fixupModelsInScene() { void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) { fixupModelsInScene(); - + { if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { // render the billboard until both models are loaded @@ -675,7 +675,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { glm::quat rotation = getOrientation(); glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - _position); rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f)); - + // compute the size from the billboard camera parameters and scale float size = getBillboardSize(); @@ -688,7 +688,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { glm::vec2 bottomRight(1.0f, 1.0f); glm::vec2 texCoordTopLeft(0.0f, 0.0f); glm::vec2 texCoordBottomRight(1.0f, 1.0f); - + gpu::Batch& batch = *renderArgs->_batch; PROFILE_RANGE_BATCH(batch, __FUNCTION__); batch.setResourceTexture(0, _billboardTexture->getGPUTexture()); @@ -721,29 +721,29 @@ glm::vec3 Avatar::getDisplayNamePosition() const { glm::vec3 namePosition(0.0f); glm::vec3 bodyUpDirection = getBodyUpDirection(); DEBUG_VALUE("bodyUpDirection =", bodyUpDirection); - + if (getSkeletonModel().getNeckPosition(namePosition)) { float headHeight = getHeadHeight(); DEBUG_VALUE("namePosition =", namePosition); DEBUG_VALUE("headHeight =", headHeight); - + static const float SLIGHTLY_ABOVE = 1.1f; namePosition += bodyUpDirection * headHeight * SLIGHTLY_ABOVE; } else { const float HEAD_PROPORTION = 0.75f; float billboardSize = getBillboardSize(); - + DEBUG_VALUE("_position =", _position); DEBUG_VALUE("billboardSize =", billboardSize); namePosition = _position + bodyUpDirection * (billboardSize * HEAD_PROPORTION); } - + if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) { qCWarning(interfaceapp) << "Invalid display name position" << namePosition << ", setting is to (0.0f, 0.5f, 0.0f)"; namePosition = glm::vec3(0.0f, 0.5f, 0.0f); } - + return namePosition; } @@ -751,16 +751,16 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons Q_ASSERT_X(frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE, "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); glm::vec3 toFrustum = frustum.getPosition() - textPosition; - + // Compute orientation // If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees const float yawRotation = (toFrustum.x == 0.0f && toFrustum.z == 0.0f) ? 0.0f : glm::atan(toFrustum.x, toFrustum.z); glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); - + // Compute correct scale to apply static const float DESIRED_HEIGHT_RAD = glm::radians(1.5f); float scale = glm::length(toFrustum) * glm::tan(DESIRED_HEIGHT_RAD); - + // Set transform Transform result; result.setTranslation(textPosition); @@ -768,7 +768,7 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons result.setScale(scale); // raise by half the scale up so that textPosition be the bottom result.postTranslate(Vectors::UP / 2.0f); - + return result; } @@ -796,14 +796,14 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co } renderedDisplayName += statsFormat.arg(QString::number(kilobitsPerSecond, 'f', 2)).arg(getReceiveRate()); } - + // Compute display name extent/position offset const glm::vec2 extent = renderer->computeExtent(renderedDisplayName); if (!glm::any(glm::isCompNull(extent, EPSILON))) { const QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y); const int text_x = -nameDynamicRect.width() / 2; const int text_y = -nameDynamicRect.height() / 2; - + // Compute background position/size static const float SLIGHTLY_IN_FRONT = 0.1f; static const float BORDER_RELATIVE_SIZE = 0.1f; @@ -814,12 +814,12 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co const int width = nameDynamicRect.width() + 2.0f * border; const int height = nameDynamicRect.height() + 2.0f * border; const int bevelDistance = BEVEL_FACTOR * height; - + // Display name and background colors glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f, (_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA); - + // Compute display name transform auto textTransform = calculateDisplayNameTransform(frustum, textPosition); // Test on extent above insures abs(height) > 0.0f @@ -835,7 +835,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co // Render actual name QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); - + // Render text slightly in front to avoid z-fighting textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); batch.setModelTransform(textTransform); @@ -937,52 +937,6 @@ glm::vec3 Avatar::getJointPosition(const QString& name) const { return position; } -glm::quat Avatar::getJointCombinedRotation(int index) const { - if (QThread::currentThread() != thread()) { - glm::quat rotation; - QMetaObject::invokeMethod(const_cast(this), "getJointCombinedRotation", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(glm::quat, rotation), Q_ARG(const int, index)); - return rotation; - } - glm::quat rotation; - _skeletonModel.getJointCombinedRotation(index, rotation); - return rotation; -} - -glm::quat Avatar::getJointCombinedRotation(const QString& name) const { - if (QThread::currentThread() != thread()) { - glm::quat rotation; - QMetaObject::invokeMethod(const_cast(this), "getJointCombinedRotation", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(glm::quat, rotation), Q_ARG(const QString&, name)); - return rotation; - } - glm::quat rotation; - _skeletonModel.getJointCombinedRotation(getJointIndex(name), rotation); - return rotation; -} - -const float SCRIPT_PRIORITY = DEFAULT_PRIORITY + 1.0f; - -void Avatar::setJointModelPositionAndOrientation(int index, glm::vec3 position, const glm::quat& rotation) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(const_cast(this), "setJointModelPositionAndOrientation", - Qt::AutoConnection, Q_ARG(const int, index), Q_ARG(const glm::vec3, position), - Q_ARG(const glm::quat&, rotation)); - } else { - _skeletonModel.inverseKinematics(index, position, rotation, SCRIPT_PRIORITY); - } -} - -void Avatar::setJointModelPositionAndOrientation(const QString& name, glm::vec3 position, const glm::quat& rotation) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(const_cast(this), "setJointModelPositionAndOrientation", - Qt::AutoConnection, Q_ARG(const QString&, name), Q_ARG(const glm::vec3, position), - Q_ARG(const glm::quat&, rotation)); - } else { - _skeletonModel.inverseKinematics(getJointIndex(name), position, rotation, SCRIPT_PRIORITY); - } -} - void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { //Scale a world space vector as if it was relative to the position positionToScale = _position + _scale * (positionToScale - _position); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 2d0ab029ef..543c079d7a 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -66,7 +66,7 @@ public: typedef render::Payload Payload; typedef std::shared_ptr PayloadPointer; - + void init(); void simulate(float deltaTime); @@ -101,20 +101,20 @@ public: float getLODDistance() const; virtual bool isMyAvatar() const { return false; } - + virtual QVector getJointRotations() const; virtual glm::quat getJointRotation(int index) const; virtual glm::vec3 getJointTranslation(int index) const; virtual int getJointIndex(const QString& name) const; virtual QStringList getJointNames() const; - + virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); virtual void setAttachmentData(const QVector& attachmentData); virtual void setBillboard(const QByteArray& billboard); void setShowDisplayName(bool showDisplayName); - + virtual int parseDataFromBuffer(const QByteArray& buffer); static void renderJointConnectingCone( gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, @@ -125,16 +125,9 @@ public: Q_INVOKABLE void setSkeletonOffset(const glm::vec3& offset); Q_INVOKABLE glm::vec3 getSkeletonOffset() { return _skeletonOffset; } virtual glm::vec3 getSkeletonPosition() const; - + Q_INVOKABLE glm::vec3 getJointPosition(int index) const; Q_INVOKABLE glm::vec3 getJointPosition(const QString& name) const; - Q_INVOKABLE glm::quat getJointCombinedRotation(int index) const; - Q_INVOKABLE glm::quat getJointCombinedRotation(const QString& name) const; - - Q_INVOKABLE void setJointModelPositionAndOrientation(int index, const glm::vec3 position, const glm::quat& rotation); - Q_INVOKABLE void setJointModelPositionAndOrientation(const QString& name, const glm::vec3 position, - const glm::quat& rotation); - Q_INVOKABLE glm::vec3 getNeckPosition() const; Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; } @@ -195,9 +188,9 @@ protected: glm::vec3 _worldUpDirection; float _stringLength; bool _moving; ///< set when position is changing - + bool isLookingAtMe(AvatarSharedPointer avatar); - + // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fb72adafa1..935a18a3d1 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -897,8 +897,8 @@ glm::vec3 MyAvatar::getDefaultEyePosition() const { return getPosition() + getWorldAlignedOrientation() * _skeletonModel.getDefaultEyeModelPosition(); } -const float SCRIPT_PRIORITY = DEFAULT_PRIORITY + 1.0f; -const float RECORDER_PRIORITY = SCRIPT_PRIORITY + 1.0f; +const float SCRIPT_PRIORITY = 1.0f + 1.0f; +const float RECORDER_PRIORITY = 1.0f + 1.0f; void MyAvatar::setJointRotations(QVector jointRotations) { int numStates = glm::min(_skeletonModel.getJointStateCount(), jointRotations.size()); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 8ee4e83ac4..5ffc6d7b1e 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -44,23 +44,7 @@ void SkeletonModel::initJointStates() { const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 geometryOffset = geometry.offset; glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); - - int rootJointIndex = geometry.rootJointIndex; - int leftHandJointIndex = geometry.leftHandJointIndex; - int leftElbowJointIndex = leftHandJointIndex >= 0 ? geometry.joints.at(leftHandJointIndex).parentIndex : -1; - int leftShoulderJointIndex = leftElbowJointIndex >= 0 ? geometry.joints.at(leftElbowJointIndex).parentIndex : -1; - int rightHandJointIndex = geometry.rightHandJointIndex; - int rightElbowJointIndex = rightHandJointIndex >= 0 ? geometry.joints.at(rightHandJointIndex).parentIndex : -1; - int rightShoulderJointIndex = rightElbowJointIndex >= 0 ? geometry.joints.at(rightElbowJointIndex).parentIndex : -1; - - _rig->initJointStates(geometry, modelOffset, - rootJointIndex, - leftHandJointIndex, - leftElbowJointIndex, - leftShoulderJointIndex, - rightHandJointIndex, - rightElbowJointIndex, - rightShoulderJointIndex); + _rig->initJointStates(geometry, modelOffset); // Determine the default eye position for avatar scale = 1.0 int headJointIndex = _geometry->getFBXGeometry().headJointIndex; @@ -100,7 +84,6 @@ void SkeletonModel::initJointStates() { emit skeletonLoaded(); } -const float PALM_PRIORITY = DEFAULT_PRIORITY; // Called within Model::simulate call, below. void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { Head* head = _owningAvatar->getHead(); diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index ae73d380e6..55e56ae503 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -23,13 +23,6 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { for (auto& joint : fbxGeometry.joints) { joints.push_back(joint); } - - // AJT: REMOVE - /* - AnimPose geometryOffset(fbxGeometry.offset); - buildSkeletonFromJoints(joints, geometryOffset); - */ - buildSkeletonFromJoints(joints); } @@ -147,37 +140,8 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints) } } } - - // AJT: REMOVE - /* - // now we want to normalize scale from geometryOffset to all poses. - // This will ensure our bone translations will be in meters, even if the model was authored with some other unit of mesure. - normalizeScale(geometryOffset, _relativeBindPoses, _absoluteBindPoses); - normalizeScale(geometryOffset, _relativeDefaultPoses, _absoluteDefaultPoses); - */ } -/* -// AJT: REMOVE -void AnimSkeleton::normalizeScale(const AnimPose& geometryOffset, AnimPoseVec& relPoses, AnimPoseVec& absPoses) const { - for (auto& absPose : absPoses) { - absPose.trans = (geometryOffset * absPose).trans; - } - - // re-compute relative poses based on the modified absolute poses. - for (size_t i = 0; i < relPoses.size(); i++) { - int parentIndex = getParentIndex(i); - if (parentIndex >= 0) { - relPoses[i] = absPoses[parentIndex].inverse() * absPoses[i]; - } else { - relPoses[i] = absPoses[i]; - } - } -} -*/ - -#define DUMP_FBX_JOINTS - #ifndef NDEBUG void AnimSkeleton::dump() const { qCDebug(animation) << "["; diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 8711f24587..0e0b07a8fd 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -55,8 +55,6 @@ public: protected: void buildSkeletonFromJoints(const std::vector& joints); - // AJT: REMOVE - //void normalizeScale(const AnimPose& geometryOffset, AnimPoseVec& relPoses, AnimPoseVec& absPoses) const; std::vector _joints; AnimPoseVec _absoluteBindPoses; diff --git a/libraries/animation/src/AvatarRig.cpp b/libraries/animation/src/AvatarRig.cpp index 0082acf03d..aec696327e 100644 --- a/libraries/animation/src/AvatarRig.cpp +++ b/libraries/animation/src/AvatarRig.cpp @@ -11,86 +11,7 @@ #include "AvatarRig.h" -// AJT: REMOVE, this should no longer be used -void AvatarRig::setHandPosition(int jointIndex, - const glm::vec3& position, const glm::quat& rotation, - float scale, float priority) { - bool rightHand = (jointIndex == _rightHandJointIndex); - - int elbowJointIndex = rightHand ? _rightElbowJointIndex : _leftElbowJointIndex; - int shoulderJointIndex = rightHand ? _rightShoulderJointIndex : _leftShoulderJointIndex; - - // this algorithm is from sample code from sixense - if (elbowJointIndex == -1 || shoulderJointIndex == -1) { - return; - } - - glm::vec3 shoulderPosition; - if (!getJointPosition(shoulderJointIndex, shoulderPosition)) { - return; - } - - // precomputed lengths - float upperArmLength = _jointStates[elbowJointIndex].getDistanceToParent() * scale; - float lowerArmLength = _jointStates[jointIndex].getDistanceToParent() * scale; - - // first set wrist position - glm::vec3 wristPosition = position; - - glm::vec3 shoulderToWrist = wristPosition - shoulderPosition; - float distanceToWrist = glm::length(shoulderToWrist); - - // prevent gimbal lock - if (distanceToWrist > upperArmLength + lowerArmLength - EPSILON) { - distanceToWrist = upperArmLength + lowerArmLength - EPSILON; - shoulderToWrist = glm::normalize(shoulderToWrist) * distanceToWrist; - wristPosition = shoulderPosition + shoulderToWrist; - } - - // cosine of angle from upper arm to hand vector - float cosA = (upperArmLength * upperArmLength + distanceToWrist * distanceToWrist - lowerArmLength * lowerArmLength) / - (2 * upperArmLength * distanceToWrist); - float mid = upperArmLength * cosA; - float height = sqrt(upperArmLength * upperArmLength + mid * mid - 2 * upperArmLength * mid * cosA); - - // direction of the elbow - glm::vec3 handNormal = glm::cross(rotation * glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow rotating with wrist - glm::vec3 relaxedNormal = glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow pointing straight down - const float NORMAL_WEIGHT = 0.5f; - glm::vec3 finalNormal = glm::mix(relaxedNormal, handNormal, NORMAL_WEIGHT); - - if (rightHand ? (finalNormal.y > 0.0f) : (finalNormal.y < 0.0f)) { - finalNormal.y = 0.0f; // dont allow elbows to point inward (y is vertical axis) - } - - glm::vec3 tangent = glm::normalize(glm::cross(shoulderToWrist, finalNormal)); - - // ik solution - glm::vec3 elbowPosition = shoulderPosition + glm::normalize(shoulderToWrist) * mid - tangent * height; - glm::vec3 forwardVector(rightHand ? -1.0f : 1.0f, 0.0f, 0.0f); - glm::quat shoulderRotation = rotationBetween(forwardVector, elbowPosition - shoulderPosition); - - setJointRotationInBindFrame(shoulderJointIndex, shoulderRotation, priority); - setJointRotationInBindFrame(elbowJointIndex, - rotationBetween(shoulderRotation * forwardVector, wristPosition - elbowPosition) * - shoulderRotation, priority); - setJointRotationInBindFrame(jointIndex, rotation, priority); -} - void AvatarRig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) { - // AJT: LEGACY - { - - if (index != -1 && index < _jointStates.size()) { - JointState& state = _jointStates[index]; - if (valid) { - state.setTranslation(translation, priority); - } else { - state.restoreTranslation(1.0f, priority); - } - } - } - if (index >= 0 && index < (int)_overrideFlags.size()) { if (valid) { assert(_overrideFlags.size() == _overridePoses.size()); @@ -100,23 +21,7 @@ void AvatarRig::setJointTranslation(int index, bool valid, const glm::vec3& tran } } - void AvatarRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { - // AJT: LEGACY - { - if (index != -1 && index < _jointStates.size()) { - - JointState& state = _jointStates[index]; - if (valid) { - state.setRotationInConstrainedFrame(rotation, priority); - state.setTranslation(translation, priority); - } else { - state.restoreRotation(1.0f, priority); - state.restoreTranslation(1.0f, priority); - } - } - } - if (index >= 0 && index < (int)_overrideFlags.size()) { assert(_overrideFlags.size() == _overridePoses.size()); _overrideFlags[index] = true; diff --git a/libraries/animation/src/AvatarRig.h b/libraries/animation/src/AvatarRig.h index 0fabacfe91..230647998a 100644 --- a/libraries/animation/src/AvatarRig.h +++ b/libraries/animation/src/AvatarRig.h @@ -21,8 +21,6 @@ class AvatarRig : public Rig { public: ~AvatarRig() {} - virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, - float scale, float priority); virtual void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority); virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); }; diff --git a/libraries/animation/src/EntityRig.cpp b/libraries/animation/src/EntityRig.cpp index ff89c9d50b..e96e5d58d5 100644 --- a/libraries/animation/src/EntityRig.cpp +++ b/libraries/animation/src/EntityRig.cpp @@ -12,20 +12,6 @@ #include "EntityRig.h" void EntityRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { - // AJT: LEGACY - { - if (index != -1 && index < _jointStates.size()) { - JointState& state = _jointStates[index]; - if (valid) { - state.setRotationInConstrainedFrame(rotation, priority); - // state.setTranslation(translation, priority); - } else { - state.restoreRotation(1.0f, priority); - // state.restoreTranslation(1.0f, priority); - } - } - } - if (index >= 0 && index < (int)_overrideFlags.size()) { assert(_overrideFlags.size() == _overridePoses.size()); _overrideFlags[index] = true; diff --git a/libraries/animation/src/EntityRig.h b/libraries/animation/src/EntityRig.h index e5d1f005d8..d283816a1a 100644 --- a/libraries/animation/src/EntityRig.h +++ b/libraries/animation/src/EntityRig.h @@ -21,8 +21,6 @@ class EntityRig : public Rig { public: ~EntityRig() {} - virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, - float scale, float priority) {} virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); }; diff --git a/libraries/animation/src/JointState.cpp b/libraries/animation/src/JointState.cpp deleted file mode 100644 index 4c4e40119a..0000000000 --- a/libraries/animation/src/JointState.cpp +++ /dev/null @@ -1,228 +0,0 @@ -// -// JointState.cpp -// libraries/animation/src/ -// -// Created by Andrzej Kapolka on 10/18/13. -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include - -#include - -#include "JointState.h" - -JointState::~JointState() { -} - -void JointState::copyState(const JointState& other) { - _transformChanged = other._transformChanged; - _transform = other._transform; - _rotationIsValid = other._rotationIsValid; - _rotation = other._rotation; - _rotationInConstrainedFrame = other._rotationInConstrainedFrame; - _positionInParentFrame = other._positionInParentFrame; - _distanceToParent = other._distanceToParent; - _animationPriority = other._animationPriority; - - _name = other._name; - _isFree = other._isFree; - _parentIndex = other._parentIndex; - _defaultRotation = other._defaultRotation; - _defaultTranslation = other._defaultTranslation; - _inverseDefaultRotation = other._inverseDefaultRotation; - _translation = other._translation; - _preRotation = other._preRotation; - _postRotation = other._postRotation; - _preTransform = other._preTransform; - _postTransform = other._postTransform; - _inverseBindRotation = other._inverseBindRotation; -} -JointState::JointState(const FBXJoint& joint) { - _rotationInConstrainedFrame = joint.rotation; - _name = joint.name; - _isFree = joint.isFree; - _parentIndex = joint.parentIndex; - _translation = joint.translation; - _defaultRotation = joint.rotation; - _defaultTranslation = _translation; - _inverseDefaultRotation = joint.inverseDefaultRotation; - _preRotation = joint.preRotation; - _postRotation = joint.postRotation; - _preTransform = joint.preTransform; - _postTransform = joint.postTransform; - _inverseBindRotation = joint.inverseBindRotation; -} - -void JointState::buildConstraint() { -} - -glm::quat JointState::getRotation() const { - if (!_rotationIsValid) { - const_cast(this)->_rotation = extractRotation(_transform); - const_cast(this)->_rotationIsValid = true; - } - - return _rotation; -} - -void JointState::initTransform(const glm::mat4& parentTransform) { - - //_unitsScale = extractScale(parentTransform); - - computeTransform(parentTransform); - _positionInParentFrame = glm::inverse(extractRotation(parentTransform)) * (extractTranslation(_transform) - extractTranslation(parentTransform)); - _distanceToParent = glm::length(_positionInParentFrame); -} - -void JointState::computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged, bool synchronousRotationCompute) { - if (!parentTransformChanged && !_transformChanged) { - return; - } - - glm::quat rotationInParentFrame = _preRotation * _rotationInConstrainedFrame * _postRotation; - glm::mat4 transformInParentFrame = _preTransform * glm::mat4_cast(rotationInParentFrame) * _postTransform; - glm::mat4 newTransform = parentTransform * glm::translate(_translation) * transformInParentFrame; - - if (newTransform != _transform) { - _transform = newTransform; - _transformChanged = true; - _rotationIsValid = false; - } -} - -glm::quat JointState::getRotationInBindFrame() const { - return getRotation() * _inverseBindRotation; -} - -glm::quat JointState::getRotationInParentFrame() const { - return _preRotation * _rotationInConstrainedFrame * _postRotation; -} - -void JointState::restoreRotation(float fraction, float priority) { - if (priority == _animationPriority || _animationPriority == 0.0f) { - setRotationInConstrainedFrameInternal(safeMix(_rotationInConstrainedFrame, _defaultRotation, fraction)); - _animationPriority = 0.0f; - } -} - -void JointState::restoreTranslation(float fraction, float priority) { - if (priority == _animationPriority || _animationPriority == 0.0f) { - _translation = _translation * (1.0f - fraction) + _defaultTranslation * fraction; - _animationPriority = 0.0f; - } -} - -void JointState::setRotationInBindFrame(const glm::quat& rotation, float priority) { - // rotation is from bind- to model-frame - if (priority >= _animationPriority) { - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * rotation * glm::inverse(_inverseBindRotation); - setRotationInConstrainedFrameInternal(targetRotation); - _animationPriority = priority; - } -} - -void JointState::setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority) { - // rotation is from bind- to model-frame - if (priority >= _animationPriority) { - glm::quat parentRotation = computeParentRotation(); - - // R = Rp * Rpre * r * Rpost - // R' = Rp * Rpre * r' * Rpost - // r' = (Rp * Rpre)^ * R' * Rpost^ - glm::quat targetRotation = glm::inverse(parentRotation * _preRotation) * rotationInModelFrame * glm::inverse(_postRotation); - _rotationInConstrainedFrame = glm::normalize(targetRotation); - _transformChanged = true; - _animationPriority = priority; - } -} - -void JointState::clearTransformTranslation() { - _transform[3][0] = 0.0f; - _transform[3][1] = 0.0f; - _transform[3][2] = 0.0f; - _transformChanged = true; -} - -void JointState::applyRotationDelta(const glm::quat& delta, float priority) { - // NOTE: delta is in model-frame - if (priority < _animationPriority || delta == glm::quat()) { - return; - } - _animationPriority = priority; - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * delta * getRotation(); - setRotationInConstrainedFrameInternal(targetRotation); -} - -/// Applies delta rotation to joint but mixes a little bit of the default pose as well. -/// This helps keep an IK solution stable. -void JointState::mixRotationDelta(const glm::quat& delta, float mixFactor, float priority) { - // NOTE: delta is in model-frame - if (priority < _animationPriority) { - return; - } - _animationPriority = priority; - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * delta * getRotation(); - if (mixFactor > 0.0f && mixFactor <= 1.0f) { - targetRotation = safeMix(targetRotation, _defaultRotation, mixFactor); - } - setRotationInConstrainedFrameInternal(targetRotation); -} - -glm::quat JointState::computeParentRotation() const { - // R = Rp * Rpre * r * Rpost - // Rp = R * (Rpre * r * Rpost)^ - return getRotation() * glm::inverse(_preRotation * _rotationInConstrainedFrame * _postRotation); -} - -void JointState::setRotationInConstrainedFrame(glm::quat targetRotation, float priority, float mix) { - if (priority >= _animationPriority || _animationPriority == 0.0f) { - auto rotation = (mix == 1.0f) ? targetRotation : safeMix(getRotationInConstrainedFrame(), targetRotation, mix); - setRotationInConstrainedFrameInternal(rotation); - _animationPriority = priority; - } -} - -void JointState::setTranslation(const glm::vec3& translation, float priority) { - if (priority >= _animationPriority || _animationPriority == 0.0f) { - _translation = translation / _unitsScale; - _transformChanged = true; - _animationPriority = priority; - } -} - -void JointState::setRotationInConstrainedFrameInternal(const glm::quat& targetRotation) { - if (_rotationInConstrainedFrame != targetRotation) { - glm::quat parentRotation = computeParentRotation(); - _rotationInConstrainedFrame = targetRotation; - _transformChanged = true; - // R' = Rp * Rpre * r' * Rpost - _rotation = parentRotation * _preRotation * _rotationInConstrainedFrame * _postRotation; - } -} - -bool JointState::rotationIsDefault(const glm::quat& rotation, float tolerance) const { - glm::quat defaultRotation = _defaultRotation; - return glm::abs(rotation.x - defaultRotation.x) < tolerance && - glm::abs(rotation.y - defaultRotation.y) < tolerance && - glm::abs(rotation.z - defaultRotation.z) < tolerance && - glm::abs(rotation.w - defaultRotation.w) < tolerance; -} - -bool JointState::translationIsDefault(const glm::vec3& translation, float tolerance) const { - return glm::distance(_defaultTranslation * _unitsScale, translation) < tolerance; -} - -glm::quat JointState::getDefaultRotationInParentFrame() const { - // NOTE: the result is constant and could be cached - return _preRotation * _defaultRotation * _postRotation; -} - -glm::vec3 JointState::getDefaultTranslationInConstrainedFrame() const { - return _defaultTranslation * _unitsScale; -} diff --git a/libraries/animation/src/JointState.h b/libraries/animation/src/JointState.h deleted file mode 100644 index 5dec7138b6..0000000000 --- a/libraries/animation/src/JointState.h +++ /dev/null @@ -1,148 +0,0 @@ -// -// JointState.h -// libraries/animation/src/ -// -// Created by Andrzej Kapolka on 10/18/13. -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_JointState_h -#define hifi_JointState_h - -#include -#include -#include - -#include -#include -#include - -const float DEFAULT_PRIORITY = 3.0f; - -class JointState { -public: - JointState() {} - JointState(const JointState& other) { copyState(other); } - JointState(const FBXJoint& joint); - ~JointState(); - JointState& operator=(const JointState& other) { copyState(other); return *this; } - void copyState(const JointState& state); - void buildConstraint(); - - void initTransform(const glm::mat4& parentTransform); - // if synchronousRotationCompute is true, then _transform is still computed synchronously, - // but _rotation will be asynchronously extracted - void computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged = true, bool synchronousRotationCompute = false); - - const glm::mat4& getTransform() const { return _transform; } - void resetTransformChanged() { _transformChanged = false; } - bool getTransformChanged() const { return _transformChanged; } - - glm::quat getRotation() const; - glm::vec3 getPosition() const { return extractTranslation(_transform); } - - /// \return rotation from bind to model frame - glm::quat getRotationInBindFrame() const; - - glm::quat getRotationInParentFrame() const; - const glm::vec3& getPositionInParentFrame() const { return _positionInParentFrame; } - float getDistanceToParent() const { return _distanceToParent; } - - int getParentIndex() const { return _parentIndex; } - - /// \param delta is in the model-frame - void applyRotationDelta(const glm::quat& delta, float priority = 1.0f); - - /// Applies delta rotation to joint but mixes a little bit of the default pose as well. - /// This helps keep an IK solution stable. - /// \param delta rotation change in model-frame - /// \param mixFactor fraction in range [0,1] of how much default pose to blend in (0 is none, 1 is all) - /// \param priority priority level of this animation blend - void mixRotationDelta(const glm::quat& delta, float mixFactor, float priority = 1.0f); - - /// Blends a fraciton of default pose into joint rotation. - /// \param fraction fraction in range [0,1] of how much default pose to blend in (0 is none, 1 is all) - /// \param priority priority level of this animation blend - void restoreRotation(float fraction, float priority); - - void restoreTranslation(float fraction, float priority); - - /// \param rotation is from bind- to model-frame - /// computes and sets new _rotationInConstrainedFrame - /// NOTE: the JointState's model-frame transform/rotation are NOT updated! - void setRotationInBindFrame(const glm::quat& rotation, float priority); - - /// \param rotationInModelRame is in model-frame - /// computes and sets new _rotationInConstrainedFrame to match rotationInModelFrame - /// NOTE: the JointState's model-frame transform/rotation are NOT updated! - void setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority); - - void setTranslation(const glm::vec3& translation, float priority); - - void setRotationInConstrainedFrame(glm::quat targetRotation, float priority, float mix = 1.0f); - - const glm::quat& getRotationInConstrainedFrame() const { return _rotationInConstrainedFrame; } - - bool rotationIsDefault(const glm::quat& rotation, float tolerance = EPSILON) const; - bool translationIsDefault(const glm::vec3& translation, float tolerance = EPSILON) const; - - glm::quat getDefaultRotationInParentFrame() const; - glm::vec3 getDefaultTranslationInConstrainedFrame() const; - - - void clearTransformTranslation(); - - /// \return parent model-frame rotation - // (used to keep _rotation consistent when modifying _rotationInWorldFrame directly) - glm::quat computeParentRotation() const; - - void setTransform(const glm::mat4& transform) { _transform = transform; } - - glm::vec3 getTranslation() const { return _translation * _unitsScale; } - const glm::mat4& getPreTransform() const { return _preTransform; } - const glm::mat4& getPostTransform() const { return _postTransform; } - const glm::quat& getPreRotation() const { return _preRotation; } - const glm::quat& getPostRotation() const { return _postRotation; } - const glm::quat& getDefaultRotation() const { return _defaultRotation; } - glm::vec3 getDefaultTranslation() const { return _defaultTranslation * _unitsScale; } - const glm::quat& getInverseDefaultRotation() const { return _inverseDefaultRotation; } - const QString& getName() const { return _name; } - bool getIsFree() const { return _isFree; } - float getAnimationPriority() const { return _animationPriority; } - void setAnimationPriority(float priority) { _animationPriority = priority; } - -private: - void setRotationInConstrainedFrameInternal(const glm::quat& targetRotation); - /// debug helper function - void loadBindRotation(); - - bool _transformChanged {true}; - bool _rotationIsValid {false}; - glm::vec3 _positionInParentFrame {0.0f}; // only changes when the Model is scaled - float _animationPriority {0.0f}; // the priority of the animation affecting this joint - float _distanceToParent {0.0f}; - - glm::mat4 _transform; // joint- to model-frame - glm::quat _rotation; // joint- to model-frame - glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied - - glm::quat _defaultRotation; // Not necessarilly bind rotation. See FBXJoint transform/bindTransform - glm::quat _inverseDefaultRotation; - glm::vec3 _defaultTranslation; - glm::vec3 _translation; - QString _name; - int _parentIndex; - bool _isFree; - glm::quat _preRotation; - glm::quat _postRotation; - glm::mat4 _preTransform; - glm::mat4 _postTransform; - glm::quat _inverseBindRotation; - - glm::vec3 _unitsScale{1.0f, 1.0f, 1.0f}; -}; - -#endif // hifi_JointState_h diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index f9f3f8086f..ea85460897 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -46,8 +46,6 @@ static bool isEqual(const glm::quat& p, const glm::quat& q) { } while (0) #endif -static bool AJT_HACK_USE_JOINT_STATES = false; - /* const glm::vec3 DEFAULT_RIGHT_EYE_POS(-0.3f, 1.6f, 0.0f); const glm::vec3 DEFAULT_LEFT_EYE_POS(0.3f, 1.6f, 0.0f); @@ -176,16 +174,12 @@ void Rig::destroyAnimGraph() { _overrideFlags.clear(); } -void Rig::initJointStates(const FBXGeometry& geometry, glm::mat4 modelOffset, int rootJointIndex, - int leftHandJointIndex, int leftElbowJointIndex, int leftShoulderJointIndex, - int rightHandJointIndex, int rightElbowJointIndex, int rightShoulderJointIndex) { +void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) { setModelOffset(modelOffset); _geometryOffset = AnimPose(geometry.offset); _animSkeleton = std::make_shared(geometry); - //_animSkeleton->dump(); - computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses()); _relativePoses.clear(); @@ -200,41 +194,44 @@ void Rig::initJointStates(const FBXGeometry& geometry, glm::mat4 modelOffset, in _overrideFlags.clear(); _overrideFlags.resize(_animSkeleton->getNumJoints(), false); - // AJT: LEGACY - { - // was Model::createJointStates - _jointStates.clear(); - for (int i = 0; i < geometry.joints.size(); ++i) { - const FBXJoint& joint = geometry.joints[i]; - // store a pointer to the FBXJoint in the JointState - JointState state(joint); - _jointStates.append(state); - } + _rootJointIndex = geometry.rootJointIndex; + _leftHandJointIndex = geometry.leftHandJointIndex; + _leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1; + _leftShoulderJointIndex = _leftElbowJointIndex >= 0 ? geometry.joints.at(_leftElbowJointIndex).parentIndex : -1; + _rightHandJointIndex = geometry.rightHandJointIndex; + _rightElbowJointIndex = _rightHandJointIndex >= 0 ? geometry.joints.at(_rightHandJointIndex).parentIndex : -1; + _rightShoulderJointIndex = _rightElbowJointIndex >= 0 ? geometry.joints.at(_rightElbowJointIndex).parentIndex : -1; +} - // was old Rig::initJointStates - // compute model transforms - glm::mat4 rootTransform = (glm::mat4)(_modelOffset * _geometryOffset); - int numStates = _animSkeleton->getNumJoints(); - for (int i = 0; i < numStates; ++i) { - JointState& state = _jointStates[i]; - int parentIndex = state.getParentIndex(); - if (parentIndex == -1) { - state.initTransform(rootTransform); - } else { - const JointState& parentState = _jointStates.at(parentIndex); - state.initTransform(parentState.getTransform()); - } - } +void Rig::reset(const FBXGeometry& geometry) { + _geometryOffset = AnimPose(geometry.offset); + _animSkeleton = std::make_shared(geometry); + + computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses()); + + _relativePoses.clear(); + _relativePoses = _animSkeleton->getRelativeDefaultPoses(); + + _absolutePoses.clear(); + _absolutePoses = _animSkeleton->getAbsoluteDefaultPoses(); + + _overridePoses.clear(); + _overridePoses = _animSkeleton->getRelativeDefaultPoses(); + + _overrideFlags.clear(); + _overrideFlags.resize(_animSkeleton->getNumJoints(), false); + + _rootJointIndex = geometry.rootJointIndex; + _leftHandJointIndex = geometry.leftHandJointIndex; + _leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1; + _leftShoulderJointIndex = _leftElbowJointIndex >= 0 ? geometry.joints.at(_leftElbowJointIndex).parentIndex : -1; + _rightHandJointIndex = geometry.rightHandJointIndex; + _rightElbowJointIndex = _rightHandJointIndex >= 0 ? geometry.joints.at(_rightHandJointIndex).parentIndex : -1; + _rightShoulderJointIndex = _rightElbowJointIndex >= 0 ? geometry.joints.at(_rightElbowJointIndex).parentIndex : -1; + + if (!_animGraphURL.isEmpty()) { + initAnimGraph(_animGraphURL); } - - // AJT: TODO: we could probaly just look these up by name? - _rootJointIndex = rootJointIndex; - _leftHandJointIndex = leftHandJointIndex; - _leftElbowJointIndex = leftElbowJointIndex; - _leftShoulderJointIndex = leftShoulderJointIndex; - _rightHandJointIndex = rightHandJointIndex; - _rightElbowJointIndex = rightElbowJointIndex; - _rightShoulderJointIndex = rightShoulderJointIndex; } bool Rig::jointStatesEmpty() { @@ -245,80 +242,15 @@ int Rig::getJointStateCount() const { return _relativePoses.size(); } -// We could build and cache a dictionary, too.... -// Should we be using .fst mapping instead/also? int Rig::indexOfJoint(const QString& jointName) { - for (int i = 0; i < _jointStates.count(); i++) { - if (_jointStates[i].getName() == jointName) { - return i; - } - } - return -1; + return _animSkeleton->nameToJointIndex(jointName); } void Rig::setModelOffset(const glm::mat4& modelOffset) { - // AJT: LEGACY - { - _legacyModelOffset = modelOffset; - } _modelOffset = AnimPose(modelOffset); } -// AJT: REMOVE -/* -void Rig::initJointTransforms(glm::mat4 rootTransform) { - // compute model transforms - int numStates = _jointStates.size(); - for (int i = 0; i < numStates; ++i) { - JointState& state = _jointStates[i]; - int parentIndex = state.getParentIndex(); - if (parentIndex == -1) { - state.initTransform(rootTransform); - } else { - const JointState& parentState = _jointStates.at(parentIndex); - state.initTransform(parentState.getTransform()); - } - } -} -*/ - -void Rig::clearJointTransformTranslation(int jointIndex) { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return; - } - _jointStates[jointIndex].clearTransformTranslation(); -} - -void Rig::reset(const QVector& fbxJoints) { - if (_jointStates.isEmpty()) { - return; - } - for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].setRotationInConstrainedFrame(fbxJoints.at(i).rotation, 0.0f); - _jointStates[i].setTranslation(fbxJoints.at(i).translation, 0.0f); - } -} - -// AJT: REMOVE -/* -JointState Rig::getJointState(int jointIndex) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return JointState(); - } - return _jointStates[jointIndex]; -} -*/ - bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { - if (AJT_HACK_USE_JOINT_STATES) { // AJT: LEGACY - if (index == -1 || index >= _jointStates.size()) { - return false; - } - const JointState& state = _jointStates.at(index); - rotation = state.getRotationInConstrainedFrame(); - return !state.rotationIsDefault(rotation); - } - if (index >= 0 && index < (int)_relativePoses.size()) { rotation = _relativePoses[index].rot; return !isEqual(rotation, _animSkeleton->getRelativeDefaultPose(index).rot); @@ -328,15 +260,6 @@ bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { } bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { - if (AJT_HACK_USE_JOINT_STATES) { // AJT: LEGACY - if (index == -1 || index >= _jointStates.size()) { - return false; - } - const JointState& state = _jointStates.at(index); - translation = state.getTranslation(); - return !state.translationIsDefault(translation); - } - if (index >= 0 && index < (int)_relativePoses.size()) { translation = _relativePoses[index].trans; return !isEqual(translation, _animSkeleton->getRelativeDefaultPose(index).trans); @@ -346,36 +269,17 @@ bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { } void Rig::clearJointState(int index) { - if (index != -1 && index < _jointStates.size()) { - // AJT: REMOVE - /* - JointState& state = _jointStates[index]; - state.setRotationInConstrainedFrame(glm::quat(), 0.0f); - state.setTranslation(state.getDefaultTranslationInConstrainedFrame(), 0.0f); - */ + if (index >= 0 && index < (int)_relativePoses.size()) { _overrideFlags[index] = false; } } void Rig::clearJointStates() { - // AJT: LEGACY - /* - { - _jointStates.clear(); - } - */ _overrideFlags.clear(); _overrideFlags.resize(_animSkeleton->getNumJoints()); } void Rig::clearJointAnimationPriority(int index) { - // AJT: legacy - { - if (index != -1 && index < _jointStates.size()) { - _jointStates[index].setAnimationPriority(0.0f); - } - } - if (index >= 0 && index < (int)_overrideFlags.size()) { _overrideFlags[index] = false; } @@ -384,21 +288,9 @@ void Rig::clearJointAnimationPriority(int index) { // Deprecated. // WARNING: this is not symmetric with getJointRotation. It's historical. Use the appropriate specific variation. void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, float priority) { - // AJT: legacy - { - if (index != -1 && index < _jointStates.size()) { - JointState& state = _jointStates[index]; - if (valid) { - state.setRotationInConstrainedFrame(rotation, priority); - } else { - state.restoreRotation(1.0f, priority); - } - } - } - if (index >= 0 && index < (int)_overrideFlags.size()) { if (valid) { - assert(_overrideFlags.size() == _overridePoses.size()); + ASSERT(_overrideFlags.size() == _overridePoses.size()); _overrideFlags[index] = true; _overridePoses[index].rot = rotation; } @@ -406,56 +298,49 @@ void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, flo } void Rig::restoreJointRotation(int index, float fraction, float priority) { - if (index != -1 && index < _jointStates.size()) { - _jointStates[index].restoreRotation(fraction, priority); - } + // AJT: DEAD CODE? + ASSERT(false); } void Rig::restoreJointTranslation(int index, float fraction, float priority) { - if (index != -1 && index < _jointStates.size()) { - _jointStates[index].restoreTranslation(fraction, priority); - } + // AJT: DEAD CODE? + ASSERT(false); } -bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, - glm::vec3 translation, glm::quat rotation) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { +// AJT: NOTE old code did not have 180 flip! +bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const { + glm::quat yFlip = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + if (jointIndex >= 0 && jointIndex < (int)_absolutePoses.size()) { + position = (rotation * yFlip * _absolutePoses[jointIndex].trans) + translation; + return true; + } else { return false; } - // position is in world-frame - position = translation + rotation * _jointStates[jointIndex].getPosition(); - return true; } +// AJT: NOTE old code did not have 180 flip! bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { + glm::quat yFlip = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + if (jointIndex >= 0 && jointIndex < (int)_absolutePoses.size()) { + position = yFlip * _absolutePoses[jointIndex].trans; + return true; + } else { return false; } - // position is in model-frame - position = extractTranslation(_jointStates[jointIndex].getTransform()); - return true; } bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const glm::quat& rotation) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { + if (jointIndex >= 0 && jointIndex < (int)_absolutePoses.size()) { + result = rotation * _absolutePoses[jointIndex].rot; + return true; + } else { return false; } - result = rotation * _jointStates[jointIndex].getRotation(); - return true; } // Deprecated. // WARNING: this is not symmetric with setJointRotation. It's historical. Use the appropriate specific variation. bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const { - - // AJT: LEGACY - { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return false; - } - rotation = _jointStates[jointIndex].getRotation(); - } - if (jointIndex >= 0 && jointIndex < (int)_relativePoses.size()) { rotation = _relativePoses[jointIndex].rot; return true; @@ -465,14 +350,6 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const { } bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { - // AJT: LEGACY - { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return false; - } - translation = _jointStates[jointIndex].getTranslation(); - } - if (jointIndex >= 0 && jointIndex < (int)_relativePoses.size()) { translation = _relativePoses[jointIndex].trans; return true; @@ -482,11 +359,9 @@ bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { } bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return false; - } - result = rotation * _jointStates[jointIndex].getRotation(); - return true; + // AJT: WTF IS THIS? + ASSERT(false); + return false; } void Rig::calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const { @@ -807,236 +682,56 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { _animVars.setTrigger(trigger); } - // AJT: LEGACY - if (AJT_HACK_USE_JOINT_STATES) { - clearJointStatePriorities(); - - // copy poses into jointStates - const float PRIORITY = 1.0f; - for (size_t i = 0; i < _relativePoses.size(); i++) { - setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * _relativePoses[i].rot, PRIORITY, 1.0f); - setJointTranslation((int)i, true, _relativePoses[i].trans, PRIORITY); - } - } - computeEyesInRootFrame(_relativePoses); } applyOverridePoses(); buildAbsolutePoses(); - - // AJT: LEGACY - { - for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].resetTransformChanged(); - } - } } void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority, const QVector& freeLineage, glm::mat4 rootTransform) { - // NOTE: targetRotation is from in model-frame - - if (endIndex == -1 || _jointStates.isEmpty()) { - return; - } - - if (freeLineage.isEmpty()) { - return; - } - - // store and remember topmost parent transform - glm::mat4 topParentTransform; - { - int index = freeLineage.last(); - const JointState& state = _jointStates.at(index); - int parentIndex = state.getParentIndex(); - if (parentIndex == -1) { - topParentTransform = rootTransform; - } else { - topParentTransform = _jointStates[parentIndex].getTransform(); - } - } - - // relax toward default rotation - // NOTE: ideally this should use dt and a relaxation timescale to compute how much to relax - int numFree = freeLineage.size(); - for (int j = 0; j < numFree; j++) { - int nextIndex = freeLineage.at(j); - JointState& nextState = _jointStates[nextIndex]; - if (! nextState.getIsFree()) { - continue; - } - - // Apply the zero rotationDelta, but use mixRotationDelta() which blends a bit of the default pose - // in the process. This provides stability to the IK solution for most models. - float mixFactor = 0.08f; - nextState.mixRotationDelta(glm::quat(), mixFactor, priority); - } - - // this is a cyclic coordinate descent algorithm: see - // http://www.ryanjuckett.com/programming/animation/21-cyclic-coordinate-descent-in-2d - - // keep track of the position of the end-effector - JointState& endState = _jointStates[endIndex]; - glm::vec3 endPosition = endState.getPosition(); - float distanceToGo = glm::distance(targetPosition, endPosition); - - const int MAX_ITERATION_COUNT = 3; - const float ACCEPTABLE_IK_ERROR = 0.005f; // 5mm - int numIterations = 0; - do { - ++numIterations; - // moving up, rotate each free joint to get endPosition closer to target - for (int j = 1; j < numFree; j++) { - int nextIndex = freeLineage.at(j); - JointState& nextState = _jointStates[nextIndex]; - if (! nextState.getIsFree()) { - continue; - } - - glm::vec3 pivot = nextState.getPosition(); - glm::vec3 leverArm = endPosition - pivot; - float leverLength = glm::length(leverArm); - if (leverLength < EPSILON) { - continue; - } - glm::quat deltaRotation = rotationBetween(leverArm, targetPosition - pivot); - - // We want to mix the shortest rotation with one that will pull the system down with gravity - // so that limbs don't float unrealistically. To do this we compute a simplified center of mass - // where each joint has unit mass and we don't bother averaging it because we only need direction. - if (j > 1) { - - glm::vec3 centerOfMass(0.0f); - for (int k = 0; k < j; ++k) { - int massIndex = freeLineage.at(k); - centerOfMass += _jointStates[massIndex].getPosition() - pivot; - } - // the gravitational effect is a rotation that tends to align the two cross products - const glm::vec3 worldAlignment = glm::vec3(0.0f, -1.0f, 0.0f); - glm::quat gravityDelta = rotationBetween(glm::cross(centerOfMass, leverArm), - glm::cross(worldAlignment, leverArm)); - - float gravityAngle = glm::angle(gravityDelta); - const float MIN_GRAVITY_ANGLE = 0.1f; - float mixFactor = 0.1f; - if (gravityAngle < MIN_GRAVITY_ANGLE) { - // the final rotation is a mix of the two - mixFactor = 0.5f * gravityAngle / MIN_GRAVITY_ANGLE; - } - deltaRotation = safeMix(deltaRotation, gravityDelta, mixFactor); - } - - // Apply the rotation delta. - glm::quat oldNextRotation = nextState.getRotation(); - nextState.applyRotationDelta(deltaRotation, priority); - - // measure the result of the rotation which may have been modified by blending - glm::quat actualDelta = nextState.getRotation() * glm::inverse(oldNextRotation); - endPosition = pivot + actualDelta * leverArm; - } - - // recompute transforms from the top down - glm::mat4 currentParentTransform = topParentTransform; - for (int j = numFree - 1; j >= 0; --j) { - JointState& freeState = _jointStates[freeLineage.at(j)]; - freeState.computeTransform(currentParentTransform); - currentParentTransform = freeState.getTransform(); - } - - // measure our success - endPosition = endState.getPosition(); - distanceToGo = glm::distance(targetPosition, endPosition); - } while (numIterations < MAX_ITERATION_COUNT && distanceToGo > ACCEPTABLE_IK_ERROR); - - // set final rotation of the end joint - endState.setRotationInModelFrame(targetRotation, priority); + ASSERT(false); } bool Rig::restoreJointPosition(int jointIndex, float fraction, float priority, const QVector& freeLineage) { - if (jointIndex == -1 || _jointStates.isEmpty()) { - return false; - } - - foreach (int index, freeLineage) { - JointState& state = _jointStates[index]; - state.restoreRotation(fraction, priority); - state.restoreTranslation(fraction, priority); - } - return true; + ASSERT(false); + return false; } float Rig::getLimbLength(int jointIndex, const QVector& freeLineage, const glm::vec3 scale, const QVector& fbxJoints) const { - if (jointIndex == -1 || _jointStates.isEmpty()) { - return 0.0f; - } - float length = 0.0f; - float lengthScale = (scale.x + scale.y + scale.z) / 3.0f; - for (int i = freeLineage.size() - 2; i >= 0; i--) { - length += fbxJoints.at(freeLineage.at(i)).distanceToParent * lengthScale; - } - return length; + ASSERT(false); + return 1.0f; } glm::quat Rig::setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority) { - glm::quat endRotation; - if (jointIndex == -1 || _jointStates.isEmpty()) { - return endRotation; - } - JointState& state = _jointStates[jointIndex]; - state.setRotationInBindFrame(rotation, priority); - endRotation = state.getRotationInBindFrame(); - return endRotation; + ASSERT(false); + return glm::quat(); } glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) { - if (jointIndex == -1 || _jointStates.isEmpty()) { - return glm::vec3(); - } - return _jointStates[jointIndex].getDefaultTranslationInConstrainedFrame(); + ASSERT(false); + return glm::vec3(); } glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, float mix) { - glm::quat endRotation; - if (jointIndex == -1 || _jointStates.isEmpty()) { - return endRotation; - } - JointState& state = _jointStates[jointIndex]; - state.setRotationInConstrainedFrame(targetRotation, priority, mix); - endRotation = state.getRotationInConstrainedFrame(); - return endRotation; + ASSERT(false); + return glm::quat(); } bool Rig::getJointRotationInConstrainedFrame(int jointIndex, glm::quat& quatOut) const { - if (jointIndex == -1 || _jointStates.isEmpty()) { - return false; - } - quatOut = _jointStates[jointIndex].getRotationInConstrainedFrame(); - return true; + ASSERT(false); + return false; } void Rig::clearJointStatePriorities() { - for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].setAnimationPriority(0.0f); - } + ASSERT(false); } -/* -void Rig::applyJointRotationDelta(int jointIndex, const glm::quat& delta, float priority) { - if (jointIndex == -1 || _jointStates.isEmpty()) { - return; - } - _jointStates[jointIndex].applyRotationDelta(delta, priority); -} -*/ - glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { - if (jointIndex == -1 || _jointStates.isEmpty()) { - return glm::quat(); - } - return _jointStates[jointIndex].getDefaultRotationInParentFrame(); + ASSERT(false); + return glm::quat(); } void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { @@ -1063,7 +758,7 @@ static const glm::vec3 Y_AXIS(0.0f, 1.0f, 0.0f); static const glm::vec3 Z_AXIS(0.0f, 0.0f, 1.0f); void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist) { - if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { + if (index >= 0 && index) { if (_animSkeleton) { glm::quat absRot = (glm::angleAxis(-RADIANS_PER_DEGREE * leanSideways, Z_AXIS) * glm::angleAxis(-RADIANS_PER_DEGREE * leanForward, X_AXIS) * @@ -1113,82 +808,69 @@ static void computeHeadNeckAnimVars(AnimSkeleton::ConstPointer skeleton, const A } void Rig::updateNeckJoint(int index, const HeadParameters& params) { - if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { - if (_animSkeleton) { + if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) { + if (params.isInHMD) { + glm::vec3 headPos, neckPos; + glm::quat headRot, neckRot; - if (params.isInHMD) { - glm::vec3 headPos, neckPos; - glm::quat headRot, neckRot; + AnimPose hmdPose(glm::vec3(1.0f), avatarToGeometryNegZForward(params.localHeadOrientation), avatarToGeometry(params.localHeadPosition)); + computeHeadNeckAnimVars(_animSkeleton, hmdPose, headPos, headRot, neckPos, neckRot); - AnimPose hmdPose(glm::vec3(1.0f), avatarToGeometryNegZForward(params.localHeadOrientation), avatarToGeometry(params.localHeadPosition)); - computeHeadNeckAnimVars(_animSkeleton, hmdPose, headPos, headRot, neckPos, neckRot); - - // debug rendering + // debug rendering #ifdef DEBUG_RENDERING - const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f); - const glm::vec4 green(0.0f, 1.0f, 0.0f, 1.0f); + const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f); + const glm::vec4 green(0.0f, 1.0f, 0.0f, 1.0f); - // transform from bone into avatar space - AnimPose headPose(glm::vec3(1), headRot, headPos); - DebugDraw::getInstance().addMyAvatarMarker("headTarget", headPose.rot, headPose.trans, red); + // transform from bone into avatar space + AnimPose headPose(glm::vec3(1), headRot, headPos); + DebugDraw::getInstance().addMyAvatarMarker("headTarget", headPose.rot, headPose.trans, red); - // transform from bone into avatar space - AnimPose neckPose(glm::vec3(1), neckRot, neckPos); - DebugDraw::getInstance().addMyAvatarMarker("neckTarget", neckPose.rot, neckPose.trans, green); + // transform from bone into avatar space + AnimPose neckPose(glm::vec3(1), neckRot, neckPos); + DebugDraw::getInstance().addMyAvatarMarker("neckTarget", neckPose.rot, neckPose.trans, green); #endif - _animVars.set("headPosition", headPos); - _animVars.set("headRotation", headRot); - _animVars.set("headType", (int)IKTarget::Type::HmdHead); - _animVars.set("neckPosition", neckPos); - _animVars.set("neckRotation", neckRot); - //_animVars.set("neckType", (int)IKTarget::Type::RotationOnly); - _animVars.set("neckType", (int)IKTarget::Type::Unknown); // 'Unknown' disables the target + _animVars.set("headPosition", headPos); + _animVars.set("headRotation", headRot); + _animVars.set("headType", (int)IKTarget::Type::HmdHead); + _animVars.set("neckPosition", neckPos); + _animVars.set("neckRotation", neckRot); + _animVars.set("neckType", (int)IKTarget::Type::Unknown); // 'Unknown' disables the target - } else { - - /* - // the params.localHeadOrientation is composed incorrectly, so re-compose it correctly from pitch, yaw and roll. - glm::quat realLocalHeadOrientation = (glm::angleAxis(glm::radians(-params.localHeadRoll), Z_AXIS) * - glm::angleAxis(glm::radians(params.localHeadYaw), Y_AXIS) * - glm::angleAxis(glm::radians(-params.localHeadPitch), X_AXIS)); - */ - - _animVars.unset("headPosition"); - - /* - qCDebug(animation) << "AJT: input orientation " << params.localHeadOrientation; - qCDebug(animation) << "AJT: after transform" << avatarToGeometry(params.localHeadOrientation); - */ - - _animVars.set("headRotation", avatarToGeometryNegZForward(params.localHeadOrientation)); - _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationOnly); - _animVars.set("headType", (int)IKTarget::Type::RotationOnly); - _animVars.unset("neckPosition"); - _animVars.unset("neckRotation"); - _animVars.set("neckType", (int)IKTarget::Type::RotationOnly); - } + } else { + _animVars.unset("headPosition"); + _animVars.set("headRotation", avatarToGeometryNegZForward(params.localHeadOrientation)); + _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationOnly); + _animVars.set("headType", (int)IKTarget::Type::RotationOnly); + _animVars.unset("neckPosition"); + _animVars.unset("neckRotation"); + _animVars.set("neckType", (int)IKTarget::Type::RotationOnly); } } } void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) { - if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { - auto& state = _jointStates[index]; - auto& parentState = _jointStates[state.getParentIndex()]; + // AJT: TODO: fix eye tracking! + /* + { + if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { + auto& state = _jointStates[index]; + auto& parentState = _jointStates[state.getParentIndex()]; - // NOTE: at the moment we do the math in the world-frame, hence the inverse transform is more complex than usual. - glm::mat4 inverse = glm::inverse(glm::mat4_cast(modelRotation) * parentState.getTransform() * - glm::translate(state.getDefaultTranslationInConstrainedFrame()) * - state.getPreTransform() * glm::mat4_cast(state.getPreRotation() * state.getDefaultRotation())); - glm::vec3 front = glm::vec3(inverse * glm::vec4(worldHeadOrientation * IDENTITY_FRONT, 0.0f)); - glm::vec3 lookAtDelta = lookAtSpot - modelTranslation; - glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(lookAtDelta + glm::length(lookAtDelta) * saccade, 1.0f)); - glm::quat between = rotationBetween(front, lookAt); - const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE; - state.setRotationInConstrainedFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * - state.getDefaultRotation(), DEFAULT_PRIORITY); + // NOTE: at the moment we do the math in the world-frame, hence the inverse transform is more complex than usual. + glm::mat4 inverse = glm::inverse(glm::mat4_cast(modelRotation) * parentState.getTransform() * + glm::translate(state.getDefaultTranslationInConstrainedFrame()) * + state.getPreTransform() * glm::mat4_cast(state.getPreRotation() * state.getDefaultRotation())); + glm::vec3 front = glm::vec3(inverse * glm::vec4(worldHeadOrientation * IDENTITY_FRONT, 0.0f)); + glm::vec3 lookAtDelta = lookAtSpot - modelTranslation; + glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(lookAtDelta + glm::length(lookAtDelta) * saccade, 1.0f)); + glm::quat between = rotationBetween(front, lookAt); + const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE; + state.setRotationInConstrainedFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * + state.getDefaultRotation(), DEFAULT_PRIORITY); + } } + */ } glm::vec3 Rig::avatarToGeometry(const glm::vec3& pos) const { @@ -1279,6 +961,9 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { } void Rig::initAnimGraph(const QUrl& url) { + _animGraphURL = url; + + _animNode.reset(); // load the anim graph _animLoader.reset(new AnimNodeLoader(url)); @@ -1337,70 +1022,13 @@ void Rig::buildAbsolutePoses() { for (int i = 0; i < (int)_absolutePoses.size(); i++) { _absolutePoses[i] = rootTransform * _absolutePoses[i]; } - - // AJT: LEGACY - { - // Build the joint states - glm::mat4 rootTransform = (glm::mat4)(_modelOffset * _geometryOffset); - for (int i = 0; i < (int)_animSkeleton->getNumJoints(); i++) { - JointState& state = _jointStates[i]; - - // compute model transforms - int parentIndex = state.getParentIndex(); - if (parentIndex == -1) { - state.computeTransform(rootTransform); - } else { - // guard against out-of-bounds access to _jointStates - if (parentIndex >= 0 && parentIndex < _jointStates.size()) { - const JointState& parentState = _jointStates.at(parentIndex); - state.computeTransform(parentState.getTransform(), parentState.getTransformChanged()); - } - } - } - } } glm::mat4 Rig::getJointTransform(int jointIndex) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return glm::mat4(); - } - - // check for differences between jointStates and _absolutePoses! - // AJT: TODO REMOVE - if (false) { - - glm::mat4 oldMat = _jointStates[jointIndex].getTransform(); - AnimPose oldPose(oldMat); - - glm::mat4 newMat = _absolutePoses[jointIndex]; - AnimPose newPose(newMat); - - bool badTrans = !isEqual(newPose.trans, oldPose.trans); - bool badScale = !isEqual(newPose.scale, oldPose.scale); - bool badRot = !isEqual(newPose.rot, oldPose.rot); - - if (badTrans || badScale || badRot) { - qCDebug(animation).nospace() << "AJT: mismatch for " << _animSkeleton->getJointName(jointIndex) << ", joint[" << jointIndex << "]"; - if (badTrans) { - qCDebug(animation) << "AJT: oldTrans = " << oldPose.trans; - qCDebug(animation) << "AJT: newTrans = " << newPose.trans; - } - if (badRot) { - qCDebug(animation) << "AJT: oldRot = " << oldPose.rot << "log =" << glm::log(oldPose.rot); - qCDebug(animation) << "AJT: newRot = " << newPose.rot << "log =" << glm::log(newPose.rot); - } - if (badScale) { - qCDebug(animation) << "AJT: oldScale = " << oldPose.scale; - qCDebug(animation) << "AJT: newScale = " << newPose.scale; - } - } - } - - // AJT: LEGACY - if (AJT_HACK_USE_JOINT_STATES) { - return _jointStates[jointIndex].getTransform(); - } else { + if (jointIndex >= 0 && jointIndex < (int)_absolutePoses.size()) { return _absolutePoses[jointIndex]; + } else { + return glm::mat4(); } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index dd1a5ec366..43977e058f 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -20,8 +20,6 @@ #include #include -#include "JointState.h" // We might want to change this (later) to something that doesn't depend on gpu, fbx and model. -HRS - #include "AnimNode.h" #include "AnimNodeLoader.h" #include "SimpleMovingAverage.h" @@ -76,7 +74,6 @@ public: virtual ~Rig() {} void destroyAnimGraph(); - void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreAnimation(); QStringList getAnimationRoles() const; @@ -84,9 +81,8 @@ public: void restoreRoleAnimation(const QString& role); void prefetchAnimation(const QString& url); - void initJointStates(const FBXGeometry& geometry, glm::mat4 modelOffset, int rootJointIndex, - int leftHandJointIndex, int leftElbowJointIndex, int leftShoulderJointIndex, - int rightHandJointIndex, int rightElbowJointIndex, int rightShoulderJointIndex); + void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); + void reset(const FBXGeometry& geometry); bool jointStatesEmpty(); int getJointStateCount() const; int indexOfJoint(const QString& jointName); @@ -94,19 +90,9 @@ public: void setModelOffset(const glm::mat4& modelOffset); const AnimPose& getGeometryOffset() const { return _geometryOffset; } - // AJT: REMOVE - /* - void initJointTransforms(glm::mat4 rootTransform); - */ - void clearJointTransformTranslation(int jointIndex); - void reset(const QVector& fbxJoints); bool getJointStateRotation(int index, glm::quat& rotation) const; bool getJointStateTranslation(int index, glm::vec3& translation) const; - // AJT: REMOVE - /* - void applyJointRotationDelta(int jointIndex, const glm::quat& delta, float priority); - JointState getJointState(int jointIndex) const; // XXX - */ + void clearJointState(int index); void clearJointStates(); void clearJointAnimationPriority(int index); @@ -151,9 +137,6 @@ public: void updateFromEyeParameters(const EyeParameters& params); void updateFromHandParameters(const HandParameters& params, float dt); - virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, - float scale, float priority) = 0; - void initAnimGraph(const QUrl& url); AnimNode::ConstPointer getAnimNode() const { return _animNode; } @@ -185,16 +168,11 @@ public: glm::quat avatarToGeometryZForward(const glm::quat& quat) const; glm::quat avatarToGeometryNegZForward(const glm::quat& quat) const; - // AJT: TODO: LEGACY - QVector _jointStates; - glm::mat4 _legacyModelOffset; - - // AJT: TODO document these better AnimPose _modelOffset; // model to avatar space (without 180 flip) AnimPose _geometryOffset; // geometry to model space (includes unit offset & fst offsets) - AnimPoseVec _relativePoses; // in fbx model space relative to parent. - AnimPoseVec _absolutePoses; // in fbx model space after _modelOffset is applied. - AnimPoseVec _overridePoses; // in fbx model space relative to parent. + AnimPoseVec _relativePoses; // geometry space relative to parent. + AnimPoseVec _absolutePoses; // avatar space, not relative to parent. + AnimPoseVec _overridePoses; // geometry space relative to parent. std::vector _overrideFlags; int _rootJointIndex { -1 }; @@ -212,6 +190,7 @@ public: glm::vec3 _lastVelocity; glm::vec3 _eyesInRootFrame { Vectors::ZERO }; + QUrl _animGraphURL; std::shared_ptr _animNode; std::shared_ptr _animSkeleton; std::unique_ptr _animLoader; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 2e8b8920ce..16252eb453 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 07d624c73f..960575844f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -87,6 +87,8 @@ void Model::setScale(const glm::vec3& scale) { _scaledToFit = false; } +const float METERS_PER_MILLIMETER = 0.01f; + void Model::setScaleInternal(const glm::vec3& scale) { if (glm::distance(_scale, scale) > METERS_PER_MILLIMETER) { _scale = scale; @@ -117,7 +119,7 @@ void Model::init() { void Model::reset() { if (_geometry && _geometry->isLoaded()) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); - _rig->reset(geometry.joints); + _rig->reset(geometry); } } @@ -162,22 +164,7 @@ void Model::initJointStates() { const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); - int rootJointIndex = geometry.rootJointIndex; - int leftHandJointIndex = geometry.leftHandJointIndex; - int leftElbowJointIndex = leftHandJointIndex >= 0 ? geometry.joints.at(leftHandJointIndex).parentIndex : -1; - int leftShoulderJointIndex = leftElbowJointIndex >= 0 ? geometry.joints.at(leftElbowJointIndex).parentIndex : -1; - int rightHandJointIndex = geometry.rightHandJointIndex; - int rightElbowJointIndex = rightHandJointIndex >= 0 ? geometry.joints.at(rightHandJointIndex).parentIndex : -1; - int rightShoulderJointIndex = rightElbowJointIndex >= 0 ? geometry.joints.at(rightElbowJointIndex).parentIndex : -1; - - _rig->initJointStates(geometry, modelOffset, - rootJointIndex, - leftHandJointIndex, - leftElbowJointIndex, - leftShoulderJointIndex, - rightHandJointIndex, - rightElbowJointIndex, - rightShoulderJointIndex); + _rig->initJointStates(geometry, modelOffset); } bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance, @@ -818,6 +805,7 @@ void Blender::run() { const float NORMAL_COEFFICIENT_SCALE = 0.01f; for (int i = 0, n = qMin(_blendshapeCoefficients.size(), mesh.blendshapes.size()); i < n; i++) { float vertexCoefficient = _blendshapeCoefficients.at(i); + const float EPSILON = 0.0001f; if (vertexCoefficient < EPSILON) { continue; } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 38d2666246..bab4ae0aa8 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -29,7 +29,6 @@ #include #include "GeometryCache.h" -#include "JointState.h" #include "TextureCache.h" #include "Rig.h"