aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorhecktest <42101236+hecktest@users.noreply.github.com>2020-06-26 00:06:29 +0200
committerGitHub <noreply@github.com>2020-06-26 00:06:29 +0200
commit7be082f9a8bb6bd46c226d7ef4c42f0fd9fe7314 (patch)
treeb06158c3a9816c9a2a8f4d471d1ef9def48d0f76 /src/client
parent3014e8b33b3d14165cc207be13631f4ee9a8fd2e (diff)
downloadminetest-7be082f9a8bb6bd46c226d7ef4c42f0fd9fe7314.tar.gz
minetest-7be082f9a8bb6bd46c226d7ef4c42f0fd9fe7314.tar.bz2
minetest-7be082f9a8bb6bd46c226d7ef4c42f0fd9fe7314.zip
Fix bone-attached entities (#10015)
Diffstat (limited to 'src/client')
-rw-r--r--src/client/content_cao.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp
index 7f573b5a1..4f949f6b0 100644
--- a/src/client/content_cao.cpp
+++ b/src/client/content_cao.cpp
@@ -162,6 +162,15 @@ static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill,
matrix.setTextureScale(txs, tys);
}
+// Evaluate transform chain recursively; irrlicht does not do this for us
+static void updatePositionRecursive(scene::ISceneNode *node)
+{
+ scene::ISceneNode *parent = node->getParent();
+ if (parent)
+ updatePositionRecursive(parent);
+ node->updateAbsolutePosition();
+}
+
/*
TestCAO
*/
@@ -929,11 +938,6 @@ void GenericCAO::updateNodePos()
void GenericCAO::step(float dtime, ClientEnvironment *env)
{
- if (m_animated_meshnode) {
- m_animated_meshnode->animateJoints();
- updateBonePosition();
- }
-
// Handle model animations and update positions instantly to prevent lags
if (m_is_local_player) {
LocalPlayer *player = m_env->getLocalPlayer();
@@ -1143,6 +1147,18 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
rot_translator.val_current = m_rotation;
updateNodePos();
}
+
+ if (m_animated_meshnode) {
+ // Everything must be updated; the whole transform
+ // chain as well as the animated mesh node.
+ // Otherwise, bone attachments would be relative to
+ // a position that's one frame old.
+ if (m_matrixnode)
+ updatePositionRecursive(m_matrixnode);
+ m_animated_meshnode->updateAbsolutePosition();
+ m_animated_meshnode->animateJoints();
+ updateBonePosition();
+ }
}
void GenericCAO::updateTexturePos()
@@ -1444,6 +1460,18 @@ void GenericCAO::updateBonePosition()
bone->updateAbsolutePosition();
}
}
+ // The following is needed for set_bone_pos to propagate to
+ // attached objects correctly.
+ // Irrlicht ought to do this, but doesn't when using EJUOR_CONTROL.
+ for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) {
+ auto bone = m_animated_meshnode->getJointNode(i);
+ // Look for the root bone.
+ if (bone && bone->getParent() == m_animated_meshnode) {
+ // Update entire skeleton.
+ bone->updateAbsolutePositionOfAllChildren();
+ break;
+ }
+ }
}
void GenericCAO::updateAttachments()