Fix player-to-object attachment teleport bug (#10008)
authorhecktest <42101236+hecktest@users.noreply.github.com>
Tue, 9 Jun 2020 17:36:47 +0000 (19:36 +0200)
committerGitHub <noreply@github.com>
Tue, 9 Jun 2020 17:36:47 +0000 (19:36 +0200)
Fixes two bugs:

 * The camera offset was not applied to an object while detaching, briefly placing the irrlicht matrixnode in world space.
 *  When attaching, the matrixnode's absolute position was evaluated without evaluating the parent first, resulting in zeroed positions.

src/client/content_cao.cpp

index a6ce06d205dbfb31a0f8c3945f9fab33ecf72f2c..79ecccb6f7f7ffea62ee95c3b69b11ef8fd494cf 100644 (file)
@@ -921,7 +921,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                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();
@@ -1403,7 +1403,7 @@ void GenericCAO::updateBonePosition()
                        bone->setRotation(it.second.Y);
                }
        }
-       
+
        // search through bones to find mistakenly rotated bones due to bug in Irrlicht
        for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) {
                irr::scene::IBoneSceneNode *bone = m_animated_meshnode->getJointNode(i);
@@ -1427,7 +1427,7 @@ void GenericCAO::updateBonePosition()
                // and update the bones transformation.
                v3f bone_rot = bone->getRelativeTransformation().getRotationDegrees();
                float offset = fabsf(bone_rot.X - bone->getRotation().X);
-               if (offset > 179.9f && offset < 180.1f) { 
+               if (offset > 179.9f && offset < 180.1f) {
                        bone->setRotation(bone_rot);
                        bone->updateAbsolutePosition();
                }
@@ -1454,15 +1454,17 @@ void GenericCAO::updateAttachments()
 
        if (!parent) { // Detach or don't attach
                if (m_matrixnode) {
+                       v3s16 camera_offset = m_env->getCameraOffset();
                        v3f old_pos = getPosition();
 
                        m_matrixnode->setParent(m_smgr->getRootSceneNode());
-                       getPosRotMatrix().setTranslation(old_pos);
+                       getPosRotMatrix().setTranslation(old_pos - intToFloat(camera_offset, BS));
                        m_matrixnode->updateAbsolutePosition();
                }
        }
        else // Attach
        {
+               parent->updateAttachments();
                scene::ISceneNode *parent_node = parent->getSceneNode();
                scene::IAnimatedMeshSceneNode *parent_animated_mesh_node =
                                parent->getAnimatedMeshSceneNode();
@@ -1472,6 +1474,7 @@ void GenericCAO::updateAttachments()
 
                if (m_matrixnode && parent_node) {
                        m_matrixnode->setParent(parent_node);
+                       parent_node->updateAbsolutePosition();
                        getPosRotMatrix().setTranslation(m_attachment_position);
                        //setPitchYawRoll(getPosRotMatrix(), m_attachment_rotation);
                        // use Irrlicht eulers instead