mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Fix animation blending
This commit is contained in:
parent
a5180fbb28
commit
c7c99296cb
6 changed files with 42 additions and 53 deletions
|
@ -231,7 +231,7 @@ public:
|
|||
|
||||
static core::quaternion interpolateValue(core::quaternion from, core::quaternion to, f32 time) {
|
||||
core::quaternion result;
|
||||
result.slerp(from, to, time, 0.001f);
|
||||
result.slerp(from, to, time);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "irrMath.h"
|
||||
#include <matrix4.h>
|
||||
#include <variant>
|
||||
#include <vector3d.h>
|
||||
#include <quaternion.h>
|
||||
|
||||
|
@ -27,12 +26,23 @@ struct Transform {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
Transform interpolate(Transform to, f32 time) const
|
||||
{
|
||||
core::quaternion interpolated_rotation;
|
||||
interpolated_rotation.slerp(rotation, to.rotation, time);
|
||||
return {
|
||||
to.translation.getInterpolated(translation, time),
|
||||
interpolated_rotation,
|
||||
to.scale.getInterpolated(scale, time),
|
||||
};
|
||||
}
|
||||
|
||||
matrix4 buildMatrix() const
|
||||
{
|
||||
matrix4 T;
|
||||
T.setTranslation(translation);
|
||||
matrix4 R;
|
||||
// TODO this is sussy. probably shouldn't be doing this.
|
||||
rotation.getMatrix_transposed(R);
|
||||
matrix4 S;
|
||||
S.setScale(scale);
|
||||
|
@ -41,4 +51,4 @@ struct Transform {
|
|||
};
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
} // end namespace irr
|
||||
|
|
|
@ -180,7 +180,7 @@ public:
|
|||
linear interpolation.
|
||||
*/
|
||||
quaternion &slerp(quaternion q1, quaternion q2,
|
||||
f32 time, f32 threshold = .05f);
|
||||
f32 time, f32 threshold = .001f);
|
||||
|
||||
//! Set this quaternion to represent a rotation from angle and axis.
|
||||
/** Axis must be unit length.
|
||||
|
|
|
@ -540,6 +540,8 @@ void CAnimatedMeshSceneNode::addJoints()
|
|||
const auto &joints = static_cast<SkinnedMesh*>(Mesh)->getAllJoints();
|
||||
JointChildSceneNodes.clear();
|
||||
JointChildSceneNodes.reserve(joints.size());
|
||||
PretransitingSave.clear();
|
||||
PretransitingSave.resize(JointChildSceneNodes.size());
|
||||
for (size_t i = 0; i < joints.size(); ++i) {
|
||||
const auto *joint = joints[i];
|
||||
ISceneNode *parent = this;
|
||||
|
@ -587,43 +589,11 @@ void CAnimatedMeshSceneNode::animateJoints()
|
|||
//-----------------------------------------
|
||||
|
||||
if (Transiting != 0.f) {
|
||||
// Init additional matrices
|
||||
if (PretransitingSave.size() < JointChildSceneNodes.size()) {
|
||||
for (u32 n = PretransitingSave.size(); n < JointChildSceneNodes.size(); ++n)
|
||||
PretransitingSave.push_back(core::matrix4());
|
||||
}
|
||||
|
||||
for (u32 n = 0; n < JointChildSceneNodes.size(); ++n) {
|
||||
//------Position------
|
||||
|
||||
JointChildSceneNodes[n]->setPosition(
|
||||
core::lerp(
|
||||
PretransitingSave[n].getTranslation(),
|
||||
JointChildSceneNodes[n]->getPosition(),
|
||||
TransitingBlend));
|
||||
|
||||
//------Rotation------
|
||||
|
||||
// Code is slow, needs to be fixed up
|
||||
|
||||
const core::quaternion RotationStart(PretransitingSave[n].getRotationDegrees() * core::DEGTORAD);
|
||||
const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation() * core::DEGTORAD);
|
||||
|
||||
core::quaternion QRotation;
|
||||
QRotation.slerp(RotationStart, RotationEnd, TransitingBlend);
|
||||
|
||||
core::vector3df tmpVector;
|
||||
QRotation.toEuler(tmpVector);
|
||||
tmpVector *= core::RADTODEG; // convert from radians back to degrees
|
||||
JointChildSceneNodes[n]->setRotation(tmpVector);
|
||||
|
||||
//------Scale------
|
||||
|
||||
// JointChildSceneNodes[n]->setScale(
|
||||
// core::lerp(
|
||||
// PretransitingSave[n].getScale(),
|
||||
// JointChildSceneNodes[n]->getScale(),
|
||||
// TransitingBlend));
|
||||
for (u32 i = 0; i < JointChildSceneNodes.size(); ++i) {
|
||||
if (PretransitingSave[i]) {
|
||||
JointChildSceneNodes[i]->setTransform(PretransitingSave[i]->interpolate(
|
||||
JointChildSceneNodes[i]->getTransform(), TransitingBlend));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -648,16 +618,15 @@ void CAnimatedMeshSceneNode::beginTransition()
|
|||
return;
|
||||
|
||||
if (TransitionTime != 0) {
|
||||
// Check the array is big enough
|
||||
if (PretransitingSave.size() < JointChildSceneNodes.size()) {
|
||||
for (u32 n = PretransitingSave.size(); n < JointChildSceneNodes.size(); ++n)
|
||||
PretransitingSave.push_back(core::matrix4());
|
||||
// Copy the transforms of animated joints
|
||||
for (u32 i = 0; i < JointChildSceneNodes.size(); ++i) {
|
||||
if (!JointChildSceneNodes[i]->Matrix) {
|
||||
PretransitingSave[i] = JointChildSceneNodes[i]->getTransform();
|
||||
} else {
|
||||
PretransitingSave[i] = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the position of joints
|
||||
for (u32 n = 0; n < JointChildSceneNodes.size(); ++n)
|
||||
PretransitingSave[n] = JointChildSceneNodes[n]->getRelativeTransformation();
|
||||
|
||||
Transiting = core::reciprocal((f32)TransitionTime);
|
||||
}
|
||||
TransitingBlend = 0.f;
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "CBoneSceneNode.h"
|
||||
#include "IAnimatedMeshSceneNode.h"
|
||||
#include "IAnimatedMesh.h"
|
||||
|
||||
#include "SkinnedMesh.h"
|
||||
#include "matrix4.h"
|
||||
#include "Transform.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -171,8 +172,8 @@ private:
|
|||
s32 PassCount;
|
||||
std::function<void(f32)> OnAnimateCallback;
|
||||
|
||||
std::vector<IBoneSceneNode *> JointChildSceneNodes;
|
||||
core::array<core::matrix4> PretransitingSave;
|
||||
std::vector<CBoneSceneNode *> JointChildSceneNodes;
|
||||
std::vector<std::optional<core::Transform>> PretransitingSave;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -46,6 +46,15 @@ public:
|
|||
setScale(transform.scale);
|
||||
}
|
||||
|
||||
core::Transform getTransform() const
|
||||
{
|
||||
return {
|
||||
getPosition(),
|
||||
core::quaternion(getRotation() * core::DEGTORAD).makeInverse(),
|
||||
getScale()
|
||||
};
|
||||
}
|
||||
|
||||
core::matrix4 getRelativeTransformation() const override
|
||||
{
|
||||
if (Matrix)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue