From 33a6d3798c38ce0de2dcfe2aff19c94c8a39452f Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 23 Oct 2022 16:55:01 +0800 Subject: [PATCH] Added orientation interface and fixed compatibility between physics and transform --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- SHADE_Engine/src/Math/SHQuaternion.cpp | 4 ++ SHADE_Engine/src/Math/SHQuaternion.h | 1 + .../Math/Transform/SHTransformComponent.cpp | 14 +++- .../src/Math/Transform/SHTransformComponent.h | 6 +- .../src/Math/Transform/SHTransformSystem.cpp | 68 +++++++++++++++---- SHADE_Engine/src/Math/Vector/SHVec4.cpp | 9 +++ SHADE_Engine/src/Math/Vector/SHVec4.h | 14 ++-- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 6 +- 9 files changed, 99 insertions(+), 25 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 23259ee4..966a00a5 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -101,7 +101,7 @@ namespace Sandbox //Set initial positions transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) }); //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); - transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); + transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f)); transform.SetWorldScale(TEST_OBJ_SCALE); //if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 924ac67a..3878cea1 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -36,6 +36,10 @@ namespace SHADE : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) {} + SHQuaternion::SHQuaternion(const SHVec4& vec4) noexcept + : XMFLOAT4( vec4.x, vec4.y, vec4.z, vec4.w ) + {} + SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept : XMFLOAT4( _x, _y, _z, _w ) {} diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index f3ce3d61..cc1b5ff4 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -49,6 +49,7 @@ namespace SHADE SHQuaternion (SHQuaternion&& rhs) = default; SHQuaternion () noexcept; + SHQuaternion (const SHVec4& vec4) noexcept; SHQuaternion (float x, float y, float z, float w) noexcept; SHQuaternion (float yaw, float pitch, float roll) noexcept; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index 306cde67..e56cbc8d 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -103,7 +103,9 @@ namespace SHADE void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept { dirty = true; + localRotation = newLocalRotation; + updateQueue.push({ UpdateCommandType::LOCAL_ROTATION, newLocalRotation }); } void SHTransformComponent::SetLocalRotation(float pitch, float yaw, float roll) noexcept @@ -113,11 +115,16 @@ namespace SHADE localRotation.x = pitch; localRotation.y = yaw; localRotation.z = roll; + + updateQueue.push({ UpdateCommandType::LOCAL_ROTATION, SHVec3{pitch, yaw, roll} }); } void SHTransformComponent::SetLocalOrientation(const SHQuaternion& newLocalOrientation) noexcept { - + dirty = true; + + local.orientation = newLocalOrientation; + updateQueue.push({ UpdateCommandType::LOCAL_ORIENTATION, newLocalOrientation }); } void SHTransformComponent::SetLocalScale(const SHVec3& newLocalScale) noexcept @@ -155,7 +162,10 @@ namespace SHADE void SHTransformComponent::SetWorldOrientation(const SHQuaternion& newWorldOrientation) noexcept { - + dirty = true; + + world.orientation = newWorldOrientation; + updateQueue.push({ UpdateCommandType::WORLD_ORIENTATION, newWorldOrientation }); } void SHTransformComponent::SetWorldScale(const SHVec3& newWorldScale) noexcept diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index d1d21bec..ce8bb6fe 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -97,7 +97,9 @@ namespace SHADE enum class UpdateCommandType { - WORLD_POSITION + LOCAL_ROTATION + , LOCAL_ORIENTATION + , WORLD_POSITION , WORLD_ROTATION , WORLD_ORIENTATION , WORLD_SCALE @@ -111,7 +113,7 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ UpdateCommandType type; - SHVec3 data; + SHVec4 data; }; using UpdateQueue = std::queue; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 3244db1b..8bd01fb4 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -200,6 +200,8 @@ namespace SHADE SHMatrix localToWorld = SHMatrix::Identity; SHMatrix worldToLocal = SHMatrix::Identity; + bool convertRotation = true; + if (parent) { localToWorld = parent->GetTRS(); @@ -212,27 +214,44 @@ namespace SHADE switch (UPDATE_COMMAND.type) { + case SHTransformComponent::UpdateCommandType::LOCAL_ROTATION: + { + convertRotation = true; + break; + } + case SHTransformComponent::UpdateCommandType::LOCAL_ORIENTATION: + { + convertRotation = false; + break; + } case SHTransformComponent::UpdateCommandType::WORLD_POSITION: { - tf.local.position = SHVec3::Transform(UPDATE_COMMAND.data, worldToLocal); + tf.local.position = SHVec3::Transform(UPDATE_COMMAND.data.ToVec3(), worldToLocal); break; } case SHTransformComponent::UpdateCommandType::WORLD_ROTATION: { - tf.localRotation = tf.worldRotation; + tf.localRotation = UPDATE_COMMAND.data.ToVec3(); if (parent) tf.localRotation -= parent->GetLocalRotation(); + convertRotation = true; + break; } case SHTransformComponent::UpdateCommandType::WORLD_ORIENTATION: { - // TODO(Diren): Test using scripts by concat quaternions? + tf.local.orientation = UPDATE_COMMAND.data; + if (parent) + tf.local.orientation /= parent->GetLocalOrientation(); + + convertRotation = false; + break; } case SHTransformComponent::UpdateCommandType::WORLD_SCALE: { - tf.local.scale = tf.world.scale; + tf.local.scale = UPDATE_COMMAND.data.ToVec3(); if (parent) tf.local.scale /= parent->GetLocalScale(); @@ -247,17 +266,42 @@ namespace SHADE tf.local.trs = localToWorld; + // Compute world transforms tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); - - tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); - - // TODO(Diren): Wrap rotations between -360 and 360 - - tf.world.orientation = SHQuaternion::FromEuler(tf.worldRotation); - tf.local.orientation = SHQuaternion::FromEuler(tf.localRotation); - tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); + SHVec3 worldRotRad, localRotRad; + + if (convertRotation) + { + tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); + + // Set the orientation + // Wrap rotations between -360 and 360 and convert to radians + for (size_t i = 0; i < SHVec3::SIZE; ++i) + { + worldRotRad[i] = SHMath::DegreesToRadians(SHMath::Wrap(tf.worldRotation[i], -360.0f, 360.0f)); + localRotRad[i] = SHMath::DegreesToRadians(SHMath::Wrap(tf.localRotation[i], -360.0f, 360.0f)); + } + + tf.world.orientation = SHQuaternion::FromEuler(worldRotRad); + tf.local.orientation = SHQuaternion::FromEuler(localRotRad); + } + else + { + tf.world.orientation = (parent ? parent->GetLocalOrientation() : SHQuaternion::Identity) * tf.local.orientation; + + // Set the euler angle rotations + worldRotRad = tf.world.orientation.ToEuler(); + localRotRad = tf.local.orientation.ToEuler(); + + for (size_t i = 0; i < SHVec3::SIZE; ++i) + { + tf.worldRotation[i] = SHMath::RadiansToDegrees(worldRotRad[i]); + tf.localRotation[i] = SHMath::RadiansToDegrees(localRotRad[i]); + } + } + tf.world.ComputeTRS(); } diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.cpp b/SHADE_Engine/src/Math/Vector/SHVec4.cpp index bcf2ef97..9857818a 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec4.cpp @@ -38,6 +38,10 @@ namespace SHADE : XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ) {} + SHVec4::SHVec4(const SHVec3& vec3) noexcept + : XMFLOAT4( vec3.x, vec3.y, vec3.z, 1.0f ) + {} + SHVec4::SHVec4(const XMFLOAT4& xmfloat4) noexcept : XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w ) {} @@ -271,6 +275,11 @@ namespace SHADE return result; } + SHVec3 SHVec4::ToVec3() const noexcept + { + return SHVec3{ x, y, z }; + } + /*-----------------------------------------------------------------------------------*/ /* Static Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.h b/SHADE_Engine/src/Math/Vector/SHVec4.h index 911a714e..ce341bed 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.h +++ b/SHADE_Engine/src/Math/Vector/SHVec4.h @@ -16,6 +16,7 @@ // Project Headers #include "SH_API.h" +#include "SHVec3.h" namespace SHADE { @@ -53,6 +54,7 @@ namespace SHADE ~SHVec4 () = default; SHVec4 () noexcept; + SHVec4 (const SHVec3& vec3) noexcept; SHVec4 (const XMFLOAT4& xmfloat4) noexcept; SHVec4 (float x, float y, float z, float w) noexcept; @@ -102,16 +104,18 @@ namespace SHADE [[nodiscard]] float Dot3D (const SHVec4& rhs) const noexcept; [[nodiscard]] SHVec4 Cross3D (const SHVec4& rhs) const noexcept; [[nodiscard]] SHVec4 Cross (const SHVec4& v1, const SHVec4& v2) const noexcept; + + [[nodiscard]] SHVec3 ToVec3 () const noexcept; /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept; - [[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept; - [[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept; - [[nodiscard]] static SHVec4 Min (const std::initializer_list& vs) noexcept; - [[nodiscard]] static SHVec4 Max (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Min (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec4 Max (const std::initializer_list& vs) noexcept; [[nodiscard]] static SHVec4 Clamp (const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) noexcept; [[nodiscard]] static SHVec4 Lerp (const SHVec4& a, const SHVec4& b, float t) noexcept; [[nodiscard]] static SHVec4 ClampedLerp (const SHVec4& a, const SHVec4& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 7dc6c44e..a1994ad2 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -16,6 +16,7 @@ // Project Headers #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" +#include "Math/SHMathHelpers.h" #include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformComponent.h" @@ -315,7 +316,7 @@ namespace SHADE if (TF->HasChanged()) { physicsObject.SetPosition(TF->GetWorldPosition()); - physicsObject.SetRotation(TF->GetWorldRotation()); + physicsObject.SetOrientation(TF->GetWorldOrientation()); } } } @@ -492,8 +493,7 @@ namespace SHADE // Convert RP3D Transform to SHADE auto* tfComponent = SHComponentManager::GetComponent(entityID); tfComponent->SetWorldPosition(rp3dPos); - tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler()); - + tfComponent->SetWorldOrientation(SHQuaternion{ rp3dRot }); // Cache transforms physicsObject.prevTransform = CURRENT_TF;