mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
stuff
This commit is contained in:
parent
769c472ceb
commit
abc2e54c07
16 changed files with 137 additions and 224 deletions
|
@ -135,7 +135,7 @@ public:
|
|||
|
||||
//! animates the joints in the mesh based on the current frame.
|
||||
/** Also takes in to account transitions. */
|
||||
virtual void animateJoints(bool CalculateAbsolutePositions = true) = 0;
|
||||
virtual void animateJoints() = 0;
|
||||
|
||||
//! render mesh ignoring its transformation.
|
||||
/** Culling is unaffected. */
|
||||
|
|
|
@ -28,15 +28,9 @@ public:
|
|||
//! Returns the relative transformation of the scene node.
|
||||
// virtual core::matrix4 getRelativeTransformation() const = 0;
|
||||
|
||||
//! The animation method.
|
||||
void OnAnimate(u32 timeMs) override = 0;
|
||||
|
||||
//! The render method.
|
||||
/** Does nothing as bones are not visible. */
|
||||
void render() override {}
|
||||
|
||||
//! Updates the absolute position based on the relative and the parents position
|
||||
virtual void updateAbsolutePositionOfAllChildren() = 0;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -94,16 +94,12 @@ public:
|
|||
\param timeMs Current time in milliseconds. */
|
||||
virtual void OnAnimate(u32 timeMs)
|
||||
{
|
||||
if (IsVisible) {
|
||||
// update absolute position
|
||||
updateAbsolutePosition();
|
||||
if (!IsVisible && Children.empty())
|
||||
return;
|
||||
|
||||
// perform the post render process on all children
|
||||
|
||||
ISceneNodeList::iterator it = Children.begin();
|
||||
for (; it != Children.end(); ++it)
|
||||
(*it)->OnAnimate(timeMs);
|
||||
}
|
||||
updateAbsolutePosition();
|
||||
for (auto *child : Children)
|
||||
child->OnAnimate(timeMs);
|
||||
}
|
||||
|
||||
//! Renders the node.
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
#include "ISceneManager.h"
|
||||
#include "SMeshBuffer.h"
|
||||
#include "SSkinMeshBuffer.h"
|
||||
#include "irrMath.h"
|
||||
#include "matrix4.h"
|
||||
#include "quaternion.h"
|
||||
#include "vector3d.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -314,8 +317,56 @@ public:
|
|||
//! The name of this joint
|
||||
std::optional<std::string> Name;
|
||||
|
||||
//! Local matrix of this joint
|
||||
core::matrix4 LocalMatrix;
|
||||
struct Transform {
|
||||
core::vector3df translation;
|
||||
core::quaternion rotation;
|
||||
core::vector3df scale{1};
|
||||
|
||||
core::matrix4 buildMatrix() const {
|
||||
core::matrix4 T;
|
||||
T.setTranslation(translation);
|
||||
core::matrix4 R;
|
||||
rotation.getMatrix_transposed(R);
|
||||
core::matrix4 S;
|
||||
S.setScale(scale);
|
||||
return T * R * S;
|
||||
}
|
||||
};
|
||||
|
||||
//! Local transformation to be set by loaders. Mutated by animation.
|
||||
//! If a matrix is used, this joint **must not** be animated,
|
||||
//! because then the unique decomposition into translation, rotation and scale need not exist!
|
||||
std::variant<core::matrix4, Transform> transform = Transform{};
|
||||
|
||||
Transform &getAnimatableTransform() {
|
||||
if (std::holds_alternative<Transform>(transform))
|
||||
return std::get<Transform>(transform);
|
||||
const auto &mat = std::get<core::matrix4>(transform);
|
||||
Transform trs;
|
||||
trs.translation = mat.getTranslation();
|
||||
trs.scale = mat.getScale();
|
||||
trs.rotation = core::quaternion(
|
||||
mat.getRotationDegrees(trs.scale) * core::DEGTORAD);
|
||||
transform = trs;
|
||||
// TODO raise a warning if the recomposed matrix does not equal the decomposed.
|
||||
return std::get<Transform>(transform);
|
||||
}
|
||||
|
||||
void animate(f32 frame) {
|
||||
if (keys.empty())
|
||||
return;
|
||||
auto &transform = getAnimatableTransform();
|
||||
keys.updateTransform(frame,
|
||||
transform.translation,
|
||||
transform.rotation,
|
||||
transform.scale);
|
||||
}
|
||||
|
||||
core::matrix4 buildLocalMatrix() const {
|
||||
if (std::holds_alternative<core::matrix4>(transform))
|
||||
return std::get<core::matrix4>(transform);
|
||||
return std::get<Transform>(transform).buildMatrix();
|
||||
}
|
||||
|
||||
//! List of child joints
|
||||
std::vector<SJoint *> Children;
|
||||
|
@ -334,11 +385,6 @@ public:
|
|||
core::matrix4 GlobalAnimatedMatrix;
|
||||
core::matrix4 LocalAnimatedMatrix;
|
||||
|
||||
//! These should be set by loaders.
|
||||
core::vector3df Animatedposition;
|
||||
core::vector3df Animatedscale;
|
||||
core::quaternion Animatedrotation;
|
||||
|
||||
// The .x and .gltf formats pre-calculate this
|
||||
std::optional<core::matrix4> GlobalInversedMatrix;
|
||||
private:
|
||||
|
|
|
@ -170,7 +170,11 @@ IMesh *CAnimatedMeshSceneNode::getMeshForCurrentFrame()
|
|||
// Update the skinned mesh for the current joint transforms.
|
||||
skinnedMesh->skinMesh();
|
||||
|
||||
skinnedMesh->updateBoundingBox();
|
||||
skinnedMesh->updateBoundingBox();
|
||||
|
||||
Box = skinnedMesh->getBoundingBox();
|
||||
|
||||
setAutomaticCulling(EAC_OFF);
|
||||
|
||||
return skinnedMesh;
|
||||
}
|
||||
|
@ -187,6 +191,10 @@ void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
|
|||
buildFrameNr(timeMs - LastTimeMs);
|
||||
LastTimeMs = timeMs;
|
||||
|
||||
// This needs to be done on animate, which is called recursively *before*
|
||||
// anything is rendered so that the transformations of children are up to date
|
||||
animateJoints();
|
||||
|
||||
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
||||
}
|
||||
|
||||
|
@ -204,15 +212,8 @@ void CAnimatedMeshSceneNode::render()
|
|||
++PassCount;
|
||||
|
||||
scene::IMesh *m = getMeshForCurrentFrame();
|
||||
|
||||
if (m) {
|
||||
Box = m->getBoundingBox();
|
||||
} else {
|
||||
#ifdef _DEBUG
|
||||
os::Printer::log("Animated Mesh returned no mesh to render.", ELL_WARNING);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
_IRR_DEBUG_BREAK_IF(!m);
|
||||
Box = m->getBoundingBox(); // HACK
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
|
@ -237,6 +238,7 @@ void CAnimatedMeshSceneNode::render()
|
|||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
// for debug purposes only:
|
||||
// DebugDataVisible = ~0;
|
||||
if (DebugDataVisible && PassCount == 1) {
|
||||
video::SMaterial debug_mat;
|
||||
debug_mat.AntiAliasing = video::EAAM_OFF;
|
||||
|
@ -559,7 +561,7 @@ void CAnimatedMeshSceneNode::setRenderFromIdentity(bool enable)
|
|||
}
|
||||
|
||||
//! updates the joint positions of this mesh
|
||||
void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
|
||||
void CAnimatedMeshSceneNode::animateJoints()
|
||||
{
|
||||
if (Mesh && Mesh->getMeshType() == EAMT_SKINNED) {
|
||||
checkJoints();
|
||||
|
@ -614,15 +616,6 @@ void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
|
|||
// TransitingBlend));
|
||||
}
|
||||
}
|
||||
|
||||
if (CalculateAbsolutePositions) {
|
||||
//---slow---
|
||||
for (u32 n = 0; n < JointChildSceneNodes.size(); ++n) {
|
||||
if (JointChildSceneNodes[n]->getParent() == this) {
|
||||
JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); // temp, should be an option
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,12 +117,12 @@ public:
|
|||
//! updates the absolute position based on the relative and the parents position
|
||||
void updateAbsolutePosition() override;
|
||||
|
||||
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
|
||||
//! Sets the transition time in seconds (note: This needs to enable joints)
|
||||
//! you must call animateJoints(), or the mesh will not animate
|
||||
void setTransitionTime(f32 Time) override;
|
||||
|
||||
//! updates the joint positions of this mesh
|
||||
void animateJoints(bool CalculateAbsolutePositions = true) override;
|
||||
void animateJoints() override;
|
||||
|
||||
//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected)
|
||||
void setRenderFromIdentity(bool On) override;
|
||||
|
|
|
@ -143,31 +143,25 @@ bool CB3DMeshFileLoader::readChunkNODE(SkinnedMesh::SJoint *inJoint)
|
|||
os::Printer::log(logStr.c_str(), joint->Name.value_or("").c_str(), ELL_DEBUG);
|
||||
#endif
|
||||
|
||||
f32 position[3], scale[3], rotation[4];
|
||||
SkinnedMesh::SJoint::Transform transform;
|
||||
{
|
||||
f32 t[3], s[3], r[4];
|
||||
|
||||
readFloats(position, 3);
|
||||
readFloats(scale, 3);
|
||||
readFloats(rotation, 4);
|
||||
readFloats(t, 3);
|
||||
readFloats(s, 3);
|
||||
readFloats(r, 4);
|
||||
|
||||
joint->Animatedposition = core::vector3df(position[0], position[1], position[2]);
|
||||
joint->Animatedscale = core::vector3df(scale[0], scale[1], scale[2]);
|
||||
joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]);
|
||||
|
||||
// Build LocalMatrix:
|
||||
|
||||
core::matrix4 positionMatrix;
|
||||
positionMatrix.setTranslation(joint->Animatedposition);
|
||||
core::matrix4 scaleMatrix;
|
||||
scaleMatrix.setScale(joint->Animatedscale);
|
||||
core::matrix4 rotationMatrix;
|
||||
joint->Animatedrotation.getMatrix_transposed(rotationMatrix);
|
||||
|
||||
joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix;
|
||||
joint->transform = transform = {
|
||||
{t[0], t[1], t[2]},
|
||||
{r[1], r[2], r[3], r[0]},
|
||||
{s[0], s[1], s[2]},
|
||||
};
|
||||
}
|
||||
|
||||
if (inJoint)
|
||||
joint->GlobalMatrix = inJoint->GlobalMatrix * joint->LocalMatrix;
|
||||
joint->GlobalMatrix = inJoint->GlobalMatrix * joint->buildLocalMatrix();
|
||||
else
|
||||
joint->GlobalMatrix = joint->LocalMatrix;
|
||||
joint->GlobalMatrix = joint->buildLocalMatrix();
|
||||
|
||||
while (B3dStack.getLast().startposition + B3dStack.getLast().length > B3DFile->getPos()) // this chunk repeats
|
||||
{
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#include "CBoneSceneNode.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
void CBoneSceneNode::OnAnimate(u32 timeMs)
|
||||
{
|
||||
if (IsVisible) {
|
||||
// update absolute position
|
||||
// updateAbsolutePosition();
|
||||
|
||||
// perform the post render process on all children
|
||||
ISceneNodeList::iterator it = Children.begin();
|
||||
for (; it != Children.end(); ++it)
|
||||
(*it)->OnAnimate(timeMs);
|
||||
}
|
||||
}
|
||||
|
||||
void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node)
|
||||
{
|
||||
Node->updateAbsolutePosition();
|
||||
|
||||
ISceneNodeList::const_iterator it = Node->getChildren().begin();
|
||||
for (; it != Node->getChildren().end(); ++it) {
|
||||
helper_updateAbsolutePositionOfAllChildren((*it));
|
||||
}
|
||||
}
|
||||
|
||||
void CBoneSceneNode::updateAbsolutePositionOfAllChildren()
|
||||
{
|
||||
helper_updateAbsolutePositionOfAllChildren(this);
|
||||
}
|
||||
|
||||
} // namespace scene
|
||||
} // namespace irr
|
|
@ -40,13 +40,6 @@ public:
|
|||
return Box;
|
||||
}
|
||||
|
||||
void OnAnimate(u32 timeMs) override;
|
||||
|
||||
void updateAbsolutePositionOfAllChildren() override;
|
||||
|
||||
private:
|
||||
void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node);
|
||||
|
||||
const u32 BoneIndex;
|
||||
|
||||
// Bogus box; bone scene nodes are not rendered anyways.
|
||||
|
|
|
@ -539,34 +539,25 @@ static core::matrix4 loadTransform(const tiniergltf::Node::Matrix &m, SkinnedMes
|
|||
mat[i] = static_cast<f32>(m[i]);
|
||||
mat = convertHandedness(mat);
|
||||
|
||||
// Decompose the matrix into translation, scale, and rotation.
|
||||
joint->Animatedposition = mat.getTranslation();
|
||||
|
||||
auto scale = mat.getScale();
|
||||
joint->Animatedscale = scale;
|
||||
joint->Animatedrotation = mat.getRotationRadians(scale);
|
||||
// Invert the rotation because it is applied using `getMatrix_transposed`,
|
||||
// which again inverts.
|
||||
joint->Animatedrotation.makeInverse();
|
||||
|
||||
// Note: "When a node is targeted for animation [...],
|
||||
// only TRS properties MAY be present; matrix MUST NOT be present."
|
||||
// Thus we MUST NOT do any decomposition, which in general need not exist.
|
||||
joint->transform = mat;
|
||||
return mat;
|
||||
}
|
||||
|
||||
static core::matrix4 loadTransform(const tiniergltf::Node::TRS &trs, SkinnedMesh::SJoint *joint)
|
||||
{
|
||||
const auto &trans = trs.translation;
|
||||
const auto &rot = trs.rotation;
|
||||
const auto &scale = trs.scale;
|
||||
core::matrix4 transMat;
|
||||
joint->Animatedposition = convertHandedness(core::vector3df(trans[0], trans[1], trans[2]));
|
||||
transMat.setTranslation(joint->Animatedposition);
|
||||
core::matrix4 rotMat;
|
||||
joint->Animatedrotation = convertHandedness(core::quaternion(rot[0], rot[1], rot[2], rot[3]));
|
||||
core::quaternion(joint->Animatedrotation).getMatrix_transposed(rotMat);
|
||||
joint->Animatedscale = core::vector3df(scale[0], scale[1], scale[2]);
|
||||
core::matrix4 scaleMat;
|
||||
scaleMat.setScale(joint->Animatedscale);
|
||||
return transMat * rotMat * scaleMat;
|
||||
const auto &t = trs.translation;
|
||||
const auto &r = trs.rotation;
|
||||
const auto &s = trs.scale;
|
||||
SkinnedMesh::SJoint::Transform transform{
|
||||
convertHandedness(core::vector3df(t[0], t[1], t[2])),
|
||||
convertHandedness(core::quaternion(r[0], r[1], r[2], r[3])),
|
||||
core::vector3df(s[0], s[1], s[2]),
|
||||
};
|
||||
joint->transform = transform;
|
||||
return transform.buildMatrix();
|
||||
}
|
||||
|
||||
static core::matrix4 loadTransform(std::optional<std::variant<tiniergltf::Node::Matrix, tiniergltf::Node::TRS>> transform,
|
||||
|
@ -584,8 +575,7 @@ void SelfType::MeshExtractor::loadNode(
|
|||
const auto &node = m_gltf_model.nodes->at(nodeIdx);
|
||||
auto *joint = m_irr_model->addJoint(parent);
|
||||
const core::matrix4 transform = loadTransform(node.transform, joint);
|
||||
joint->LocalMatrix = transform;
|
||||
joint->GlobalMatrix = parent ? parent->GlobalMatrix * joint->LocalMatrix : joint->LocalMatrix;
|
||||
joint->GlobalMatrix = parent ? parent->GlobalMatrix * transform : transform;
|
||||
if (node.name.has_value()) {
|
||||
joint->Name = node.name->c_str();
|
||||
}
|
||||
|
|
|
@ -320,7 +320,6 @@ set(IRRMESHLOADER
|
|||
|
||||
add_library(IRRMESHOBJ OBJECT
|
||||
SkinnedMesh.cpp
|
||||
CBoneSceneNode.cpp
|
||||
CMeshSceneNode.cpp
|
||||
CAnimatedMeshSceneNode.cpp
|
||||
${IRRMESHLOADER}
|
||||
|
|
|
@ -552,12 +552,9 @@ bool CXMeshFileLoader::parseDataObjectFrame(SkinnedMesh::SJoint *Parent)
|
|||
if (!parseDataObjectFrame(joint))
|
||||
return false;
|
||||
} else if (objectName == "FrameTransformMatrix") {
|
||||
if (!parseDataObjectTransformationMatrix(joint->LocalMatrix))
|
||||
joint->transform = core::matrix4();
|
||||
if (!parseDataObjectTransformationMatrix(std::get<core::matrix4>(joint->transform)))
|
||||
return false;
|
||||
|
||||
// joint->LocalAnimatedMatrix
|
||||
// joint->LocalAnimatedMatrix.makeInverse();
|
||||
// joint->LocalMatrix=tmp*joint->LocalAnimatedMatrix;
|
||||
} else if (objectName == "Mesh") {
|
||||
/*
|
||||
frame.Meshes.push_back(SXMesh());
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
#include "CBoneSceneNode.h"
|
||||
#include "IAnimatedMeshSceneNode.h"
|
||||
#include "SSkinMeshBuffer.h"
|
||||
#include "irrMath.h"
|
||||
#include "matrix4.h"
|
||||
#include "os.h"
|
||||
#include "vector3d.h"
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
|
@ -73,13 +77,8 @@ void SkinnedMesh::animateMesh(f32 frame)
|
|||
LastAnimatedFrame = frame;
|
||||
SkinnedLastFrame = false;
|
||||
|
||||
for (auto *joint : AllJoints) {
|
||||
// The joints can be animated here with no input from their parents
|
||||
joint->keys.updateTransform(frame,
|
||||
joint->Animatedposition,
|
||||
joint->Animatedrotation,
|
||||
joint->Animatedscale);
|
||||
}
|
||||
for (auto *joint : AllJoints)
|
||||
joint->animate(frame);
|
||||
|
||||
// Note:
|
||||
// LocalAnimatedMatrix needs to be built at some point, but this function may be called lots of times for
|
||||
|
@ -98,56 +97,7 @@ void SkinnedMesh::buildAllLocalAnimatedMatrices()
|
|||
{
|
||||
for (auto *joint : AllJoints) {
|
||||
// Could be faster:
|
||||
|
||||
if (!joint->keys.empty()) {
|
||||
// IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility.
|
||||
// Not tested so far if this was correct or wrong before quaternion fix!
|
||||
// Note that using getMatrix_transposed inverts the rotation.
|
||||
joint->Animatedrotation.getMatrix_transposed(joint->LocalAnimatedMatrix);
|
||||
|
||||
// --- joint->LocalAnimatedMatrix *= joint->Animatedrotation.getMatrix() ---
|
||||
f32 *m1 = joint->LocalAnimatedMatrix.pointer();
|
||||
core::vector3df &Pos = joint->Animatedposition;
|
||||
m1[0] += Pos.X * m1[3];
|
||||
m1[1] += Pos.Y * m1[3];
|
||||
m1[2] += Pos.Z * m1[3];
|
||||
m1[4] += Pos.X * m1[7];
|
||||
m1[5] += Pos.Y * m1[7];
|
||||
m1[6] += Pos.Z * m1[7];
|
||||
m1[8] += Pos.X * m1[11];
|
||||
m1[9] += Pos.Y * m1[11];
|
||||
m1[10] += Pos.Z * m1[11];
|
||||
m1[12] += Pos.X * m1[15];
|
||||
m1[13] += Pos.Y * m1[15];
|
||||
m1[14] += Pos.Z * m1[15];
|
||||
// -----------------------------------
|
||||
|
||||
if (!joint->keys.scale.empty()) {
|
||||
/*
|
||||
core::matrix4 scaleMatrix;
|
||||
scaleMatrix.setScale(joint->Animatedscale);
|
||||
joint->LocalAnimatedMatrix *= scaleMatrix;
|
||||
*/
|
||||
|
||||
// -------- joint->LocalAnimatedMatrix *= scaleMatrix -----------------
|
||||
core::matrix4 &mat = joint->LocalAnimatedMatrix;
|
||||
mat[0] *= joint->Animatedscale.X;
|
||||
mat[1] *= joint->Animatedscale.X;
|
||||
mat[2] *= joint->Animatedscale.X;
|
||||
mat[3] *= joint->Animatedscale.X;
|
||||
mat[4] *= joint->Animatedscale.Y;
|
||||
mat[5] *= joint->Animatedscale.Y;
|
||||
mat[6] *= joint->Animatedscale.Y;
|
||||
mat[7] *= joint->Animatedscale.Y;
|
||||
mat[8] *= joint->Animatedscale.Z;
|
||||
mat[9] *= joint->Animatedscale.Z;
|
||||
mat[10] *= joint->Animatedscale.Z;
|
||||
mat[11] *= joint->Animatedscale.Z;
|
||||
// -----------------------------------
|
||||
}
|
||||
} else {
|
||||
joint->LocalAnimatedMatrix = joint->LocalMatrix;
|
||||
}
|
||||
joint->LocalAnimatedMatrix = joint->buildLocalMatrix();
|
||||
}
|
||||
SkinnedLastFrame = false;
|
||||
}
|
||||
|
@ -396,12 +346,13 @@ void SkinnedMesh::calculateGlobalMatrices(SJoint *joint, SJoint *parentJoint)
|
|||
return;
|
||||
}
|
||||
|
||||
const auto local_matrix = joint->buildLocalMatrix();
|
||||
if (!parentJoint)
|
||||
joint->GlobalMatrix = joint->LocalMatrix;
|
||||
joint->GlobalMatrix = local_matrix;
|
||||
else
|
||||
joint->GlobalMatrix = parentJoint->GlobalMatrix * joint->LocalMatrix;
|
||||
joint->GlobalMatrix = parentJoint->GlobalMatrix * local_matrix;
|
||||
|
||||
joint->LocalAnimatedMatrix = joint->LocalMatrix;
|
||||
joint->LocalAnimatedMatrix = local_matrix;
|
||||
joint->GlobalAnimatedMatrix = joint->GlobalMatrix;
|
||||
|
||||
if (!joint->GlobalInversedMatrix.has_value()) { // might be pre calculated
|
||||
|
@ -689,7 +640,7 @@ void SkinnedMesh::recoverJointsFromMesh(std::vector<IBoneSceneNode *> &jointChil
|
|||
node->setRotation(joint->LocalAnimatedMatrix.getRotationDegrees());
|
||||
node->setScale(joint->LocalAnimatedMatrix.getScale());
|
||||
|
||||
node->updateAbsolutePosition();
|
||||
node->updateAbsolutePosition(); // WTF
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -916,12 +916,7 @@ struct Node {
|
|||
std::optional<std::size_t> skin;
|
||||
std::optional<std::vector<double>> weights;
|
||||
Node(const Json::Value &o)
|
||||
: transform(Matrix {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
})
|
||||
: transform(TRS{})
|
||||
{
|
||||
check(o.isObject());
|
||||
if (o.isMember("camera")) {
|
||||
|
|
|
@ -1401,6 +1401,8 @@ void GenericCAO::updateBones(f32 dtime)
|
|||
if (m_bone_override.empty())
|
||||
return;
|
||||
|
||||
// FIXME these need to be applied at a different point in time
|
||||
// in order to be relative to the animated bone positions of the current frame
|
||||
for (auto &it : m_bone_override) {
|
||||
std::string bone_name = it.first;
|
||||
scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
|
||||
|
|
|
@ -413,17 +413,23 @@ SECTION("simple skin")
|
|||
|
||||
SECTION("transformations are correct")
|
||||
{
|
||||
CHECK(parent->Animatedposition == v3f(0, 0, 0));
|
||||
CHECK(parent->Animatedrotation == irr::core::quaternion());
|
||||
CHECK(parent->Animatedscale == v3f(1, 1, 1));
|
||||
CHECK(parent->GlobalInversedMatrix == irr::core::matrix4());
|
||||
const v3f childTranslation(0, 1, 0);
|
||||
CHECK(child->Animatedposition == childTranslation);
|
||||
CHECK(child->Animatedrotation == irr::core::quaternion());
|
||||
CHECK(child->Animatedscale == v3f(1, 1, 1));
|
||||
irr::core::matrix4 inverseBindMatrix;
|
||||
inverseBindMatrix.setTranslation(-childTranslation);
|
||||
CHECK(child->GlobalInversedMatrix == inverseBindMatrix);
|
||||
{
|
||||
const auto &transform = std::get<SkinnedMesh::SJoint::Transform>(parent->transform);
|
||||
CHECK(transform.translation == v3f(0, 0, 0));
|
||||
CHECK(transform.rotation == irr::core::quaternion());
|
||||
CHECK(transform.scale == v3f(1, 1, 1));
|
||||
CHECK(parent->GlobalInversedMatrix == irr::core::matrix4());
|
||||
}
|
||||
{
|
||||
const auto &transform = std::get<SkinnedMesh::SJoint::Transform>(child->transform);
|
||||
const v3f translation(0, 1, 0);
|
||||
CHECK(transform.translation == translation);
|
||||
CHECK(transform.rotation == irr::core::quaternion());
|
||||
CHECK(transform.scale == v3f(1, 1, 1));
|
||||
irr::core::matrix4 inverseBindMatrix;
|
||||
inverseBindMatrix.setTranslation(-translation);
|
||||
CHECK(child->GlobalInversedMatrix == inverseBindMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("weights are correct")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue