SP3-16 Quaternions #112
|
@ -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)
|
||||||
|
|
|
@ -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 )
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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,17 +266,42 @@ 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.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);
|
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();
|
tf.world.ComputeTRS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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,15 +105,17 @@ 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 */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept;
|
[[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept;
|
||||||
[[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept;
|
[[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept;
|
||||||
[[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept;
|
[[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept;
|
||||||
[[nodiscard]] static SHVec4 Min (const std::initializer_list<SHVec4>& vs) noexcept;
|
[[nodiscard]] static SHVec4 Min (const std::initializer_list<SHVec4>& vs) noexcept;
|
||||||
[[nodiscard]] static SHVec4 Max (const std::initializer_list<SHVec4>& vs) noexcept;
|
[[nodiscard]] static SHVec4 Max (const std::initializer_list<SHVec4>& vs) noexcept;
|
||||||
[[nodiscard]] static SHVec4 Clamp (const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) 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 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;
|
[[nodiscard]] static SHVec4 ClampedLerp (const SHVec4& a, const SHVec4& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue