From 284c971ec0e1242664aa25280cc89cd3e260b4bb Mon Sep 17 00:00:00 2001 From: nothingTVatYT Date: Fri, 5 Jan 2024 05:07:08 +0100 Subject: [PATCH 1/5] don't rotate a rigidbody around locked axis --- Source/Engine/Level/Actors/AnimatedModel.cpp | 29 +++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) 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() From a24a9d209433d3f79a14be6f34a4ab340ec39bf5 Mon Sep 17 00:00:00 2001 From: nothingTVatYT Date: Sat, 6 Jan 2024 12:40:24 +0100 Subject: [PATCH 2/5] move constraints checks to RigidBody --- Source/Engine/Level/Actors/AnimatedModel.cpp | 28 +------------- Source/Engine/Physics/Actors/RigidBody.cpp | 40 ++++++++++++++++++++ Source/Engine/Physics/Actors/RigidBody.h | 6 +++ 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 2ff4def5f..3a40dbf46 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -549,33 +549,7 @@ void AnimatedModel::ApplyRootMotion(const Transform& rootMotionDelta) // Apply movement Actor* target = RootMotionTarget ? RootMotionTarget.Get() : this; - // 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); + target->AddMovement(translation, rootMotionDelta.Orientation); } void AnimatedModel::SyncParameters() diff --git a/Source/Engine/Physics/Actors/RigidBody.cpp b/Source/Engine/Physics/Actors/RigidBody.cpp index afbac6611..15ea95075 100644 --- a/Source/Engine/Physics/Actors/RigidBody.cpp +++ b/Source/Engine/Physics/Actors/RigidBody.cpp @@ -300,6 +300,46 @@ void RigidBody::ClosestPoint(const Vector3& position, Vector3& result) const } } +void RigidBody::AddMovement(const Vector3& translation, const Quaternion& rotation) +{ + // filter rotation according to constraints + Quaternion allowedRotation; + if (static_cast(GetConstraints()) & static_cast(RigidbodyConstraints::LockRotation)) + allowedRotation = Quaternion::Identity; + else + { + Float3 euler = rotation.GetEuler(); + const auto constraints = static_cast(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; + allowedRotation = Quaternion::Euler(euler); + } + + // filter translation according to the constraints + auto allowedTranslation = translation; + if (static_cast(GetConstraints()) & static_cast(RigidbodyConstraints::LockPosition)) + allowedTranslation = Vector3::Zero; + else + { + const auto constraints = static_cast(GetConstraints()); + if (constraints & static_cast(RigidbodyConstraints::LockPositionX)) + allowedTranslation.X = 0; + if (constraints & static_cast(RigidbodyConstraints::LockPositionY)) + allowedTranslation.Y = 0; + if (constraints & static_cast(RigidbodyConstraints::LockPositionZ)) + allowedTranslation.Z = 0; + } + Transform t; + t.Translation = _transform.Translation + allowedTranslation; + t.Orientation = _transform.Orientation * allowedRotation; + t.Scale = _transform.Scale; + SetTransform(t); +} + void RigidBody::OnCollisionEnter(const Collision& c) { CollisionEnter(c); diff --git a/Source/Engine/Physics/Actors/RigidBody.h b/Source/Engine/Physics/Actors/RigidBody.h index 2ef50ca7a..b8c7d0208 100644 --- a/Source/Engine/Physics/Actors/RigidBody.h +++ b/Source/Engine/Physics/Actors/RigidBody.h @@ -430,6 +430,12 @@ public: /// The result point on the rigidbody shape that is closest to the specified location. API_FUNCTION() void ClosestPoint(const Vector3& position, API_PARAM(Out) Vector3& result) const; + /// + /// Moves and rotates the rigidbody in world space within the limits of defined constraints. + /// + /// The translation vector. + /// The rotation quaternion. + API_FUNCTION() void AddMovement(const Vector3& translation, const Quaternion& rotation) override; public: /// /// Occurs when a collision start gets registered for this rigidbody (it collides with something). From 2c76785bf0fc8c206d7441c5b527b8da0676e99a Mon Sep 17 00:00:00 2001 From: nothingTVatYT Date: Wed, 10 Jan 2024 18:31:13 +0100 Subject: [PATCH 3/5] remove unused import --- Source/Engine/Level/Actors/AnimatedModel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 3a40dbf46..c1b5af398 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -15,7 +15,6 @@ #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) From d126f5bc55b2a0f8d2b2db6a983d96956401eebe Mon Sep 17 00:00:00 2001 From: nothingTVatYT Date: Wed, 10 Jan 2024 18:36:05 +0100 Subject: [PATCH 4/5] use enum helper functions --- Source/Engine/Physics/Actors/RigidBody.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Source/Engine/Physics/Actors/RigidBody.cpp b/Source/Engine/Physics/Actors/RigidBody.cpp index 15ea95075..71151866a 100644 --- a/Source/Engine/Physics/Actors/RigidBody.cpp +++ b/Source/Engine/Physics/Actors/RigidBody.cpp @@ -304,33 +304,31 @@ void RigidBody::AddMovement(const Vector3& translation, const Quaternion& rotati { // filter rotation according to constraints Quaternion allowedRotation; - if (static_cast(GetConstraints()) & static_cast(RigidbodyConstraints::LockRotation)) + if (EnumHasAllFlags(GetConstraints(), RigidbodyConstraints::LockRotation)) allowedRotation = Quaternion::Identity; else { Float3 euler = rotation.GetEuler(); - const auto constraints = static_cast(GetConstraints()); - if (constraints & static_cast(RigidbodyConstraints::LockRotationX)) + if (EnumHasAnyFlags(GetConstraints(), RigidbodyConstraints::LockRotationX)) euler.X = 0; - if (constraints & static_cast(RigidbodyConstraints::LockRotationY)) + if (EnumHasAnyFlags(GetConstraints(), RigidbodyConstraints::LockRotationY)) euler.Y = 0; - if (constraints & static_cast(RigidbodyConstraints::LockRotationZ)) + if (EnumHasAnyFlags(GetConstraints(), RigidbodyConstraints::LockRotationZ)) euler.Z = 0; allowedRotation = Quaternion::Euler(euler); } // filter translation according to the constraints auto allowedTranslation = translation; - if (static_cast(GetConstraints()) & static_cast(RigidbodyConstraints::LockPosition)) + if (EnumHasAllFlags(GetConstraints(), RigidbodyConstraints::LockPosition)) allowedTranslation = Vector3::Zero; else { - const auto constraints = static_cast(GetConstraints()); - if (constraints & static_cast(RigidbodyConstraints::LockPositionX)) + if (EnumHasAnyFlags(GetConstraints(), RigidbodyConstraints::LockPositionX)) allowedTranslation.X = 0; - if (constraints & static_cast(RigidbodyConstraints::LockPositionY)) + if (EnumHasAnyFlags(GetConstraints(), RigidbodyConstraints::LockPositionY)) allowedTranslation.Y = 0; - if (constraints & static_cast(RigidbodyConstraints::LockPositionZ)) + if (EnumHasAnyFlags(GetConstraints(), RigidbodyConstraints::LockPositionZ)) allowedTranslation.Z = 0; } Transform t; From 8922b5cd7970321a0ee91389a343d6f6e0b8396b Mon Sep 17 00:00:00 2001 From: nothingTVatYT Date: Wed, 10 Jan 2024 18:38:29 +0100 Subject: [PATCH 5/5] clean up include file --- Source/Engine/Physics/Actors/RigidBody.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/Engine/Physics/Actors/RigidBody.h b/Source/Engine/Physics/Actors/RigidBody.h index b8c7d0208..ca1428810 100644 --- a/Source/Engine/Physics/Actors/RigidBody.h +++ b/Source/Engine/Physics/Actors/RigidBody.h @@ -430,12 +430,6 @@ public: /// The result point on the rigidbody shape that is closest to the specified location. API_FUNCTION() void ClosestPoint(const Vector3& position, API_PARAM(Out) Vector3& result) const; - /// - /// Moves and rotates the rigidbody in world space within the limits of defined constraints. - /// - /// The translation vector. - /// The rotation quaternion. - API_FUNCTION() void AddMovement(const Vector3& translation, const Quaternion& rotation) override; public: /// /// Occurs when a collision start gets registered for this rigidbody (it collides with something). @@ -492,6 +486,7 @@ public: // [Actor] void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; + void AddMovement(const Vector3& translation, const Quaternion& rotation) override; // [IPhysicsActor] void* GetPhysicsActor() const override;