1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00
This commit is contained in:
Lars Mueller 2025-01-14 18:04:15 +01:00
parent d17f22f536
commit 769c472ceb
9 changed files with 28 additions and 203 deletions

View file

@ -12,18 +12,6 @@ namespace irr
{
namespace scene
{
enum E_JOINT_UPDATE_ON_RENDER
{
//! do nothing
EJUOR_NONE = 0,
//! get joints positions from the mesh (for attached nodes, etc)
EJUOR_READ,
//! control joint positions in the mesh (eg. ragdolls, or set the animation from animateJoints() )
EJUOR_CONTROL
};
class IAnimatedMeshSceneNode;
//! Callback interface for catching events of ended animations.
@ -141,13 +129,8 @@ public:
//! Returns the current mesh
virtual IAnimatedMesh *getMesh(void) = 0;
//! Set how the joints should be updated on render
virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) = 0;
//! Sets the transition time in seconds
/** Note: This needs to enable joints, and setJointmode set to
EJUOR_CONTROL. You must call animateJoints(), or the mesh will
not animate. */
/** Note: You must call animateJoints(), or the mesh will not animate. */
virtual void setTransitionTime(f32 Time) = 0;
//! animates the joints in the mesh based on the current frame.

View file

@ -11,60 +11,17 @@ namespace irr
namespace scene
{
//! Enumeration for different bone animation modes
enum E_BONE_ANIMATION_MODE
{
//! The bone is usually animated, unless it's parent is not animated
EBAM_AUTOMATIC = 0,
//! The bone is animated by the skin, if it's parent is not animated then animation will resume from this bone onward
EBAM_ANIMATED,
//! The bone is not animated by the skin
EBAM_UNANIMATED,
//! Not an animation mode, just here to count the available modes
EBAM_COUNT
};
enum E_BONE_SKINNING_SPACE
{
//! local skinning, standard
EBSS_LOCAL = 0,
//! global skinning
EBSS_GLOBAL,
EBSS_COUNT
};
//! Names for bone animation modes
const c8 *const BoneAnimationModeNames[] = {
"automatic",
"animated",
"unanimated",
0,
};
//! Interface for bones used for skeletal animation.
/** Used with SkinnedMesh and IAnimatedMeshSceneNode. */
class IBoneSceneNode : public ISceneNode
{
public:
IBoneSceneNode(ISceneNode *parent, ISceneManager *mgr, s32 id = -1) :
ISceneNode(parent, mgr, id), positionHint(-1), scaleHint(-1), rotationHint(-1) {}
ISceneNode(parent, mgr, id) {}
//! Get the index of the bone
virtual u32 getBoneIndex() const = 0;
//! Sets the animation mode of the bone.
/** \return True if successful. (Unused) */
virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode) = 0;
//! Gets the current animation mode of the bone
virtual E_BONE_ANIMATION_MODE getAnimationMode() const = 0;
//! Get the axis aligned bounding box of this node
const core::aabbox3d<f32> &getBoundingBox() const override = 0;
@ -78,18 +35,8 @@ public:
/** Does nothing as bones are not visible. */
void render() override {}
//! How the relative transformation of the bone is used
virtual void setSkinningSpace(E_BONE_SKINNING_SPACE space) = 0;
//! How the relative transformation of the bone is used
virtual E_BONE_SKINNING_SPACE getSkinningSpace() const = 0;
//! Updates the absolute position based on the relative and the parents position
virtual void updateAbsolutePositionOfAllChildren() = 0;
s32 positionHint;
s32 scaleHint;
s32 rotationHint;
};
} // end namespace scene

View file

