diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index c1b5af398..2ff4def5f 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -15,6 +15,7 @@ #include "Engine/Graphics/Models/MeshDeformation.h" #include "Engine/Level/Scene/Scene.h" #include "Engine/Level/SceneObjectsFactory.h" +#include "Engine/Physics/Actors/RigidBody.h" #include "Engine/Serialization/Serialization.h" AnimatedModel::AnimatedModel(const SpawnParams& params) @@ -548,7 +549,33 @@ void AnimatedModel::ApplyRootMotion(const Transform& rootMotionDelta) // Apply movement Actor* target = RootMotionTarget ? RootMotionTarget.Get() : this; - target->AddMovement(translation, rootMotionDelta.Orientation); + // filter rotation according to constraints if the target is a rigidbody + const auto rigidBody = dynamic_cast(target); + auto rotation = rootMotionDelta.Orientation; + if (rigidBody) + { + if (static_cast(rigidBody->GetConstraints()) & static_cast(RigidbodyConstraints::LockRotation)) + rotation = Quaternion::Identity; + else + { + Float3 euler = rotation.GetEuler(); + const auto constraints = static_cast(rigidBody->GetConstraints()); + if (constraints & static_cast(RigidbodyConstraints::LockRotationX)) + { + euler.X = 0; + } + if (constraints & static_cast(RigidbodyConstraints::LockRotationY)) + { + euler.Y = 0; + } + if (constraints & static_cast(RigidbodyConstraints::LockRotationZ)) + { + euler.Z = 0; + } + rotation = Quaternion::Euler(euler); + } + } + target->AddMovement(translation, rotation); } void AnimatedModel::SyncParameters()