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:
parent
704821c41e
commit
a5180fbb28
5 changed files with 33 additions and 75 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue