SP3-16 Quaternions #112

Merged
direnbharwani merged 17 commits from SP3-16-Math into main 2022-10-23 20:07:17 +08:00
9 changed files with 99 additions and 25 deletions
Showing only changes of commit 33a6d3798c - Show all commits

View File

@ -101,7 +101,7 @@ namespace Sandbox
//Set initial positions //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(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.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); transform.SetWorldScale(TEST_OBJ_SCALE);
//if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) //if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN)

View File

@ -36,6 +36,10 @@ namespace SHADE
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) : 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 SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept
: XMFLOAT4( _x, _y, _z, _w ) : XMFLOAT4( _x, _y, _z, _w )
{} {}

View File

@ -49,6 +49,7 @@ namespace SHADE
SHQuaternion (SHQuaternion&& rhs) = default; SHQuaternion (SHQuaternion&& rhs) = default;
SHQuaternion () noexcept; SHQuaternion () noexcept;
SHQuaternion (const SHVec4& vec4) noexcept;
SHQuaternion (float x, float y, float z, float w) noexcept; SHQuaternion (float x, float y, float z, float w) noexcept;
SHQuaternion (float yaw, float pitch, float roll) noexcept; SHQuaternion (float yaw, float pitch, float roll) noexcept;

View File

@ -103,7 +103,9 @@ namespace SHADE
void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept
{ {
dirty = true; dirty = true;
localRotation = newLocalRotation; localRotation = newLocalRotation;
updateQueue.push({ UpdateCommandType::LOCAL_ROTATION, newLocalRotation });
} }
void SHTransformComponent::SetLocalRotation(float pitch, float yaw, float roll) noexcept void SHTransformComponent::SetLocalRotation(float pitch, float yaw, float roll) noexcept
@ -113,11 +115,16 @@ namespace SHADE
localRotation.x = pitch; localRotation.x = pitch;
localRotation.y = yaw; localRotation.y = yaw;
localRotation.z = roll; localRotation.z = roll;
updateQueue.push({ UpdateCommandType::LOCAL_ROTATION, SHVec3{pitch, yaw, roll} });
} }
void SHTransformComponent::SetLocalOrientation(const SHQuaternion& newLocalOrientation) noexcept 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 void SHTransformComponent::SetLocalScale(const SHVec3& newLocalScale) noexcept
@ -155,7 +162,10 @@ namespace SHADE
void SHTransformComponent::SetWorldOrientation(const SHQuaternion& newWorldOrientation) noexcept 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 void SHTransformComponent::SetWorldScale(const SHVec3& newWorldScale) noexcept

View File

@ -97,7 +97,9 @@ namespace SHADE
enum class UpdateCommandType enum class UpdateCommandType
{ {
WORLD_POSITION LOCAL_ROTATION
, LOCAL_ORIENTATION
, WORLD_POSITION
, WORLD_ROTATION , WORLD_ROTATION
, WORLD_ORIENTATION , WORLD_ORIENTATION
, WORLD_SCALE , WORLD_SCALE
@ -111,7 +113,7 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
UpdateCommandType type; UpdateCommandType type;
SHVec3 data; SHVec4 data;
}; };
using UpdateQueue = std::queue<UpdateCommand>; using UpdateQueue = std::queue<UpdateCommand>;

View File

