Merge pull request #112 from SHADE-DP/SP3-16-Math
SP3-16 Quaternions NEW Added implementations for Quaternion LookRotation, FromToRotation, Slerp, Lerp and RotateTowards Transform now stores orientations instead of euler angle rotations. Transform Component interface unchanged. Added Orientation getters and setters to Transform Component.
This commit is contained in:
commit
23b8b66297
|
@ -83,11 +83,13 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>();
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>();
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>();
|
||||||
|
|
||||||
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostLogicUpdate>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformUpdateRoutine>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
|
@ -67,9 +67,9 @@ namespace Sandbox
|
||||||
customMat->SetProperty("data.alpha", 0.1f);
|
customMat->SetProperty("data.alpha", 0.1f);
|
||||||
|
|
||||||
// Create Stress Test Objects
|
// Create Stress Test Objects
|
||||||
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f;
|
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One;
|
||||||
constexpr int NUM_ROWS = 0;
|
constexpr int NUM_ROWS = 3;
|
||||||
constexpr int NUM_COLS = 0;
|
constexpr int NUM_COLS = 1;
|
||||||
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
|
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
|
||||||
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
|
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
|
||||||
|
|
||||||
|
@ -91,13 +91,13 @@ 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)
|
||||||
collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
|
collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
|
||||||
else
|
//else
|
||||||
collider.AddBoundingSphere(0.5f, SHVec3::Zero);
|
// collider.AddBoundingSphere(0.5f, SHVec3::Zero);
|
||||||
|
|
||||||
stressTestObjects.emplace_back(entity);
|
stressTestObjects.emplace_back(entity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,9 @@ typedef uint32_t SHEventIdentifier;
|
||||||
typedef uint32_t SHEventHandle;
|
typedef uint32_t SHEventHandle;
|
||||||
|
|
||||||
//Add your event identifiers here:
|
//Add your event identifiers here:
|
||||||
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};
|
constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 };
|
||||||
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT{ 1 };
|
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 };
|
||||||
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT{ 2 };
|
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT{ 3 };
|
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT{ 4 };
|
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
||||||
|
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||||
|
|
|
@ -295,32 +295,33 @@ namespace SHADE
|
||||||
) != 0;
|
) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHMatrix::operator XMMATRIX() const noexcept
|
||||||
|
{
|
||||||
|
return XMLoadFloat4x4(this);
|
||||||
|
}
|
||||||
|
|
||||||
SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept
|
SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept
|
||||||
{
|
{
|
||||||
return rhs * lhs;
|
return rhs * lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Function Member Definitions */
|
/* Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHMatrix::Transpose() noexcept
|
void SHMatrix::Transpose() noexcept
|
||||||
{
|
{
|
||||||
const XMMATRIX M = XMLoadFloat4x4(this);
|
XMStoreFloat4x4(this, XMMatrixTranspose(*this));
|
||||||
XMStoreFloat4x4(this, XMMatrixTranspose(M));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMatrix::Invert() noexcept
|
void SHMatrix::Invert() noexcept
|
||||||
{
|
{
|
||||||
const XMMATRIX M = XMLoadFloat4x4(this);
|
XMStoreFloat4x4(this, XMMatrixInverse(nullptr, *this));
|
||||||
XMStoreFloat4x4(this, XMMatrixInverse(nullptr, M));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHMatrix::Determinant() const noexcept
|
float SHMatrix::Determinant() const noexcept
|
||||||
{
|
{
|
||||||
const XMMATRIX M = XMLoadFloat4x4(this);
|
return XMVectorGetX(XMMatrixDeterminant(*this));
|
||||||
return XMVectorGetX(XMMatrixDeterminant(M));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SHMatrix::ToString() const noexcept
|
std::string SHMatrix::ToString() const noexcept
|
||||||
|
@ -337,9 +338,8 @@ namespace SHADE
|
||||||
bool SHMatrix::Decompose(SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept
|
bool SHMatrix::Decompose(SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept
|
||||||
{
|
{
|
||||||
XMVECTOR s, r, t;
|
XMVECTOR s, r, t;
|
||||||
const XMMATRIX M = XMLoadFloat4x4(this);
|
|
||||||
|
|
||||||
if (!XMMatrixDecompose(&s, &r, &t, M))
|
if (!XMMatrixDecompose(&s, &r, &t, *this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
|
@ -356,9 +356,8 @@ namespace SHADE
|
||||||
bool SHMatrix::Decompose(SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept
|
bool SHMatrix::Decompose(SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept
|
||||||
{
|
{
|
||||||
XMVECTOR s, r, t;
|
XMVECTOR s, r, t;
|
||||||
const XMMATRIX M = XMLoadFloat4x4(this);
|
|
||||||
|
|
||||||
if (!XMMatrixDecompose(&s, &r, &t, M))
|
if (!XMMatrixDecompose(&s, &r, &t, *this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
XMStoreFloat3(&scale, s);
|
XMStoreFloat3(&scale, s);
|
||||||
|
@ -376,8 +375,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
const XMMATRIX M = XMLoadFloat4x4(&matrix);
|
XMStoreFloat4x4(&result, XMMatrixTranspose(matrix));
|
||||||
XMStoreFloat4x4(&result, XMMatrixTranspose(M));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,8 +383,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
const XMMATRIX M = XMLoadFloat4x4(&matrix);
|
XMStoreFloat4x4(&result, XMMatrixInverse(nullptr, matrix));
|
||||||
XMStoreFloat4x4(&result, XMMatrixInverse(nullptr, M));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,8 +398,8 @@ namespace SHADE
|
||||||
SHMatrix SHMatrix::Translate(const SHVec3& pos) noexcept
|
SHMatrix SHMatrix::Translate(const SHVec3& pos) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixTranslation(pos.x, pos.y, pos.z));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixTranslation(pos.x, pos.y, pos.z));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,25 +407,23 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
const XMVECTOR A = XMLoadFloat3(&axis);
|
XMStoreFloat4x4(&result, XMMatrixRotationAxis(axis, angleInRad));
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationAxis(A, angleInRad));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::Rotate(float yaw, float pitch, float roll) noexcept
|
SHMatrix SHMatrix::Rotate(float yaw, float pitch, float roll) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(pitch, yaw, roll));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(pitch, yaw, roll));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::Rotate(const SHVec3& eulerAngles) noexcept
|
SHMatrix SHMatrix::Rotate(const SHVec3& eulerAngles) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(eulerAngles.x, eulerAngles.y, eulerAngles.z));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYawFromVector(eulerAngles));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,57 +431,55 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(&q);
|
XMStoreFloat4x4(&result, XMMatrixRotationQuaternion(q));
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationQuaternion(Q));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::RotateX(float angleInRad) noexcept
|
SHMatrix SHMatrix::RotateX(float angleInRad) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationX(angleInRad));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixRotationX(angleInRad));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::RotateY(float angleInRad) noexcept
|
SHMatrix SHMatrix::RotateY(float angleInRad) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationY(angleInRad));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixRotationY(angleInRad));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::RotateZ(float angleInRad) noexcept
|
SHMatrix SHMatrix::RotateZ(float angleInRad) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixRotationZ(angleInRad));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixRotationZ(angleInRad));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::Scale(float uniformScaleFactor) noexcept
|
SHMatrix SHMatrix::Scale(float uniformScaleFactor) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixScaling(uniformScaleFactor, uniformScaleFactor, uniformScaleFactor));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixScaling(uniformScaleFactor, uniformScaleFactor, uniformScaleFactor));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::Scale(float x, float y, float z) noexcept
|
SHMatrix SHMatrix::Scale(float x, float y, float z) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixScaling(x, y, z));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixScaling(x, y, z));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMatrix SHMatrix::Scale(const SHVec3& scale) noexcept
|
SHMatrix SHMatrix::Scale(const SHVec3& scale) noexcept
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
XMStoreFloat4x4(&result, XMMatrixScaling(scale.x, scale.y, scale.z));
|
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&result, XMMatrixScalingFromVector(scale));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,12 +487,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
const XMVECTOR EYE = XMLoadFloat3(&eye);
|
XMStoreFloat4x4(&result, XMMatrixLookAtRH(eye, target, up));
|
||||||
const XMVECTOR TGT = XMLoadFloat3(&target);
|
|
||||||
const XMVECTOR UP = XMLoadFloat3(&up);
|
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixLookAtRH(EYE, TGT, UP));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,12 +495,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
const XMVECTOR EYE = XMLoadFloat3(&eye);
|
XMStoreFloat4x4(&result, XMMatrixLookAtLH(eye, target, up));
|
||||||
const XMVECTOR TGT = XMLoadFloat3(&target);
|
|
||||||
const XMVECTOR UP = XMLoadFloat3(&up);
|
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixLookAtLH(EYE, TGT, UP));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,8 +505,8 @@ namespace SHADE
|
||||||
|
|
||||||
const SHVec3 FWD_HAT = SHVec3::Normalise(-forward);
|
const SHVec3 FWD_HAT = SHVec3::Normalise(-forward);
|
||||||
|
|
||||||
const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT));
|
const XMVECTOR Z_HAT = XMVector3Normalize(FWD_HAT);
|
||||||
const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT));
|
const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(up, Z_HAT));
|
||||||
const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT);
|
const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT);
|
||||||
|
|
||||||
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._11), X_HAT);
|
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._11), X_HAT);
|
||||||
|
@ -543,8 +526,8 @@ namespace SHADE
|
||||||
|
|
||||||
const SHVec3 FWD_HAT = SHVec3::Normalise(forward);
|
const SHVec3 FWD_HAT = SHVec3::Normalise(forward);
|
||||||
|
|
||||||
const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT));
|
const XMVECTOR Z_HAT = XMVector3Normalize(FWD_HAT);
|
||||||
const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT));
|
const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(up, Z_HAT));
|
||||||
const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT);
|
const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT);
|
||||||
|
|
||||||
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._11), X_HAT);
|
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._11), X_HAT);
|
||||||
|
@ -563,7 +546,6 @@ namespace SHADE
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane));
|
XMStoreFloat4x4(&result, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,7 +554,6 @@ namespace SHADE
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixPerspectiveFovLH(fov, aspectRatio, nearPlane, farPlane));
|
XMStoreFloat4x4(&result, XMMatrixPerspectiveFovLH(fov, aspectRatio, nearPlane, farPlane));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +562,6 @@ namespace SHADE
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane));
|
XMStoreFloat4x4(&result, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +570,6 @@ namespace SHADE
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixPerspectiveLH(width, height, nearPlane, farPlane));
|
XMStoreFloat4x4(&result, XMMatrixPerspectiveLH(width, height, nearPlane, farPlane));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +578,6 @@ namespace SHADE
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixOrthographicRH(width, height, nearPlane, farPlane));
|
XMStoreFloat4x4(&result, XMMatrixOrthographicRH(width, height, nearPlane, farPlane));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +586,6 @@ namespace SHADE
|
||||||
SHMatrix result;
|
SHMatrix result;
|
||||||
|
|
||||||
XMStoreFloat4x4(&result, XMMatrixOrthographicLH(width, height, nearPlane, farPlane));
|
XMStoreFloat4x4(&result, XMMatrixOrthographicLH(width, height, nearPlane, farPlane));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,8 @@ namespace SHADE
|
||||||
SHMatrix& operator= (const SHMatrix& rhs) = default;
|
SHMatrix& operator= (const SHMatrix& rhs) = default;
|
||||||
SHMatrix& operator= (SHMatrix&& rhs) = default;
|
SHMatrix& operator= (SHMatrix&& rhs) = default;
|
||||||
|
|
||||||
|
operator DirectX::XMMATRIX () const noexcept;
|
||||||
|
|
||||||
SHMatrix& operator+= (const SHMatrix& rhs) noexcept;
|
SHMatrix& operator+= (const SHMatrix& rhs) noexcept;
|
||||||
SHMatrix& operator-= (const SHMatrix& rhs) noexcept;
|
SHMatrix& operator-= (const SHMatrix& rhs) noexcept;
|
||||||
SHMatrix& operator*= (const SHMatrix& rhs) noexcept;
|
SHMatrix& operator*= (const SHMatrix& rhs) noexcept;
|
||||||
|
|
|
@ -36,44 +36,18 @@ 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 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(float yaw, float pitch, float roll) noexcept
|
|
||||||
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
|
|
||||||
{
|
|
||||||
XMStoreFloat4(this, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(const SHVec3& eulerAngles) noexcept
|
|
||||||
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
|
|
||||||
{
|
|
||||||
const XMVECTOR V = XMLoadFloat3(&eulerAngles);
|
|
||||||
XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(const SHVec3& axis, float angleInRad) noexcept
|
|
||||||
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
|
|
||||||
{
|
|
||||||
const XMVECTOR AXIS = XMLoadFloat3(&axis);
|
|
||||||
XMStoreFloat4(this, XMQuaternionRotationAxis(AXIS, angleInRad));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(const SHMatrix& rotationMatrix) noexcept
|
|
||||||
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
|
|
||||||
{
|
|
||||||
const XMMATRIX M = XMLoadFloat4x4(&rotationMatrix);
|
|
||||||
XMStoreFloat4(this, XMQuaternionRotationMatrix(M));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(const reactphysics3d::Vector3& rp3dEuler) noexcept
|
SHQuaternion::SHQuaternion(const reactphysics3d::Vector3& rp3dEuler) noexcept
|
||||||
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
|
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
|
||||||
{
|
{
|
||||||
const SHVec3& SHADE_VEC{ rp3dEuler };
|
XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(SHVec3 { rp3dEuler }));
|
||||||
|
|
||||||
const XMVECTOR V = XMLoadFloat3(&SHADE_VEC);
|
|
||||||
XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(const reactphysics3d::Quaternion& rp3dQuat) noexcept
|
SHQuaternion::SHQuaternion(const reactphysics3d::Quaternion& rp3dQuat) noexcept
|
||||||
|
@ -113,10 +87,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
XMStoreFloat4(&result, XMVectorAdd(*this, rhs));
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
|
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMVectorAdd(Q1, Q2));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +95,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
XMStoreFloat4(&result, XMVectorSubtract(*this, rhs));
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
|
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMVectorSubtract(Q1, Q2));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,9 +103,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
XMStoreFloat4(&result, XMVectorNegate(*this));
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMVectorNegate(Q));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +111,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
XMStoreFloat4(&result, XMQuaternionMultiply(*this, rhs));
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
|
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,9 +119,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
XMStoreFloat4(&result, XMVectorScale(*this, rhs));
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMVectorScale(Q, rhs));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,27 +127,18 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
XMStoreFloat4(&result, XMQuaternionMultiply(*this, XMQuaternionInverse(rhs)));
|
||||||
const XMVECTOR Q2 = XMQuaternionInverse(XMLoadFloat4(&rhs));
|
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHQuaternion::operator==(const SHQuaternion& rhs) const noexcept
|
bool SHQuaternion::operator==(const SHQuaternion& rhs) const noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
return XMQuaternionEqual(*this, rhs);
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
|
|
||||||
|
|
||||||
return XMQuaternionEqual(Q1, Q2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHQuaternion::operator!=(const SHQuaternion& rhs) const noexcept
|
bool SHQuaternion::operator!=(const SHQuaternion& rhs) const noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
return XMQuaternionNotEqual(*this, rhs);
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
|
|
||||||
|
|
||||||
return XMQuaternionNotEqual(Q1, Q2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHQuaternion::operator reactphysics3d::Quaternion() const noexcept
|
SHQuaternion::operator reactphysics3d::Quaternion() const noexcept
|
||||||
|
@ -199,6 +151,11 @@ namespace SHADE
|
||||||
return reactphysics3d::Vector3{ ToEuler() };
|
return reactphysics3d::Vector3{ ToEuler() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHQuaternion::operator XMVECTOR() const noexcept
|
||||||
|
{
|
||||||
|
return XMLoadFloat4(this);
|
||||||
|
}
|
||||||
|
|
||||||
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept
|
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept
|
||||||
{
|
{
|
||||||
return rhs * lhs;
|
return rhs * lhs;
|
||||||
|
@ -213,8 +170,7 @@ namespace SHADE
|
||||||
XMVECTOR axis;
|
XMVECTOR axis;
|
||||||
float angle;
|
float angle;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
XMQuaternionToAxisAngle(&axis, &angle, *this);
|
||||||
XMQuaternionToAxisAngle(&axis, &angle, Q);
|
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +179,7 @@ namespace SHADE
|
||||||
XMVECTOR axis;
|
XMVECTOR axis;
|
||||||
float angle;
|
float angle;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
XMQuaternionToAxisAngle(&axis, &angle, *this);
|
||||||
XMQuaternionToAxisAngle(&axis, &angle, Q);
|
|
||||||
|
|
||||||
|
|
||||||
return SHVec4{XMVectorGetX(axis), XMVectorGetY(axis), XMVectorGetZ(axis), angle};
|
return SHVec4{XMVectorGetX(axis), XMVectorGetY(axis), XMVectorGetZ(axis), angle};
|
||||||
|
@ -238,64 +193,49 @@ namespace SHADE
|
||||||
|
|
||||||
void SHQuaternion::Invert() noexcept
|
void SHQuaternion::Invert() noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
XMStoreFloat4(this, XMQuaternionInverse(*this));
|
||||||
XMStoreFloat4(this, XMQuaternionInverse(Q));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHQuaternion::Length() const noexcept
|
float SHQuaternion::Length() const noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
return XMVectorGetX(XMQuaternionLength(*this));
|
||||||
return XMVectorGetX(XMQuaternionLength(Q));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHQuaternion::LengthSquared() const noexcept
|
float SHQuaternion::LengthSquared() const noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Q = XMLoadFloat4(this);
|
return XMVectorGetX(XMQuaternionLengthSq(*this));
|
||||||
return XMVectorGetX(XMQuaternionLengthSq(Q));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHQuaternion::Dot(const SHQuaternion& rhs) const noexcept
|
float SHQuaternion::Dot(const SHQuaternion& rhs) const noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(this);
|
return XMVectorGetX(XMQuaternionDot(*this, rhs));
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
|
|
||||||
|
|
||||||
return XMVectorGetX(XMQuaternionDot(Q1, Q2));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion&, float) const noexcept
|
|
||||||
{
|
|
||||||
SHQuaternion result;
|
|
||||||
|
|
||||||
// TODO (Diren)
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHQuaternion::ToEuler() const noexcept
|
SHVec3 SHQuaternion::ToEuler() const noexcept
|
||||||
{
|
{
|
||||||
const float xx = x * x;
|
const float XX = x * x;
|
||||||
const float yy = y * y;
|
const float YY = y * y;
|
||||||
const float zz = z * z;
|
const float ZZ = z * z;
|
||||||
|
|
||||||
const float m31 = 2.f * x * z + 2.f * y * w;
|
const float M_31 = 2.f * x * z + 2.f * y * w;
|
||||||
const float m32 = 2.f * y * z - 2.f * x * w;
|
const float M_32 = 2.f * y * z - 2.f * x * w;
|
||||||
const float m33 = 1.f - 2.f * xx - 2.f * yy;
|
const float M_33 = 1.f - 2.f * XX - 2.f * YY;
|
||||||
|
|
||||||
const float cy = sqrtf(m33 * m33 + m31 * m31);
|
const float CY = sqrtf(M_33 * M_33 + M_31 * M_31);
|
||||||
const float cx = atan2f(-m32, cy);
|
const float CX = atan2f(-M_32, CY);
|
||||||
if (cy > 16.0f * SHMath::EPSILON)
|
if (CY > 16.0f * SHMath::EPSILON)
|
||||||
{
|
{
|
||||||
const float m12 = 2.f * x * y + 2.f * z * w;
|
const float M_12 = 2.f * x * y + 2.f * z * w;
|
||||||
const float m22 = 1.f - 2.f * xx - 2.f * zz;
|
const float M_22 = 1.f - 2.f * XX - 2.f * ZZ;
|
||||||
|
|
||||||
return SHVec3(cx, atan2f(m31, m33), atan2f(m12, m22));
|
return SHVec3(CX, atan2f(M_31, M_33), atan2f(M_12, M_22));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const float m11 = 1.f - 2.f * yy - 2.f * zz;
|
const float m11 = 1.f - 2.f * YY - 2.f * ZZ;
|
||||||
const float m21 = 2.f * x * y - 2.f * z * w;
|
const float m21 = 2.f * x * y - 2.f * z * w;
|
||||||
|
|
||||||
return SHVec3(cx, 0.f, atan2f(-m21, m11));
|
return SHVec3(CX, 0.f, atan2f(-m21, m11));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,13 +251,43 @@ namespace SHADE
|
||||||
/* Static Function Member Definitions */
|
/* Static Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::FromEuler(const SHVec3& eulerAngles) noexcept
|
||||||
|
{
|
||||||
|
SHQuaternion result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMQuaternionRotationRollPitchYawFromVector(eulerAngles));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::FromPitchYawRoll(float pitch, float yaw, float roll) noexcept
|
||||||
|
{
|
||||||
|
SHQuaternion result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::FromAxisAngle(const SHVec3& axis, float angle) noexcept
|
||||||
|
{
|
||||||
|
SHQuaternion result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMQuaternionRotationAxis(axis, angle));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::FromRotationMatrix(const SHMatrix& rotationMatrix) noexcept
|
||||||
|
{
|
||||||
|
SHQuaternion result;
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMQuaternionRotationMatrix(rotationMatrix));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
SHQuaternion SHQuaternion::Normalise(const SHQuaternion& q) noexcept
|
SHQuaternion SHQuaternion::Normalise(const SHQuaternion& q) noexcept
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(&q);
|
XMStoreFloat4(&result, XMQuaternionNormalize(q));
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMQuaternionNormalize(Q));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,9 +295,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(&q);
|
XMStoreFloat4(&result, XMQuaternionConjugate(q));
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMQuaternionConjugate(Q));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,26 +303,37 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q = XMLoadFloat4(&q);
|
XMStoreFloat4(&result, XMQuaternionInverse(q));
|
||||||
XMStoreFloat4(&result, XMQuaternionInverse(Q));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float SHQuaternion::Angle(const SHQuaternion&, const SHQuaternion&) noexcept
|
float SHQuaternion::Angle(const SHQuaternion& q1, const SHQuaternion& q2) noexcept
|
||||||
{
|
{
|
||||||
// TODO (Diren)
|
XMVECTOR R = XMQuaternionMultiply(XMQuaternionConjugate(q1), q2);
|
||||||
|
|
||||||
return 0.0f;
|
const float RS = XMVectorGetW(R);
|
||||||
|
R = XMVector3Length(R);
|
||||||
|
return 2.0f * atan2f(XMVectorGetX(R), RS);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHQuaternion SHQuaternion::Lerp(const SHQuaternion&, const SHQuaternion&, float) noexcept
|
SHQuaternion SHQuaternion::Lerp(const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
// TODO (Diren)
|
XMVECTOR R = XMVectorZero();
|
||||||
|
if (XMVector4GreaterOrEqual(XMVector4Dot(q1, q2), R))
|
||||||
|
{
|
||||||
|
R = XMVectorLerp(q1, q2, t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const XMVECTOR X0 = XMVectorMultiply(q1, XMVectorReplicate(1.f - t));
|
||||||
|
const XMVECTOR X1 = XMVectorMultiply(q2, XMVectorReplicate(t));
|
||||||
|
R = XMVectorSubtract(X0, X1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMQuaternionNormalize(R));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,19 +341,105 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
const XMVECTOR Q1 = XMLoadFloat4(&q1);
|
XMStoreFloat4(&result, XMQuaternionSlerp(q1, q2, t));
|
||||||
const XMVECTOR Q2 = XMLoadFloat4(&q2);
|
|
||||||
|
|
||||||
XMStoreFloat4(&result, XMQuaternionSlerp(Q1, Q2, t));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHQuaternion SHQuaternion::Rotate(const SHVec3& , const SHVec3&) noexcept
|
SHQuaternion SHQuaternion::ClampedLerp(const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin, float tMax) noexcept
|
||||||
|
{
|
||||||
|
return Lerp(q1, q2, std::clamp(t, tMin, tMax));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::ClampedSlerp(const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin, float tMax) noexcept
|
||||||
|
{
|
||||||
|
return Slerp(q1, q2, std::clamp(t, tMin, tMax));
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::FromToRotation(const SHVec3& from, const SHVec3& to) noexcept
|
||||||
|
{
|
||||||
|
// Melax, "The Shortest Arc Quaternion", Game Programming Gems
|
||||||
|
|
||||||
|
SHQuaternion result;
|
||||||
|
|
||||||
|
const XMVECTOR F = XMVector3Normalize(from);
|
||||||
|
const XMVECTOR T = XMVector3Normalize(to);
|
||||||
|
|
||||||
|
const float dot = XMVectorGetX(XMVector3Dot(F, T));
|
||||||
|
if (dot >= 1.f)
|
||||||
|
{
|
||||||
|
result = Identity;
|
||||||
|
}
|
||||||
|
else if (dot <= -1.f)
|
||||||
|
{
|
||||||
|
XMVECTOR axis = XMVector3Cross(F, SHVec3::Right);
|
||||||
|
if (XMVector3NearEqual(XMVector3LengthSq(axis), g_XMZero, g_XMEpsilon))
|
||||||
|
{
|
||||||
|
axis = XMVector3Cross(F, SHVec3::Up);
|
||||||
|
}
|
||||||
|
|
||||||
|
const XMVECTOR Q = XMQuaternionRotationAxis(axis, XM_PI);
|
||||||
|
XMStoreFloat4(&result, Q);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const XMVECTOR C = XMVector3Cross(F, T);
|
||||||
|
XMStoreFloat4(&result, C);
|
||||||
|
|
||||||
|
const float s = sqrtf((1.f + dot) * 2.f);
|
||||||
|
result.x /= s;
|
||||||
|
result.y /= s;
|
||||||
|
result.z /= s;
|
||||||
|
result.w = s * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::LookRotation(const SHVec3& forward, const SHVec3& up) noexcept
|
||||||
{
|
{
|
||||||
SHQuaternion result;
|
SHQuaternion result;
|
||||||
|
|
||||||
// TODO (Diren)
|
const SHQuaternion Q1 = FromToRotation(SHVec3::Forward, forward);
|
||||||
|
|
||||||
|
const XMVECTOR C = XMVector3Cross(forward, up);
|
||||||
|
if (XMVector3NearEqual(XMVector3LengthSq(C), g_XMZero, g_XMEpsilon))
|
||||||
|
{
|
||||||
|
// forward and up are co-linear
|
||||||
|
return Q1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 qU;
|
||||||
|
XMStoreFloat3(&qU, XMQuaternionMultiply(Q1, SHVec3::Up));
|
||||||
|
|
||||||
|
const SHQuaternion Q2 = FromToRotation(qU, up);
|
||||||
|
|
||||||
|
XMStoreFloat4(&result, XMQuaternionMultiply(Q2, Q1));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion& from, const SHQuaternion& to, float maxAngleInRad) noexcept
|
||||||
|
{
|
||||||
|
SHQuaternion result;
|
||||||
|
|
||||||
|
// We can use the conjugate here instead of inverse assuming q1 & q2 are normalized.
|
||||||
|
const XMVECTOR R = XMQuaternionMultiply(XMQuaternionConjugate(from), to);
|
||||||
|
|
||||||
|
const float RS = XMVectorGetW(R);
|
||||||
|
const XMVECTOR L = XMVector3Length(R);
|
||||||
|
const float angle = 2.f * atan2f(XMVectorGetX(L), RS);
|
||||||
|
if (angle > maxAngleInRad)
|
||||||
|
{
|
||||||
|
const XMVECTOR delta = XMQuaternionRotationAxis(R, maxAngleInRad);
|
||||||
|
const XMVECTOR Q = XMQuaternionMultiply(delta, from);
|
||||||
|
XMStoreFloat4(&result, Q);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Don't overshoot.
|
||||||
|
result = to;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,8 @@ 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 (const SHVec3& eulerAngles) noexcept;
|
|
||||||
SHQuaternion (const SHVec3& axis, float angleInRad) noexcept;
|
|
||||||
SHQuaternion (const SHMatrix& rotationMatrix) noexcept;
|
|
||||||
|
|
||||||
// Conversion from other math types
|
// Conversion from other math types
|
||||||
|
|
||||||
|
@ -87,6 +84,7 @@ namespace SHADE
|
||||||
|
|
||||||
operator reactphysics3d::Quaternion () const noexcept;
|
operator reactphysics3d::Quaternion () const noexcept;
|
||||||
operator reactphysics3d::Vector3 () const noexcept;
|
operator reactphysics3d::Vector3 () const noexcept;
|
||||||
|
operator DirectX::XMVECTOR () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
@ -99,29 +97,37 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void Invert () noexcept;
|
void Invert () noexcept;
|
||||||
|
|
||||||
[[nodiscard]] float Length () const noexcept;
|
[[nodiscard]] float Length () const noexcept;
|
||||||
[[nodiscard]] float LengthSquared () const noexcept;
|
[[nodiscard]] float LengthSquared () const noexcept;
|
||||||
[[nodiscard]] float Dot (const SHQuaternion& rhs) const noexcept;
|
[[nodiscard]] float Dot (const SHQuaternion& rhs) const noexcept;
|
||||||
[[nodiscard]] SHQuaternion RotateTowards (const SHQuaternion& target, float maxAngleInRad) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 ToEuler () const noexcept;
|
[[nodiscard]] SHVec3 ToEuler () const noexcept;
|
||||||
[[nodiscard]] std::string ToString () const noexcept;
|
[[nodiscard]] std::string ToString () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Static Function Members */
|
/* Static Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept;
|
[[nodiscard]] static SHQuaternion FromEuler (const SHVec3& eulerAngles) noexcept;
|
||||||
[[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept;
|
[[nodiscard]] static SHQuaternion FromPitchYawRoll (float pitch, float yaw, float roll) noexcept;
|
||||||
[[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept;
|
[[nodiscard]] static SHQuaternion FromAxisAngle (const SHVec3& axis, float angle) noexcept;
|
||||||
[[nodiscard]] static float Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept;
|
[[nodiscard]] static SHQuaternion FromRotationMatrix(const SHMatrix& rotationMatrix) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept;
|
[[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept;
|
||||||
[[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept;
|
[[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept;
|
||||||
|
[[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept;
|
||||||
|
[[nodiscard]] static float Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] static SHQuaternion Rotate (const SHVec3& from, const SHVec3& to) noexcept;
|
[[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept;
|
||||||
|
[[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept;
|
||||||
|
[[nodiscard]] static SHQuaternion ClampedLerp (const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept;
|
||||||
|
[[nodiscard]] static SHQuaternion ClampedSlerp (const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] static SHQuaternion FromToRotation (const SHVec3& from, const SHVec3& to) noexcept;
|
||||||
|
[[nodiscard]] static SHQuaternion LookRotation (const SHVec3& forward, const SHVec3& up) noexcept;
|
||||||
|
[[nodiscard]] static SHQuaternion RotateTowards (const SHQuaternion& from, const SHQuaternion& to, float maxAngleInRad) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept;
|
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept;
|
||||||
|
|
|
@ -26,15 +26,15 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHTransform::SHTransform() noexcept
|
SHTransform::SHTransform() noexcept
|
||||||
: position { SHVec3::Zero }
|
: position { SHVec3::Zero }
|
||||||
, rotation { SHVec3::Zero }
|
, orientation { SHQuaternion::Identity }
|
||||||
, scale { SHVec3::One }
|
, scale { SHVec3::One }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHTransform::SHTransform(const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept
|
SHTransform::SHTransform(const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept
|
||||||
: position { pos }
|
: position { pos }
|
||||||
, rotation { rot }
|
, orientation { SHQuaternion::FromEuler(rot) }
|
||||||
, scale { scl }
|
, scale { scl }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -43,12 +43,12 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHTransform::operator==(const SHTransform& rhs) const noexcept
|
bool SHTransform::operator==(const SHTransform& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return !(position != rhs.position || rotation != rhs.rotation || scale != rhs.scale);
|
return !(position != rhs.position || orientation != rhs.orientation || scale != rhs.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHTransform::operator!=(const SHTransform& rhs) const noexcept
|
bool SHTransform::operator!=(const SHTransform& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return (position != rhs.position || rotation != rhs.rotation || scale != rhs.scale);
|
return (position != rhs.position || orientation != rhs.orientation || scale != rhs.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -59,7 +59,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
const SHMatrix T = SHMatrix::Translate(position);
|
const SHMatrix T = SHMatrix::Translate(position);
|
||||||
const SHMatrix R = SHMatrix::Rotate(rotation);
|
const SHMatrix R = SHMatrix::Rotate(orientation);
|
||||||
const SHMatrix S = SHMatrix::Scale(scale);
|
const SHMatrix S = SHMatrix::Scale(scale);
|
||||||
|
|
||||||
trs = S * R * T;
|
trs = S * R * T;
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "Math/Vector/SHVec2.h"
|
|
||||||
#include "Math/Vector/SHVec3.h"
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/SHQuaternion.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -31,22 +31,23 @@ namespace SHADE
|
||||||
|
|
||||||
static const SHTransform Identity;
|
static const SHTransform Identity;
|
||||||
|
|
||||||
SHVec3 position;
|
SHVec3 position;
|
||||||
SHVec3 rotation;
|
SHQuaternion orientation;
|
||||||
SHVec3 scale;
|
SHVec3 scale;
|
||||||
|
|
||||||
SHMatrix trs;
|
SHMatrix trs;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructors & Destructor */
|
/* Constructors & Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHTransform (const SHTransform&) = default;
|
SHTransform (const SHTransform&) = default;
|
||||||
SHTransform (SHTransform&&) = default;
|
SHTransform (SHTransform&&) = default;
|
||||||
~SHTransform () = default;
|
~SHTransform () = default;
|
||||||
|
|
||||||
SHTransform () noexcept;
|
SHTransform () noexcept;
|
||||||
SHTransform (const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept;
|
SHTransform (const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept;
|
||||||
|
SHTransform (const SHVec3& pos, const SHQuaternion& quat, const SHVec3& scl) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Operator Overloads */
|
||||||
|
@ -63,7 +64,6 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
const SHMatrix& ComputeTRS();
|
const SHMatrix& ComputeTRS();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SHTransformComponent.h"
|
#include "SHTransformComponent.h"
|
||||||
|
// Project Headers
|
||||||
|
#include "Math/SHMathHelpers.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -40,7 +42,12 @@ namespace SHADE
|
||||||
|
|
||||||
const SHVec3& SHTransformComponent::GetLocalRotation() const noexcept
|
const SHVec3& SHTransformComponent::GetLocalRotation() const noexcept
|
||||||
{
|
{
|
||||||
return local.rotation;
|
return localRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHQuaternion& SHTransformComponent::GetLocalOrientation() const noexcept
|
||||||
|
{
|
||||||
|
return local.orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHTransformComponent::GetLocalScale() const noexcept
|
const SHVec3& SHTransformComponent::GetLocalScale() const noexcept
|
||||||
|
@ -55,7 +62,12 @@ namespace SHADE
|
||||||
|
|
||||||
const SHVec3& SHTransformComponent::GetWorldRotation() const noexcept
|
const SHVec3& SHTransformComponent::GetWorldRotation() const noexcept
|
||||||
{
|
{
|
||||||
return world.rotation;
|
return worldRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHQuaternion& SHTransformComponent::GetWorldOrientation() const noexcept
|
||||||
|
{
|
||||||
|
return world.orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHTransformComponent::GetWorldScale() const noexcept
|
const SHVec3& SHTransformComponent::GetWorldScale() const noexcept
|
||||||
|
@ -91,16 +103,28 @@ namespace SHADE
|
||||||
void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept
|
void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
local.rotation = 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
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
local.rotation.x = pitch;
|
localRotation.x = pitch;
|
||||||
local.rotation.y = yaw;
|
localRotation.y = yaw;
|
||||||
local.rotation.z = roll;
|
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
|
void SHTransformComponent::SetLocalScale(const SHVec3& newLocalScale) noexcept
|
||||||
|
@ -121,7 +145,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
world.rotation = newWorldRotation;
|
worldRotation = newWorldRotation;
|
||||||
updateQueue.push({ UpdateCommandType::WORLD_ROTATION, newWorldRotation });
|
updateQueue.push({ UpdateCommandType::WORLD_ROTATION, newWorldRotation });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,13 +153,21 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
world.rotation.x = pitch;
|
worldRotation.x = pitch;
|
||||||
world.rotation.y = yaw;
|
worldRotation.y = yaw;
|
||||||
world.rotation.z = roll;
|
worldRotation.z = roll;
|
||||||
|
|
||||||
updateQueue.push({ UpdateCommandType::WORLD_ROTATION, SHVec3{ pitch, yaw, roll} });
|
updateQueue.push({ UpdateCommandType::WORLD_ROTATION, SHVec3{ pitch, yaw, roll} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
@ -153,6 +185,6 @@ RTTR_REGISTRATION
|
||||||
|
|
||||||
registration::class_<SHTransformComponent>("Transform Component")
|
registration::class_<SHTransformComponent>("Transform Component")
|
||||||
.property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition )
|
.property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition )
|
||||||
.property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload<void(SHVec3 const&)>(&SHTransformComponent::SetLocalRotation) )
|
.property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation) )
|
||||||
.property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale );
|
.property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale );
|
||||||
}
|
}
|
|
@ -56,42 +56,52 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] bool HasChanged () const noexcept;
|
[[nodiscard]] bool HasChanged () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetLocalPosition () const noexcept;
|
[[nodiscard]] const SHVec3& GetLocalPosition () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetLocalRotation () const noexcept;
|
[[nodiscard]] const SHVec3& GetLocalRotation () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetLocalScale () const noexcept;
|
[[nodiscard]] const SHQuaternion& GetLocalOrientation () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetWorldPosition () const noexcept;
|
[[nodiscard]] const SHVec3& GetLocalScale () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetWorldRotation () const noexcept;
|
[[nodiscard]] const SHVec3& GetWorldPosition () const noexcept;
|
||||||
[[nodiscard]] const SHVec3& GetWorldScale () const noexcept;
|
[[nodiscard]] const SHVec3& GetWorldRotation () const noexcept;
|
||||||
|
[[nodiscard]] const SHQuaternion& GetWorldOrientation () const noexcept;
|
||||||
|
[[nodiscard]] const SHVec3& GetWorldScale () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHMatrix& GetLocalToWorld () const noexcept;
|
[[nodiscard]] const SHMatrix& GetLocalToWorld () const noexcept;
|
||||||
[[nodiscard]] SHMatrix GetWorldToLocal () const noexcept;
|
[[nodiscard]] SHMatrix GetWorldToLocal () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHMatrix& GetTRS () const noexcept;
|
[[nodiscard]] const SHMatrix& GetTRS () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetLocalPosition (const SHVec3& newLocalPosition) noexcept;
|
void SetLocalPosition (const SHVec3& newLocalPosition) noexcept;
|
||||||
void SetLocalRotation (const SHVec3& newLocalRotation) noexcept;
|
void SetLocalRotation (const SHVec3& newLocalRotation) noexcept;
|
||||||
void SetLocalRotation (float pitch, float yaw, float roll) noexcept;
|
void SetLocalRotation (float pitch, float yaw, float roll) noexcept;
|
||||||
void SetLocalScale (const SHVec3& newLocalScale) noexcept;
|
void SetLocalOrientation (const SHQuaternion& newLocalOrientation) noexcept;
|
||||||
void SetWorldPosition (const SHVec3& newWorldPosition) noexcept;
|
void SetLocalScale (const SHVec3& newLocalScale) noexcept;
|
||||||
void SetWorldRotation (const SHVec3& newWorldRotation) noexcept;
|
void SetWorldPosition (const SHVec3& newWorldPosition) noexcept;
|
||||||
void SetWorldRotation (float pitch, float yaw, float roll) noexcept;
|
void SetWorldRotation (const SHVec3& newWorldRotation) noexcept;
|
||||||
void SetWorldScale (const SHVec3& newWorldScale) noexcept;
|
void SetWorldRotation (float pitch, float yaw, float roll) noexcept;
|
||||||
|
void SetWorldOrientation (const SHQuaternion& newWorldOrientation) noexcept;
|
||||||
|
void SetWorldScale (const SHVec3& newWorldScale) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Differentiate between rotation and orientation for setters
|
||||||
|
// Setting a quaternion directly is different from using euler angle rotations.
|
||||||
|
|
||||||
enum class UpdateCommandType
|
enum class UpdateCommandType
|
||||||
{
|
{
|
||||||
WORLD_POSITION
|
LOCAL_ROTATION
|
||||||
|
, LOCAL_ORIENTATION
|
||||||
|
, WORLD_POSITION
|
||||||
, WORLD_ROTATION
|
, WORLD_ROTATION
|
||||||
|
, WORLD_ORIENTATION
|
||||||
, WORLD_SCALE
|
, WORLD_SCALE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,7 +113,7 @@ namespace SHADE
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
UpdateCommandType type;
|
UpdateCommandType type;
|
||||||
SHVec3 data;
|
SHVec4 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
using UpdateQueue = std::queue<UpdateCommand>;
|
using UpdateQueue = std::queue<UpdateCommand>;
|
||||||
|
@ -114,6 +124,12 @@ namespace SHADE
|
||||||
|
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
|
||||||
|
// We store euler angle rotations separately to interface with transform quaternions.
|
||||||
|
// Reading quaternions are unreliable.
|
||||||
|
|
||||||
|
SHVec3 localRotation; // Stored in Radians
|
||||||
|
SHVec3 worldRotation; // Stored in Radians
|
||||||
|
|
||||||
SHTransform local; // Local TRS holds Local To World Transform
|
SHTransform local; // Local TRS holds Local To World Transform
|
||||||
SHTransform world;
|
SHTransform world;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#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 "Tools/SHException.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Math/SHMathHelpers.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -29,8 +30,12 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHTransformSystem::TransformUpdateRoutine::TransformUpdateRoutine()
|
SHTransformSystem::TransformPostLogicUpdate::TransformPostLogicUpdate()
|
||||||
: SHSystemRoutine { "Transform Update", true }
|
: SHSystemRoutine { "Transform Post-Logic Update", true }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHTransformSystem::TransformPostPhysicsUpdate::TransformPostPhysicsUpdate()
|
||||||
|
: SHSystemRoutine { "Transform Post-Physics Update", false }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,16 +43,27 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHTransformSystem::TransformUpdateRoutine::Execute(double) noexcept
|
void SHTransformSystem::TransformPostLogicUpdate::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
// Get the current scene graph to traverse and update
|
// Get the current scene graph to traverse and update
|
||||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
UpdateEntity(SCENE_GRAPH.GetRoot());
|
|
||||||
|
// TODO(Diren): Consider how to clear dirty in pause / stop mode and update physics, but do not clear in play mode.
|
||||||
|
UpdateEntity(SCENE_GRAPH.GetRoot(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept
|
||||||
|
{
|
||||||
|
// Get the current scene graph to traverse and update
|
||||||
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
UpdateEntity(SCENE_GRAPH.GetRoot(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTransformSystem::Init()
|
void SHTransformSystem::Init()
|
||||||
{
|
{
|
||||||
|
std::shared_ptr thisReceiver { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
|
||||||
|
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
|
||||||
|
SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTransformSystem::Exit()
|
void SHTransformSystem::Exit()
|
||||||
|
@ -59,7 +75,97 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHTransformSystem::UpdateEntity(const SHSceneNode* node)
|
SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent)
|
||||||
|
{
|
||||||
|
const auto& eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphChangeParentEvent>*>(changeParentEvent.get());
|
||||||
|
|
||||||
|
auto* node = eventData->data->node;
|
||||||
|
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
|
||||||
|
|
||||||
|
// Recompute local transform and store localToWorld Matrix
|
||||||
|
SHMatrix localToWorld = SHMatrix::Identity;
|
||||||
|
SHMatrix worldToLocal = SHMatrix::Identity;
|
||||||
|
|
||||||
|
auto* newParent = eventData->data->newParent;
|
||||||
|
const auto* PARENT_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(newParent->GetEntityID());
|
||||||
|
if (PARENT_TF != nullptr) // Not the root
|
||||||
|
{
|
||||||
|
localToWorld = PARENT_TF->GetTRS();
|
||||||
|
worldToLocal = SHMatrix::Inverse(localToWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maintain World Transform and recompute Local Transform
|
||||||
|
|
||||||
|
// Compute Local Position
|
||||||
|
tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal);
|
||||||
|
|
||||||
|
|
||||||
|
tf->localRotation = tf->worldRotation;
|
||||||
|
tf->local.scale = tf->world.scale;
|
||||||
|
|
||||||
|
if (PARENT_TF != nullptr)
|
||||||
|
{
|
||||||
|
// Compute Local Rotation
|
||||||
|
tf->localRotation -= PARENT_TF->GetLocalRotation();
|
||||||
|
|
||||||
|
// Compute Local Scale
|
||||||
|
tf->local.scale /= PARENT_TF->GetLocalScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
tf->local.trs = localToWorld;
|
||||||
|
|
||||||
|
// Propagate maintaining world transform down the branch
|
||||||
|
UpdateChildrenLocalTransforms(node);
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTransformSystem::UpdateChildrenLocalTransforms(SHSceneNode* node)
|
||||||
|
{
|
||||||
|
// Structure is similar to update entity, albeit without a queue to do being a forced update
|
||||||
|
for (const auto* child : node->GetChildren())
|
||||||
|
{
|
||||||
|
if (auto* childTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(child->GetEntityID()); childTransform)
|
||||||
|
{
|
||||||
|
const bool IS_NODE_ACTIVE = child->IsActive();
|
||||||
|
if (IS_NODE_ACTIVE && childTransform->isActive)
|
||||||
|
{
|
||||||
|
// Recompute local transform and store localToWorld Matrix
|
||||||
|
SHMatrix localToWorld = SHMatrix::Identity;
|
||||||
|
SHMatrix worldToLocal = SHMatrix::Identity;
|
||||||
|
|
||||||
|
const auto* parent = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
|
||||||
|
|
||||||
|
if (parent != nullptr) // Not the root
|
||||||
|
{
|
||||||
|
localToWorld = parent->GetTRS();
|
||||||
|
worldToLocal = SHMatrix::Inverse(localToWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maintain World Transform and recompute Local Transform
|
||||||
|
|
||||||
|
// Compute Local Position
|
||||||
|
childTransform->local.position = SHVec3::Transform(childTransform->world.position, worldToLocal);
|
||||||
|
|
||||||
|
|
||||||
|
childTransform->localRotation = childTransform->worldRotation;
|
||||||
|
childTransform->local.scale = childTransform->world.scale;
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
// Compute Local Rotation
|
||||||
|
childTransform->localRotation -= parent->GetLocalRotation();
|
||||||
|
|
||||||
|
// Compute Local Scale
|
||||||
|
childTransform->local.scale /= parent->GetLocalScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
childTransform->local.trs = localToWorld;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTransformSystem::UpdateEntity(const SHSceneNode* node, bool clearDirtyFlag)
|
||||||
{
|
{
|
||||||
const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
|
const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
|
||||||
const bool HAS_PARENT_CHANGED = NODE_TRANSFORM && NODE_TRANSFORM->dirty;
|
const bool HAS_PARENT_CHANGED = NODE_TRANSFORM && NODE_TRANSFORM->dirty;
|
||||||
|
@ -74,14 +180,17 @@ namespace SHADE
|
||||||
if (IS_NODE_ACTIVE && childTransform->isActive)
|
if (IS_NODE_ACTIVE && childTransform->isActive)
|
||||||
{
|
{
|
||||||
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
||||||
|
{
|
||||||
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
||||||
|
childTransform->dirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateEntity(child);
|
UpdateEntity(child, clearDirtyFlag);
|
||||||
|
|
||||||
// Clear dirty flag after all children are updated
|
// Clear dirty flag after all children are updated
|
||||||
if (childTransform)
|
if (childTransform && clearDirtyFlag)
|
||||||
childTransform->dirty = false;
|
childTransform->dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,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();
|
||||||
|
@ -103,22 +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.local.rotation = tf.world.rotation;
|
tf.localRotation = UPDATE_COMMAND.data.ToVec3();
|
||||||
if (parent)
|
if (parent)
|
||||||
tf.local.rotation -= parent->GetLocalRotation();
|
tf.localRotation -= parent->GetLocalRotation();
|
||||||
|
|
||||||
|
convertRotation = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SHTransformComponent::UpdateCommandType::WORLD_ORIENTATION:
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
|
||||||
|
@ -133,15 +266,38 @@ 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.rotation = tf.local.rotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
|
||||||
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One);
|
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One);
|
||||||
|
|
||||||
tf.world.ComputeTRS();
|
|
||||||
|
|
||||||
// Transpose TRS to column major
|
|
||||||
//tf.local.trs.Transpose();
|
if (convertRotation)
|
||||||
//tf.world.trs.Transpose();
|
{
|
||||||
|
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
||||||
|
|
||||||
|
// Set the orientation
|
||||||
|
// Wrap rotations between -360 and 360 and convert to radians
|
||||||
|
SHVec3 worldRotRad, localRotRad;
|
||||||
|
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
||||||
|
{
|
||||||
|
worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI);
|
||||||
|
localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
tf.worldRotation = tf.world.orientation.ToEuler();
|
||||||
|
tf.localRotation = tf.local.orientation.ToEuler();
|
||||||
|
}
|
||||||
|
|
||||||
|
tf.world.ComputeTRS();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -45,25 +45,52 @@ namespace SHADE
|
||||||
/* System Routines */
|
/* System Routines */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API TransformUpdateRoutine final: public SHSystemRoutine
|
class SH_API TransformPostLogicUpdate final: public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
/* Constructors & Destructor */
|
/* Constructors & Destructor */
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
TransformUpdateRoutine ();
|
TransformPostLogicUpdate ();
|
||||||
~TransformUpdateRoutine () = default;
|
~TransformPostLogicUpdate () = default;
|
||||||
|
|
||||||
TransformUpdateRoutine (const TransformUpdateRoutine&) = delete;
|
TransformPostLogicUpdate (const TransformPostLogicUpdate&) = delete;
|
||||||
TransformUpdateRoutine (TransformUpdateRoutine&&) = delete;
|
TransformPostLogicUpdate (TransformPostLogicUpdate&&) = delete;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Operator Overloads */
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
TransformUpdateRoutine& operator= (const TransformUpdateRoutine&) = delete;
|
TransformPostLogicUpdate& operator= (const TransformPostLogicUpdate&) = delete;
|
||||||
TransformUpdateRoutine& operator= (TransformUpdateRoutine&&) = delete;
|
TransformPostLogicUpdate& operator= (TransformPostLogicUpdate&&) = delete;
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
/* Function Members */
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void Execute(double dt) noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SH_API TransformPostPhysicsUpdate final: public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
TransformPostPhysicsUpdate ();
|
||||||
|
~TransformPostPhysicsUpdate () = default;
|
||||||
|
|
||||||
|
TransformPostPhysicsUpdate (const TransformPostPhysicsUpdate&) = delete;
|
||||||
|
TransformPostPhysicsUpdate (TransformPostPhysicsUpdate&&) = delete;
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
TransformPostPhysicsUpdate& operator= (const TransformPostPhysicsUpdate&) = delete;
|
||||||
|
TransformPostPhysicsUpdate& operator= (TransformPostPhysicsUpdate&&) = delete;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -84,8 +111,11 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void UpdateEntity (const SHSceneNode* node);
|
SHEventHandle ChangeParent (SHEventPtr changeParentEvent);
|
||||||
static void UpdateTransform(SHTransformComponent& tf, const SHTransformComponent* parent = nullptr);
|
static void UpdateChildrenLocalTransforms (SHSceneNode* node);
|
||||||
|
|
||||||
|
static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag);
|
||||||
|
static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -140,12 +140,12 @@ namespace SHADE
|
||||||
isRigidBody = true;
|
isRigidBody = true;
|
||||||
|
|
||||||
rb->position = tf->GetWorldPosition();
|
rb->position = tf->GetWorldPosition();
|
||||||
rb->orientation = tf->GetWorldRotation();
|
rb->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation());
|
||||||
|
|
||||||
if (hasColliders)
|
if (hasColliders)
|
||||||
{
|
{
|
||||||
c->position = tf->GetWorldPosition();
|
c->position = tf->GetWorldPosition();
|
||||||
c->orientation = tf->GetWorldRotation();
|
c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation());
|
||||||
// Get array of colliders and add them back into the rigidbody
|
// Get array of colliders and add them back into the rigidbody
|
||||||
for (auto& collider : c->colliders | std::views::keys)
|
for (auto& collider : c->colliders | std::views::keys)
|
||||||
AddCollider(&collider);
|
AddCollider(&collider);
|
||||||
|
@ -160,7 +160,7 @@ namespace SHADE
|
||||||
hasColliders = true;
|
hasColliders = true;
|
||||||
|
|
||||||
c->position = tf->GetWorldPosition();
|
c->position = tf->GetWorldPosition();
|
||||||
c->orientation = tf->GetWorldRotation();
|
c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation());
|
||||||
|
|
||||||
for (auto& collider : c->colliders | std::views::keys)
|
for (auto& collider : c->colliders | std::views::keys)
|
||||||
AddCollider(&collider);
|
AddCollider(&collider);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Events/SHEventManager.hpp"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
#include "Tools/SHException.h"
|
#include "Tools/SHException.h"
|
||||||
|
|
||||||
|
@ -317,6 +318,11 @@ namespace SHADE
|
||||||
if (parentNode == nullptr)
|
if (parentNode == nullptr)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
parent->RemoveChild(this);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle self assignment
|
// Handle self assignment
|
||||||
|
@ -359,10 +365,19 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
const SHSceneGraphChangeParentEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.node = NODE_ITER->second
|
||||||
|
, .oldParent = NODE_ITER->second->GetParent()
|
||||||
|
, .newParent = parent ? parent : root
|
||||||
|
};
|
||||||
|
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
parent = root;
|
parent = root;
|
||||||
|
|
||||||
NODE_ITER->second->SetParent(parent);
|
NODE_ITER->second->SetParent(parent);
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
||||||
|
@ -396,8 +411,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
const SHSceneGraphChangeParentEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.node = NODE_ITER->second
|
||||||
|
, .oldParent = NODE_ITER->second->GetParent()
|
||||||
|
, .newParent = PARENT_ITER->second
|
||||||
|
};
|
||||||
|
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
currentNode->SetParent(PARENT_ITER->second);
|
currentNode->SetParent(PARENT_ITER->second);
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -558,7 +582,7 @@ namespace SHADE
|
||||||
ReleaseNode(node);
|
ReleaseNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::Traverse (const UnaryPredicate& predicate) const
|
void SHSceneGraph::Traverse (const UnaryFunction& predicate) const
|
||||||
{
|
{
|
||||||
TraverseAndInvokePredicate(root, predicate);
|
TraverseAndInvokePredicate(root, predicate);
|
||||||
}
|
}
|
||||||
|
@ -597,7 +621,7 @@ namespace SHADE
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::TraverseAndInvokePredicate(const SHSceneNode* node, const UnaryPredicate& predicate)
|
void SHSceneGraph::TraverseAndInvokePredicate(const SHSceneNode* node, const UnaryFunction& predicate)
|
||||||
{
|
{
|
||||||
for (auto* child : node->children)
|
for (auto* child : node->children)
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,9 +97,8 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
using EntityNodeMap = std::unordered_map<EntityID, SHSceneNode*>;
|
using EntityNodeMap = std::unordered_map<EntityID, SHSceneNode*>;
|
||||||
|
using UnaryFunction = std::function<void(SHSceneNode*)>;
|
||||||
using UnaryPredicate = std::function<void(SHSceneNode*)>;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -143,8 +142,7 @@ namespace SHADE
|
||||||
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
||||||
void Reset () noexcept;
|
void Reset () noexcept;
|
||||||
|
|
||||||
void Traverse (const UnaryPredicate& predicate) const;
|
void Traverse (const UnaryFunction& predicate) const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -160,8 +158,14 @@ namespace SHADE
|
||||||
|
|
||||||
SHSceneNode* AllocateNode (EntityID entityID);
|
SHSceneNode* AllocateNode (EntityID entityID);
|
||||||
void ReleaseNode (SHSceneNode* node) noexcept;
|
void ReleaseNode (SHSceneNode* node) noexcept;
|
||||||
static void TraverseAndInvokePredicate (const SHSceneNode* node, const UnaryPredicate& predicate);
|
static void TraverseAndInvokePredicate (const SHSceneNode* node, const UnaryFunction& predicate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SHSceneGraphChangeParentEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* node;
|
||||||
|
SHSceneNode* oldParent;
|
||||||
|
SHSceneNode* newParent;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -0,0 +1,17 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file Quaternion.hxx
|
||||||
|
\author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
\par email: diren.dbharwani\@digipen.edu
|
||||||
|
\date Oct 23, 2022
|
||||||
|
\brief Contains the definitions of Quaternion struct.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// TODO(Diren)
|
|
@ -11,6 +11,7 @@ Copyright (C) 2021 DigiPen Institute of Technology.
|
||||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
of DigiPen Institute of Technology is prohibited.
|
of DigiPen Institute of Technology is prohibited.
|
||||||
*//*************************************************************************************/
|
*//*************************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Standard Libraries
|
// Standard Libraries
|
||||||
|
|
Loading…
Reference in New Issue