SP3-16 Quaternions #112

Merged
direnbharwani merged 17 commits from SP3-16-Math into main 2022-10-23 20:07:17 +08:00
5 changed files with 84 additions and 30 deletions
Showing only changes of commit fda33f7461 - Show all commits

View File

@ -78,7 +78,7 @@ namespace Sandbox
// Create Stress Test Objects
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One;
constexpr int NUM_ROWS = 2;
constexpr int NUM_ROWS = 3;
constexpr int NUM_COLS = 1;
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 };

View File

@ -64,17 +64,18 @@ namespace SHADE
{
const auto& eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphChangeParentEvent>*>(changeParentEvent.get());
// Get Current Respective Components
auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(eventData->data->entityID);
const auto* PARENT = SHComponentManager::GetComponent_s<SHTransformComponent>(eventData->data->newParentID);
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;
if (PARENT != nullptr) // Not the root
auto* newParent = eventData->data->newParent;
const auto* PARENT_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(newParent->GetEntityID());
if (PARENT_TF != nullptr) // Not the root
{
localToWorld = PARENT->GetTRS();
localToWorld = PARENT_TF->GetTRS();
worldToLocal = SHMatrix::Inverse(localToWorld);
}
@ -83,21 +84,74 @@ namespace SHADE
// Compute Local Position
tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal);
// Compute Local Rotation
tf->local.rotation = tf->world.rotation;
if (PARENT)
tf->local.rotation -= PARENT->GetLocalRotation();
tf->local.rotation = tf->world.rotation;
tf->local.scale = tf->world.scale;
// Compute Local Scale
tf->local.scale = tf->world.scale;
if (PARENT)
tf->local.scale /= PARENT->GetLocalScale();
if (PARENT_TF != nullptr)
{
// Compute Local Rotation
tf->local.rotation -= 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->local.rotation = childTransform->world.rotation;
childTransform->local.scale = childTransform->world.scale;
if (parent)
{
// Compute Local Rotation
childTransform->local.rotation -= parent->GetLocalRotation();
// Compute Local Scale
childTransform->local.scale /= parent->GetLocalScale();
}
childTransform->local.trs = localToWorld;
}
}
}
}
void SHTransformSystem::UpdateEntity(const SHSceneNode* node)
{
const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
@ -113,7 +167,10 @@ namespace SHADE
if (IS_NODE_ACTIVE && childTransform->isActive)
{
if (childTransform->dirty || HAS_PARENT_CHANGED)
{
UpdateTransform(*childTransform, NODE_TRANSFORM);
childTransform->dirty = true;
}
}
}
@ -177,10 +234,6 @@ namespace SHADE
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One);
tf.world.ComputeTRS();
// Transpose TRS to column major
//tf.local.trs.Transpose();
//tf.world.trs.Transpose();
}
} // namespace SHADE

View File

@ -84,10 +84,11 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHEventHandle ChangeParent (SHEventPtr changeParentEvent);
SHEventHandle ChangeParent (SHEventPtr changeParentEvent);
static void UpdateChildrenLocalTransforms (SHSceneNode* node);
static void UpdateEntity (const SHSceneNode* node);
static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr);
static void UpdateEntity (const SHSceneNode* node);
static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr);
};

View File

@ -367,9 +367,9 @@ namespace SHADE
const SHSceneGraphChangeParentEvent EVENT_DATA
{
.entityID = entityID
, .oldParentID = NODE_ITER->second->GetParent()->GetEntityID()
, .newParentID = parent ? parent->GetEntityID() : root->GetEntityID()
.node = NODE_ITER->second
, .oldParent = NODE_ITER->second->GetParent()
, .newParent = parent ? parent : root
};
if (parent == nullptr)
@ -413,9 +413,9 @@ namespace SHADE
const SHSceneGraphChangeParentEvent EVENT_DATA
{
.entityID = entityID
, .oldParentID = NODE_ITER->second->GetParent()->GetEntityID()
, .newParentID = parent
.node = NODE_ITER->second
, .oldParent = NODE_ITER->second->GetParent()
, .newParent = PARENT_ITER->second
};
SHSceneNode* currentNode = NODE_ITER->second;

View File

@ -163,9 +163,9 @@ namespace SHADE
struct SHSceneGraphChangeParentEvent
{
EntityID entityID;
EntityID oldParentID;
EntityID newParentID;
SHSceneNode* node;
SHSceneNode* oldParent;
SHSceneNode* newParent;
};
} // namespace SHADE