@ -200,6 +200,8 @@ namespace SHADE
SHMatrix localToWorld = SHMatrix::Identity; SHMatrix localToWorld = SHMatrix::Identity;
SHMatrix worldToLocal = SHMatrix::Identity; SHMatrix worldToLocal = SHMatrix::Identity;
bool convertRotation = true;
if (parent) if (parent)
{ {
localToWorld = parent->GetTRS(); localToWorld = parent->GetTRS();
@ -212,27 +214,44 @@ namespace SHADE
switch (UPDATE_COMMAND.type) 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: 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; break;
} }
case SHTransformComponent::UpdateCommandType::WORLD_ROTATION: case SHTransformComponent::UpdateCommandType::WORLD_ROTATION:
{ {
tf.localRotation = tf.worldRotation; tf.localRotation = UPDATE_COMMAND.data.ToVec3();
if (parent) if (parent)
tf.localRotation -= parent->GetLocalRotation(); tf.localRotation -= parent->GetLocalRotation();
convertRotation = true;
break; break;
} }
case SHTransformComponent::UpdateCommandType::WORLD_ORIENTATION: 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; break;
} }
case SHTransformComponent::UpdateCommandType::WORLD_SCALE: case SHTransformComponent::UpdateCommandType::WORLD_SCALE:
{ {
tf.local.scale = tf.world.scale; tf.local.scale = UPDATE_COMMAND.data.ToVec3();
if (parent) if (parent)
tf.local.scale /= parent->GetLocalScale(); tf.local.scale /= parent->GetLocalScale();
@ -247,16 +266,41 @@ namespace SHADE
tf.local.trs = localToWorld; tf.local.trs = localToWorld;
// Compute world transforms
tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); tf.world.position = SHVec3::Transform(tf.local.position, localToWorld);
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); tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
// TODO(Diren): Wrap rotations between -360 and 360 // 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(tf.worldRotation); tf.world.orientation = SHQuaternion::FromEuler(worldRotRad);
tf.local.orientation = SHQuaternion::FromEuler(tf.localRotation); tf.local.orientation = SHQuaternion::FromEuler(localRotRad);
}
else
{
tf.world.orientation = (parent ? parent->GetLocalOrientation() : SHQuaternion::Identity) * tf.local.orientation;
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); // 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(); tf.world.ComputeTRS();
} }

View File

@ -38,6 +38,10 @@ namespace SHADE
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ) : 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 SHVec4::SHVec4(const XMFLOAT4& xmfloat4) noexcept
: XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w ) : XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w )
{} {}
@ -271,6 +275,11 @@ namespace SHADE
return result; return result;
} }
SHVec3 SHVec4::ToVec3() const noexcept
{
return SHVec3{ x, y, z };
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */ /* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -16,6 +16,7 @@
// Project Headers // Project Headers
#include "SH_API.h" #include "SH_API.h"
#include "SHVec3.h"
namespace SHADE namespace SHADE
{ {
@ -53,6 +54,7 @@ namespace SHADE
~SHVec4 () = default; ~SHVec4 () = default;
SHVec4 () noexcept; SHVec4 () noexcept;
SHVec4 (const SHVec3& vec3) noexcept;
SHVec4 (const XMFLOAT4& xmfloat4) noexcept; SHVec4 (const XMFLOAT4& xmfloat4) noexcept;
SHVec4 (float x, float y, float z, float w) noexcept; SHVec4 (float x, float y, float z, float w) noexcept;
@ -103,6 +105,8 @@ namespace SHADE
[[nodiscard]] SHVec4 Cross3D (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]] SHVec4 Cross (const SHVec4& v1, const SHVec4& v2) const noexcept;
[[nodiscard]] SHVec3 ToVec3 () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Static Function Members */ /* Static Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -16,6 +16,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Math/SHMathHelpers.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
@ -315,7 +316,7 @@ namespace SHADE
if (TF->HasChanged()) if (TF->HasChanged())
{ {
physicsObject.SetPosition(TF->GetWorldPosition()); physicsObject.SetPosition(TF->GetWorldPosition());
physicsObject.SetRotation(TF->GetWorldRotation()); physicsObject.SetOrientation(TF->GetWorldOrientation());
} }
} }
} }
@ -492,8 +493,7 @@ namespace SHADE
// Convert RP3D Transform to SHADE // Convert RP3D Transform to SHADE
auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID); auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
tfComponent->SetWorldPosition(rp3dPos); tfComponent->SetWorldPosition(rp3dPos);
tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler()); tfComponent->SetWorldOrientation(SHQuaternion{ rp3dRot });
// Cache transforms // Cache transforms
physicsObject.prevTransform = CURRENT_TF; physicsObject.prevTransform = CURRENT_TF;