Fix a transform update issue.

This commit is contained in:
Anish Bhobe 2024-07-20 09:33:47 +02:00
parent ab947ad9f9
commit 41a1725c34
2 changed files with 28 additions and 10 deletions

View File

@ -542,14 +542,14 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
const mat4 transform = const mat4 transform =
translate(mat4(1.0f), nodeTranslation) * mat4_cast(nodeRotation) * scale(mat4(1.0f), nodeScale) * nodeMatrix; translate(mat4(1.0f), nodeTranslation) * mat4_cast(nodeRotation) * scale(mat4(1.0f), nodeScale) * nodeMatrix;
const u32 nodeArrayIndex = nodes.Add(transform, parent); const i32 nodeArrayIndex = Cast<i32>(nodes.Add(transform, parent));
if (node->mesh >= 0) if (node->mesh >= 0)
{ {
auto [start, count] = meshPrimRanges[node->mesh]; auto [start, count] = meshPrimRanges[node->mesh];
const auto end = start + count; const auto end = start + count;
for (usize i = start; i != end; ++i) for (usize i = start; i != end; ++i)
{ {
meshPrimitives[i].m_TransformIdx = Cast<i32>(nodeArrayIndex); meshPrimitives[i].m_TransformIdx = nodeArrayIndex;
} }
} }
@ -711,7 +711,7 @@ Model::operator=(Model &&other) noexcept
m_NormalHandle = other.m_NormalHandle; m_NormalHandle = other.m_NormalHandle;
m_TexCoord0Handle = other.m_TexCoord0Handle; m_TexCoord0Handle = other.m_TexCoord0Handle;
m_VertexColorHandle = other.m_VertexColorHandle; m_VertexColorHandle = other.m_VertexColorHandle;
m_NodeHandle = std::move(other.m_NodeHandle); m_NodeHandle = other.m_NodeHandle;
m_IndexBuffer = other.m_IndexBuffer; m_IndexBuffer = other.m_IndexBuffer;
m_MeshPrimitives = std::move(other.m_MeshPrimitives); m_MeshPrimitives = std::move(other.m_MeshPrimitives);
return *this; return *this;

View File

@ -34,6 +34,7 @@ struct Nodes
{ {
eastl::vector<mat4> m_Transforms; eastl::vector<mat4> m_Transforms;
eastl::vector<mat4> m_GlobalTransforms; eastl::vector<mat4> m_GlobalTransforms;
/// Parents are also used for bookkeeping
eastl::vector<u32> m_Parents_; eastl::vector<u32> m_Parents_;
bool m_Dirty = true; bool m_Dirty = true;
@ -42,10 +43,10 @@ struct Nodes
constexpr static u32 PARENT_MASK = ~(ROOT_BIT | DIRTY_BIT); constexpr static u32 PARENT_MASK = ~(ROOT_BIT | DIRTY_BIT);
u32 u32
Add(const mat4& transform, i32 parent = -1) Add(const mat4& transform, const i32 parent = -1)
{ {
m_Dirty = true; m_Dirty = true;
u32 index = Count(); const u32 index = Count();
m_Transforms.push_back(transform); m_Transforms.push_back(transform);
m_GlobalTransforms.push_back(transform); m_GlobalTransforms.push_back(transform);
const u32 parentVal = (parent < 0 ? ROOT_BIT : parent & PARENT_MASK) | DIRTY_BIT; const u32 parentVal = (parent < 0 ? ROOT_BIT : parent & PARENT_MASK) | DIRTY_BIT;
@ -113,22 +114,39 @@ struct Nodes
while (parentIter != parentEnd) while (parentIter != parentEnd)
{ {
if (!(*parentIter & ROOT_BIT) && *parentIter & DIRTY_BIT) const bool isRoot = *parentIter & ROOT_BIT;
const bool isDirty = *parentIter & DIRTY_BIT;
if (isRoot)
{ {
u32 parent = *parentIter & PARENT_MASK; if (isDirty)
*globalTransformIter = m_GlobalTransforms[parent] * *transformIter; {
// Copy-update if the root is dirty.
*globalTransformIter = *transformIter;
}
} }
else else
{ {
*globalTransformIter = *transformIter; const u32 parentIdx = *parentIter & PARENT_MASK;
const bool isParentDirty = m_Parents_[parentIdx] & DIRTY_BIT;
if (isDirty || isParentDirty)
{
// Update w.r.t parent if either local or parent transforms updated.
*globalTransformIter = m_GlobalTransforms[parentIdx] * *transformIter;
m_Parents_[parentIdx] |= m_Dirty; // Set dirty to propagate the update.
}
} }
*parentIter &= ~DIRTY_BIT;
++parentIter; ++parentIter;
++globalTransformIter; ++globalTransformIter;
++transformIter; ++transformIter;
} }
for (u32 &parentValue : m_Parents_)
{
parentValue &= ~DIRTY_BIT; // Unset dirty.
}
m_Dirty = false; m_Dirty = false;
} }
}; };