Added orientation interface and fixed compatibility between physics and transform

This commit is contained in:
Diren D Bharwani 2022-10-23 16:55:01 +08:00
parent ebfcf1c6bb
commit 33a6d3798c
9 changed files with 99 additions and 25 deletions

View File

@ -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)

View File

@ -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 )
{}

View File

@ -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;

View File

@ -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

View File

@ -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<UpdateCommand>;

View File

@ -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();
}

View File

@ -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 */
/*-----------------------------------------------------------------------------------*/

View File

@ -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<SHVec4>& vs) noexcept;
[[nodiscard]] static SHVec4 Max (const std::initializer_list<SHVec4>& 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<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 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;

View File

@ -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<SHTransformComponent>(entityID);
tfComponent->SetWorldPosition(rp3dPos);
tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler());
tfComponent->SetWorldOrientation(SHQuaternion{ rp3dRot });
// Cache transforms
physicsObject.prevTransform = CURRENT_TF;