@ -309,7 +309,7 @@ public:
//! Joints
struct SJoint
{
SJoint() : GlobalSkinningSpace(false) {}
SJoint() {}
//! The name of this joint
std::optional<std::string> Name;
@ -344,8 +344,6 @@ public:
private:
//! Internal members used by SkinnedMesh
friend class SkinnedMesh;
bool GlobalSkinningSpace;
};
const std::vector<SJoint *> &getAllJoints() const {

View file

@ -34,7 +34,7 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh *mesh,
StartFrame(0), EndFrame(0), FramesPerSecond(0.025f),
CurrentFrameNr(0.f), LastTimeMs(0),
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
JointMode(EJUOR_NONE), JointsUsed(false),
JointsUsed(false),
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
LoopCallBack(0), PassCount(0)
{
@ -163,28 +163,14 @@ IMesh *CAnimatedMeshSceneNode::getMeshForCurrentFrame()
SkinnedMesh *skinnedMesh = static_cast<SkinnedMesh *>(Mesh);
if (JointMode == EJUOR_CONTROL) // write to mesh
skinnedMesh->transferJointsToMesh(JointChildSceneNodes);
else
skinnedMesh->animateMesh(getFrameNr());
// skinnedMesh->transferJointsToMesh(JointChildSceneNodes);
// Update the skinned mesh for the current joint transforms.
skinnedMesh->skinMesh();
if (JointMode == EJUOR_READ) { // read from mesh
skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes);
//---slow---
for (u32 n = 0; n < JointChildSceneNodes.size(); ++n)
if (JointChildSceneNodes[n]->getParent() == this) {
JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); // temp, should be an option
}
}
if (JointMode == EJUOR_CONTROL) {
// For meshes other than EJUOR_CONTROL, this is done by calling animateMesh()
skinnedMesh->updateBoundingBox();
}
return skinnedMesh;
}
@ -556,14 +542,7 @@ void CAnimatedMeshSceneNode::updateAbsolutePosition()
IAnimatedMeshSceneNode::updateAbsolutePosition();
}
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode)
{
checkJoints();
JointMode = mode;
}
//! 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 CAnimatedMeshSceneNode::setTransitionTime(f32 time)
{
@ -571,10 +550,6 @@ void CAnimatedMeshSceneNode::setTransitionTime(f32 time)
if (TransitionTime == ttime)
return;
TransitionTime = ttime;
if (ttime != 0)
setJointMode(EJUOR_CONTROL);
else
setJointMode(EJUOR_NONE);
}
//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected)
@ -651,8 +626,6 @@ void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
}
}
/*!
*/
void CAnimatedMeshSceneNode::checkJoints()
{
if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED)
@ -668,12 +641,9 @@ void CAnimatedMeshSceneNode::checkJoints()
((SkinnedMesh *)Mesh)->recoverJointsFromMesh(JointChildSceneNodes);
JointsUsed = true;
JointMode = EJUOR_READ;
}
}
/*!
*/
void CAnimatedMeshSceneNode::beginTransition()
{
if (!JointsUsed)
@ -695,8 +665,6 @@ void CAnimatedMeshSceneNode::beginTransition()
TransitingBlend = 0.f;
}
/*!
*/
ISceneNode *CAnimatedMeshSceneNode::clone(ISceneNode *newParent, ISceneManager *newManager)
{
if (!newParent)
@ -722,7 +690,6 @@ ISceneNode *CAnimatedMeshSceneNode::clone(ISceneNode *newParent, ISceneManager *
newNode->EndFrame = EndFrame;
newNode->FramesPerSecond = FramesPerSecond;
newNode->CurrentFrameNr = CurrentFrameNr;
newNode->JointMode = JointMode;
newNode->JointsUsed = JointsUsed;
newNode->TransitionTime = TransitionTime;
newNode->Transiting = Transiting;

View file

@ -117,9 +117,6 @@ public:
//! updates the absolute position based on the relative and the parents position
void updateAbsolutePosition() override;
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) override;
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
void setTransitionTime(f32 Time) override;
@ -158,8 +155,6 @@ private:
f32 Transiting; // is mesh transiting (plus cache of TransitionTime)
f32 TransitingBlend; // 0-1, calculated on buildFrameNr
// 0-unused, 1-get joints only, 2-set joints only, 3-move and set
E_JOINT_UPDATE_ON_RENDER JointMode;
bool JointsUsed;
bool Looping;

View file

@ -11,49 +11,6 @@ namespace irr
namespace scene
{
//! constructor
CBoneSceneNode::CBoneSceneNode(ISceneNode *parent, ISceneManager *mgr, s32 id,
u32 boneIndex, const std::optional<std::string> &boneName) :
IBoneSceneNode(parent, mgr, id),
BoneIndex(boneIndex),
AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL)
{
setName(boneName);
}
//! Returns the index of the bone
u32 CBoneSceneNode::getBoneIndex() const
{
return BoneIndex;
}
//! Sets the animation mode of the bone. Returns true if successful.
bool CBoneSceneNode::setAnimationMode(E_BONE_ANIMATION_MODE mode)
{
AnimationMode = mode;
return true;
}
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE CBoneSceneNode::getAnimationMode() const
{
return AnimationMode;
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32> &CBoneSceneNode::getBoundingBox() const
{
return Box;
}
/*
//! Returns the relative transformation of the scene node.
core::matrix4 CBoneSceneNode::getRelativeTransformation() const
{
return core::matrix4(); // RelativeTransformation;
}
*/
void CBoneSceneNode::OnAnimate(u32 timeMs)
{
if (IsVisible) {

View file

@ -21,49 +21,36 @@ public:
//! constructor
CBoneSceneNode(ISceneNode *parent, ISceneManager *mgr,
s32 id = -1, u32 boneIndex = 0,
const std::optional<std::string> &boneName = std::nullopt);
const std::optional<std::string> &boneName = std::nullopt) :
IBoneSceneNode(parent, mgr, id),
BoneIndex(boneIndex)
{
setName(boneName);
}
//! Returns the index of the bone
u32 getBoneIndex() const override;
//! Sets the animation mode of the bone. Returns true if successful.
bool setAnimationMode(E_BONE_ANIMATION_MODE mode) override;
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE getAnimationMode() const override;
u32 getBoneIndex() const override
{
return BoneIndex;
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32> &getBoundingBox() const override;
/*
//! Returns the relative transformation of the scene node.
//core::matrix4 getRelativeTransformation() const override;
*/
const core::aabbox3d<f32> &getBoundingBox() const override
{
return Box;
}
void OnAnimate(u32 timeMs) override;
void updateAbsolutePositionOfAllChildren() override;
//! How the relative transformation of the bone is used
void setSkinningSpace(E_BONE_SKINNING_SPACE space) override
{
SkinningSpace = space;
}
E_BONE_SKINNING_SPACE getSkinningSpace() const override
{
return SkinningSpace;
}
private:
void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node);
u32 BoneIndex;
const u32 BoneIndex;
core::aabbox3d<f32> Box{-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
E_BONE_ANIMATION_MODE AnimationMode;
E_BONE_SKINNING_SPACE SkinningSpace;
// Bogus box; bone scene nodes are not rendered anyways.
static constexpr core::aabbox3d<f32> Box = {{0, 0, 0}};
};
} // end namespace scene

View file

@ -74,9 +74,7 @@ void SkinnedMesh::animateMesh(f32 frame)
SkinnedLastFrame = false;
for (auto *joint : AllJoints) {
// The joints can be animated here with no input from their
// parents, but for setAnimationMode extra checks are needed
// to their parents
// The joints can be animated here with no input from their parents
joint->keys.updateTransform(frame,
joint->Animatedposition,
joint->Animatedrotation,
@ -102,8 +100,6 @@ void SkinnedMesh::buildAllLocalAnimatedMatrices()
// Could be faster:
if (!joint->keys.empty()) {
joint->GlobalSkinningSpace = false;
// 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.
@ -164,7 +160,7 @@ void SkinnedMesh::buildAllGlobalAnimatedMatrices(SJoint *joint, SJoint *parentJo
return;
} else {
// Find global matrix...
if (!parentJoint || joint->GlobalSkinningSpace)
if (!parentJoint)
joint->GlobalAnimatedMatrix = joint->LocalAnimatedMatrix;
else
joint->GlobalAnimatedMatrix = parentJoint->GlobalAnimatedMatrix * joint->LocalAnimatedMatrix;
@ -706,8 +702,6 @@ void SkinnedMesh::transferJointsToMesh(const std::vector<IBoneSceneNode *> &join
joint->LocalAnimatedMatrix.setRotationDegrees(node->getRotation());
joint->LocalAnimatedMatrix.setTranslation(node->getPosition());
joint->LocalAnimatedMatrix *= core::matrix4().setScale(node->getScale());
joint->GlobalSkinningSpace = (node->getSkinningSpace() == EBSS_GLOBAL);
}
// Make sure we recalc the next frame
LastAnimatedFrame = -1;

View file

@ -1398,12 +1398,9 @@ void GenericCAO::updateBones(f32 dtime)
{
if (!m_animated_meshnode)
return;
if (m_bone_override.empty()) {
m_animated_meshnode->setJointMode(scene::EJUOR_NONE);
if (m_bone_override.empty())
return;
}
m_animated_meshnode->setJointMode(scene::EJUOR_CONTROL); // To write positions to the mesh on render
for (auto &it : m_bone_override) {
std::string bone_name = it.first;
scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());