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; return transform;
if (std::holds_alternative<core::matrix4>(transform)) { if (std::holds_alternative<core::matrix4>(transform)) {
// TODO raise a warning: Attempt to animate a static joint. // .x lets animations override matrix transforms entirely.
return transform; core::Transform trs;
keys.updateTransform(frame, trs);
return {trs};
} }
auto trs = std::get<core::Transform>(transform); auto trs = std::get<core::Transform>(transform);
@ -346,7 +348,7 @@ public:
// The .x and .gltf formats pre-calculate this // The .x and .gltf formats pre-calculate this
std::optional<core::matrix4> GlobalInversedMatrix; std::optional<core::matrix4> GlobalInversedMatrix;
// TODO friends? // TODO friends?
u16 JointID; // TODO refactor away: pointers -> IDs u16 JointID; // TODO refactor away: pointers -> IDs
std::optional<u16> ParentJointID; std::optional<u16> ParentJointID;
@ -357,7 +359,7 @@ public:
core::aabbox3df calculateBoundingBox( core::aabbox3df calculateBoundingBox(
const std::vector<core::matrix4> &global_transforms); const std::vector<core::matrix4> &global_transforms);
void recalculateBaseBoundingBoxes(); void recalculateBaseBoundingBoxes();
const std::vector<SJoint *> &getAllJoints() const { const std::vector<SJoint *> &getAllJoints() const {

View file

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

View file

@ -8,6 +8,7 @@
#include "IBoneSceneNode.h" #include "IBoneSceneNode.h"
#include "Transform.h" #include "Transform.h"
#include "matrix4.h"
#include <optional> #include <optional>
@ -23,8 +24,10 @@ public:
CBoneSceneNode(ISceneNode *parent, ISceneManager *mgr, CBoneSceneNode(ISceneNode *parent, ISceneManager *mgr,
s32 id = -1, u32 boneIndex = 0, s32 id = -1, u32 boneIndex = 0,
const std::optional<std::string> &boneName = std::nullopt, const std::optional<std::string> &boneName = std::nullopt,
const core::Transform &transform = {}) : const core::Transform &transform = {},
IBoneSceneNode(parent, mgr, id, boneIndex, boneName) const std::optional<core::matrix4> &matrix = std::nullopt) :
IBoneSceneNode(parent, mgr, id, boneIndex, boneName),
Matrix(matrix)
{ {
setTransform(transform); setTransform(transform);
} }
@ -42,6 +45,17 @@ public:
} }
setScale(transform.scale); 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 } // 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 "IBoneSceneNode.h"
#include "CBoneSceneNode.h" #include "CBoneSceneNode.h"
#include "IAnimatedMeshSceneNode.h" #include "IAnimatedMeshSceneNode.h"
#include "MatrixBoneSceneNode.h"
#include "SSkinMeshBuffer.h" #include "SSkinMeshBuffer.h"
#include "Transform.h" #include "Transform.h"
#include "aabbox3d.h" #include "aabbox3d.h"