diff --git a/engines/grim/actor.cpp b/engines/grim/actor.cpp index be50a3297c2..83cd5af14ea 100644 --- a/engines/grim/actor.cpp +++ b/engines/grim/actor.cpp @@ -2042,9 +2042,19 @@ Math::Vector3d Actor::getWorldPos() const { Math::Quaternion Actor::getRotationQuat() const { if (g_grim->getGameType() == GType_MONKEY4) { Math::Quaternion ret = Math::Quaternion::fromEuler(_yaw, _pitch, _roll); + if (isAttached()) { Actor *attachedActor = Actor::getPool().getObject(_attachedActor); - ret = ret * attachedActor->getRotationQuat(); + const Math::Quaternion &attachedQuat = attachedActor->getRotationQuat(); + + EMICostume *cost = static_cast(attachedActor->getCurrentCostume()); + if (cost && cost->_emiSkel && cost->_emiSkel->_obj) { + Joint *j = cost->_emiSkel->_obj->getJointNamed(_attachedJoint); + const Math::Quaternion &jointQuat = j->_finalQuat; + ret = ret * jointQuat * attachedQuat; + } else { + ret = ret * attachedQuat; + } } return ret; } else { diff --git a/engines/grim/emi/animationemi.cpp b/engines/grim/emi/animationemi.cpp index d2713bcdd41..be741003033 100644 --- a/engines/grim/emi/animationemi.cpp +++ b/engines/grim/emi/animationemi.cpp @@ -67,6 +67,7 @@ void AnimationEmi::animate(Skeleton *skel, float delta) { curBone._target = skel->getJointNamed(curBone._boneName); Math::Matrix4 &relFinal = curBone._target->_finalMatrix; + Math::Quaternion &quatFinal = curBone._target->_finalQuat; if (curBone._rotations) { int keyfIdx = 0; @@ -92,6 +93,7 @@ void AnimationEmi::animate(Skeleton *skel, float delta) { quat = curBone._rotations[keyfIdx]._quat.slerpQuat(curBone._rotations[keyfIdx - 1]._quat, interpVal); } quat.toMatrix(relFinal); + quatFinal = quat; relFinal.setPosition(relPos); } diff --git a/engines/grim/emi/skeleton.cpp b/engines/grim/emi/skeleton.cpp index 97fdced1160..9e6fb57f5cf 100644 --- a/engines/grim/emi/skeleton.cpp +++ b/engines/grim/emi/skeleton.cpp @@ -86,6 +86,7 @@ void Skeleton::initBones() { void Skeleton::resetAnim() { for (int i = 0; i < _numJoints; ++i) { _joints[i]._finalMatrix = _joints[i]._relMatrix; + _joints[i]._finalQuat = _joints[i]._quat; } } @@ -94,6 +95,7 @@ void Skeleton::commitAnim() { const Joint *parent = getParentJoint(&_joints[m]); if (parent) { _joints[m]._finalMatrix = parent->_finalMatrix * _joints[m]._finalMatrix; + _joints[m]._finalQuat = parent->_finalQuat * _joints[m]._finalQuat; } } } diff --git a/engines/grim/emi/skeleton.h b/engines/grim/emi/skeleton.h index c45e6d5dff8..95e1c1fe7b9 100644 --- a/engines/grim/emi/skeleton.h +++ b/engines/grim/emi/skeleton.h @@ -47,6 +47,7 @@ struct Joint { Math::Matrix4 _absMatrix; Math::Matrix4 _relMatrix; Math::Matrix4 _finalMatrix; + Math::Quaternion _finalQuat; }; class Skeleton : public Object {