1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

do it properly

This commit is contained in:
Lars Mueller 2025-01-26 01:37:39 +01:00
parent 704821c41e
commit a5180fbb28
5 changed files with 33 additions and 75 deletions

View file

@ -319,8 +319,10 @@ public:
return transform;
if (std::holds_alternative<core::matrix4>(transform)) {
// TODO raise a warning: Attempt to animate a static joint.
return transform;
// .x lets animations override matrix transforms entirely.
core::Transform trs;
keys.updateTransform(frame, trs);
return {trs};
}
auto trs = std::get<core::Transform>(transform);

View file

@ -6,7 +6,6 @@
#include "CBoneSceneNode.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "MatrixBoneSceneNode.h"
#include "S3DVertex.h"
#include "Transform.h"
#include "matrix4.h"
@ -22,6 +21,7 @@
#include "quaternion.h"
#include <algorithm>
#include <cstddef>
#include <optional>
namespace irr
{
@ -546,14 +546,11 @@ void CAnimatedMeshSceneNode::addJoints()
if (joint->ParentJointID)
parent = JointChildSceneNodes.at(*joint->ParentJointID); // exists because of topo. order
assert(parent);
if (const auto *matrix = std::get_if<core::matrix4>(&joint->transform)) {
JointChildSceneNodes.push_back(new MatrixBoneSceneNode(
parent, SceneManager, 0, i, joint->Name, *matrix));
} else {
JointChildSceneNodes.push_back(new CBoneSceneNode(
parent, SceneManager, 0, i, joint->Name,
std::get<core::Transform>(joint->transform)));
}
const auto *matrix = std::get_if<core::matrix4>(&joint->transform);
JointChildSceneNodes.push_back(new CBoneSceneNode(
parent, SceneManager, 0, i, joint->Name,
matrix ? core::Transform{} : std::get<core::Transform>(joint->transform),
matrix ? *matrix : std::optional<core::matrix4>{}));
}
}
@ -562,11 +559,13 @@ void CAnimatedMeshSceneNode::updateJointSceneNodes(
{
for (size_t i = 0; i < transforms.size(); ++i) {
const auto &transform = transforms[i];
IBoneSceneNode *node = JointChildSceneNodes[i];
auto *node = static_cast<CBoneSceneNode*>(JointChildSceneNodes[i]);
if (const auto *trs = std::get_if<core::Transform>(&transform)) {
dynamic_cast<CBoneSceneNode*>(node)->setTransform(*trs);
node->setTransform(*trs);
// .x lets animations override matrix transforms entirely.
node->Matrix = std::nullopt;
} else {
assert(dynamic_cast<MatrixBoneSceneNode*>(node));
node->Matrix = std::get<core::matrix4>(transform);
}
}
}

View file

@ -8,6 +8,7 @@
#include "IBoneSceneNode.h"
#include "Transform.h"
#include "matrix4.h"
#include <optional>
@ -23,8 +24,10 @@ public:
CBoneSceneNode(ISceneNode *parent, ISceneManager *mgr,
s32 id = -1, u32 boneIndex = 0,
const std::optional<std::string> &boneName = std::nullopt,
const core::Transform &transform = {}) :
IBoneSceneNode(parent, mgr, id, boneIndex, boneName)
const core::Transform &transform = {},
const std::optional<core::matrix4> &matrix = std::nullopt) :
IBoneSceneNode(parent, mgr, id, boneIndex, boneName),
Matrix(matrix)
{
setTransform(transform);
}
@ -42,6 +45,17 @@ public:
}
setScale(transform.scale);
}
core::matrix4 getRelativeTransformation() const override
{
if (Matrix)
return *Matrix;
return IBoneSceneNode::getRelativeTransformation();
}
//! Some file formats alternatively let bones specify a transformation matrix.
//! If this is set, it overrides the TRS properties.
std::optional<core::matrix4> Matrix;
};
} // end namespace scene

View file

@ -1,56 +0,0 @@
// Copyright (C) 2025 Joe Mama
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
#include "IBoneSceneNode.h"
#include "matrix4.h"
#include "vector3d.h"
#include <iostream>
#include <optional>
// We must represent some transforms differently:
// Bones can have static non-TRS matrix transforms,
// for example shearing (can not be decomposed at all)
// or negatively scaling an axis (can not be decomposed uniquely).
// Hence well-defined animation is not possible for such nodes
// (and in fact glTF even guarantees that they will never be animated).
namespace irr
{
namespace scene
{
class MatrixBoneSceneNode : public IBoneSceneNode
{
public:
//! constructor
MatrixBoneSceneNode(ISceneNode *parent, ISceneManager *mgr,
s32 id = -1, u32 boneIndex = 0,
const std::optional<std::string> &boneName = std::nullopt,
const core::matrix4 &matrix = core::IdentityMatrix) :
IBoneSceneNode(parent, mgr, id, boneIndex, boneName),
matrix(matrix)
{}
const core::matrix4 matrix;
// Matrix nodes should not be fake decomposed.
const core::vector3df &getPosition() const override { assert(false); }
const core::vector3df &getRotation() const override { assert(false); }
const core::vector3df &getScale() const override { assert(false); }
// This node should be static.
void setPosition(const core::vector3df &pos) override { assert(false); }
void setRotation(const core::vector3df &euler_deg) override { assert(false); }
void setScale(const core::vector3df &scale) override { assert(false); }
core::matrix4 getRelativeTransformation() const override
{
return matrix;
}
};
} // end namespace scene
} // end namespace irr

View file

@ -6,7 +6,6 @@
#include "IBoneSceneNode.h"
#include "CBoneSceneNode.h"
#include "IAnimatedMeshSceneNode.h"
#include "MatrixBoneSceneNode.h"
#include "SSkinMeshBuffer.h"
#include "Transform.h"
#include "aabbox3d.h"