SP3-16 Quaternions #112
|
@ -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 };
|
||||
|
|
|
@ -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();
|
||||
|
||||
// Compute Local Scale
|
||||
tf->local.scale = tf->world.scale;
|
||||
if (PARENT)
|
||||
tf->local.scale /= PARENT->GetLocalScale();
|
||||
tf->local.rotation = tf->world.rotation;
|
||||
tf->local.scale = tf->world.scale;
|
||||
|
||||
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
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -163,9 +163,9 @@ namespace SHADE
|
|||
|
||||
struct SHSceneGraphChangeParentEvent
|
||||
{
|
||||
EntityID entityID;
|
||||
EntityID oldParentID;
|
||||
EntityID newParentID;
|
||||
SHSceneNode* node;
|
||||
SHSceneNode* oldParent;
|
||||
SHSceneNode* newParent;
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
Loading…
Reference in New Issue