mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
fixes
This commit is contained in:
parent
8c00f403f1
commit
4dacb66693
3 changed files with 20 additions and 14 deletions
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
//! Turns the given array of local matrices into an array of global matrices
|
||||
//! by multiplying with respective parent matrices.
|
||||
void calculateGlobalMatrices(std::vector<core::matrix4> &matrices);
|
||||
void calculateGlobalMatrices(std::vector<core::matrix4> &matrices) const;
|
||||
|
||||
//! Performs a software skin on this mesh based on the given joint matrices
|
||||
void skinMesh(const std::vector<core::matrix4> &animated_transforms);
|
||||
|
|
|
@ -514,6 +514,8 @@ bool CXMeshFileLoader::parseDataObjectFrame(SkinnedMesh::SJoint *Parent)
|
|||
if (n.has_value()) {
|
||||
JointID = *n;
|
||||
joint = AnimatedMesh->getAllJoints()[JointID];
|
||||
if (Parent)
|
||||
joint->ParentJointID = Parent->JointID;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ void SkinnedMesh::resetAnimation()
|
|||
|
||||
//! Turns the given array of local matrices into an array of global matrices
|
||||
//! by multiplying with respective parent matrices.
|
||||
void SkinnedMesh::calculateGlobalMatrices(std::vector<core::matrix4> &matrices)
|
||||
void SkinnedMesh::calculateGlobalMatrices(std::vector<core::matrix4> &matrices) const
|
||||
{
|
||||
// Note that the joints are topologically sorted.
|
||||
for (u16 i = 0; i < AllJoints.size(); ++i) {
|
||||
|
@ -409,40 +409,45 @@ void SkinnedMesh::recalculateBaseBoundingBoxes() {
|
|||
calculateBufferBoundingBoxes();
|
||||
}
|
||||
|
||||
// TODO this can be removed: Our API guarantees topo sorting if we prevent mutation
|
||||
void SkinnedMesh::topoSortJoints()
|
||||
{
|
||||
size_t n = AllJoints.size();
|
||||
|
||||
std::vector<u16> permutation; // new id -> old id
|
||||
std::vector<u16> new_to_old_id; // new id -> old id
|
||||
|
||||
std::vector<std::vector<u16>> children(AllJoints.size());
|
||||
std::vector<std::vector<u16>> children(n);
|
||||
for (u16 i = 0; i < n; ++i) {
|
||||
if (auto parentId = AllJoints[i]->ParentJointID)
|
||||
children[*parentId].push_back(i);
|
||||
else
|
||||
permutation.push_back(i);
|
||||
new_to_old_id.push_back(i);
|
||||
}
|
||||
|
||||
// Levelorder
|
||||
for (u16 i = 0; i < n; ++i) {
|
||||
permutation.insert(permutation.end(),
|
||||
children[i].begin(), children[i].end());
|
||||
new_to_old_id.insert(new_to_old_id.end(),
|
||||
children[new_to_old_id[i]].begin(),
|
||||
children[new_to_old_id[i]].end());
|
||||
}
|
||||
|
||||
// old id -> new id
|
||||
std::vector<u16> inverse_permutation(n);
|
||||
std::vector<u16> old_to_new_id(n);
|
||||
for (u16 i = 0; i < n; ++i)
|
||||
inverse_permutation[permutation[i]] = i;
|
||||
old_to_new_id[new_to_old_id[i]] = i;
|
||||
|
||||
std::vector<SJoint *> joints(n);
|
||||
for (u16 i = 0; i < n; ++i) {
|
||||
joints[i] = AllJoints[permutation[i]];
|
||||
joints[i] = AllJoints[new_to_old_id[i]];
|
||||
joints[i]->JointID = i;
|
||||
if (auto parentId = joints[i]->ParentJointID)
|
||||
joints[i]->ParentJointID = inverse_permutation[*parentId];
|
||||
joints[i]->ParentJointID = old_to_new_id[*parentId];
|
||||
}
|
||||
AllJoints = std::move(joints);
|
||||
|
||||
for (u16 i = 0; i < n; ++i) {
|
||||
if (auto pjid = AllJoints[i]->ParentJointID)
|
||||
assert(*pjid < i);
|
||||
}
|
||||
AllJoints = joints;
|
||||
}
|
||||
|
||||
//! called by loader after populating with mesh and bone data
|
||||
|
@ -469,7 +474,6 @@ SkinnedMesh *SkinnedMeshBuilder::finalize()
|
|||
}
|
||||
calculateGlobalMatrices(matrices);
|
||||
|
||||
|
||||
for (size_t i = 0; i < AllJoints.size(); ++i) {
|
||||
auto *joint = AllJoints[i];
|
||||
if (!joint->GlobalInversedMatrix) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue