Enable client-side attachments, add detachment code
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 4 Nov 2012 12:33:30 +0000 (14:33 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 25 Nov 2012 17:14:23 +0000 (19:14 +0200)
src/content_cao.cpp
src/content_sao.cpp
src/content_sao.h

index 60d458318d7ce6a3816d6d30137ef6d3f6ca724b..deb9aa9036e8260cbc155f9cc80dd70356ecc2b6 100644 (file)
@@ -583,7 +583,7 @@ private:
        std::map<std::string, core::vector2d<v3f> > m_bone_posrot;
        ClientActiveObject* m_attachment_parent;
        std::string m_attachment_bone;
-       v3f m_attacmhent_position;
+       v3f m_attachment_position;
        v3f m_attachment_rotation;
        int m_anim_frame;
        int m_anim_num_frames;
@@ -626,7 +626,7 @@ public:
                // Nothing to do for m_bone_posrot
                m_attachment_parent(NULL),
                m_attachment_bone(""),
-               m_attacmhent_position(v3f(0,0,0)),
+               m_attachment_position(v3f(0,0,0)),
                m_attachment_rotation(v3f(0,0,0)),
                m_anim_frame(0),
                m_anim_num_frames(1),
@@ -852,7 +852,6 @@ public:
                        if(mesh)
                        {
                                m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL);
-                               m_animated_meshnode->setMD2Animation(scene::EMAT_STAND);
                                m_animated_meshnode->animateJoints(); // Needed for some animations
                                m_animated_meshnode->setScale(v3f(m_prop.visual_size.X,
                                                m_prop.visual_size.Y,
@@ -1053,8 +1052,12 @@ public:
                        updateNodePos();
                }
 
-               if(m_animated_meshnode)
-                       errorstream<<"Attachment position: "<<m_animated_meshnode->getPosition().X<<","<<m_animated_meshnode->getPosition().Y<<","<<m_animated_meshnode->getPosition().Z<<std::endl;
+               // REMAINING ATTACHMENT ISSUES:
+               // Absolute Position of attachments is printed differently here than what it's set to in the SetAttachment function.
+               // Apparently here it prints the origin of the parent, but ignores the offset it was actually set to.
+
+               //if(m_animated_meshnode != NULL && m_attachment_parent != NULL)
+               //      errorstream<<"Attachment position, step: "<<m_animated_meshnode->getAbsolutePosition().X<<","<<m_animated_meshnode->getAbsolutePosition().Y<<","<<m_animated_meshnode->getAbsolutePosition().Z<<std::endl;
        }
 
        void updateTexturePos()
@@ -1280,11 +1283,42 @@ public:
                // http://gamedev.stackexchange.com/questions/27363/finding-the-endpoint-of-a-named-bone-in-irrlicht
                // Irrlicht documentation: http://irrlicht.sourceforge.net/docu/
 
-               if (m_attachment_parent != NULL && !m_attachment_parent->isLocalPlayer())
+               if(m_attachment_parent == NULL || m_attachment_parent->isLocalPlayer()) // Detach
+               {
+                       if(m_meshnode)
+                       {
+                               v3f old_position = m_meshnode->getAbsolutePosition();
+                               v3f old_rotation = m_meshnode->getRotation();
+                               m_meshnode->setParent(m_smgr->getRootSceneNode());
+                               m_meshnode->setPosition(old_position);
+                               m_meshnode->setRotation(old_rotation);
+                               m_meshnode->updateAbsolutePosition();
+                       }
+                       if(m_animated_meshnode)
+                       {
+                               v3f old_position = m_animated_meshnode->getAbsolutePosition();
+                               v3f old_rotation = m_animated_meshnode->getRotation();
+                               m_animated_meshnode->setParent(m_smgr->getRootSceneNode());
+                               m_animated_meshnode->setPosition(old_position);
+                               m_animated_meshnode->setRotation(old_rotation);
+                               m_animated_meshnode->updateAbsolutePosition();
+                       }
+                       if(m_spritenode)
+                       {
+                               v3f old_position = m_spritenode->getAbsolutePosition();
+                               v3f old_rotation = m_spritenode->getRotation();
+                               m_spritenode->setParent(m_smgr->getRootSceneNode());
+                               m_spritenode->setPosition(old_position);
+                               m_spritenode->setRotation(old_rotation);
+                               m_spritenode->updateAbsolutePosition();
+                       }
+               }
+               else // Attach
                {
                        // REMAINING ATTACHMENT ISSUES:
                        // The code below should cause the child to get attached, but for some reason it's not working
-                       // A debug print confirms both position and absolute position are set accordingly, but the object still shows at origin 0,0,0
+                       // A debug print confirms both position and absolute position are set accordingly, but the object still doesn't show
+                       // Position and Absolute Position were tested to be set properly here
 
                        scene::IMeshSceneNode *parent_mesh = NULL;
                        if(m_attachment_parent->getMeshSceneNode())
@@ -1299,94 +1333,92 @@ public:
                        scene::IBoneSceneNode *parent_bone = NULL;
                        if(parent_animated_mesh && m_attachment_bone != "")
                                parent_bone = parent_animated_mesh->getJointNode(m_attachment_bone.c_str());
-                       if(!parent_bone) // Should be false if the bone doesn't exist on the mesh
-                               parent_bone = NULL;
 
                        // TODO: Perhaps use polymorphism here to save code duplication
                        if(m_meshnode){
                                if(parent_bone){
-                                       m_meshnode->setPosition(parent_bone->getPosition());
-                                       m_meshnode->setRotation(parent_bone->getRotation());
+                                       m_meshnode->setParent(parent_bone);
+                                       m_meshnode->setPosition(m_attachment_position);
+                                       m_meshnode->setRotation(m_attachment_rotation);
                                        m_meshnode->updateAbsolutePosition();
-                                       //m_meshnode->setParent(parent_bone);
                                }
                                else
                                {
                                        if(parent_mesh){
-                                               m_meshnode->setPosition(parent_mesh->getPosition());
-                                               m_meshnode->setRotation(parent_mesh->getRotation());
+                                               m_meshnode->setParent(parent_mesh);
+                                               m_meshnode->setPosition(m_attachment_position);
+                                               m_meshnode->setRotation(m_attachment_rotation);
                                                m_meshnode->updateAbsolutePosition();
-                                               //m_meshnode->setParent(parent_mesh);
                                        }
                                        else if(parent_animated_mesh){
-                                               m_meshnode->setPosition(parent_animated_mesh->getPosition());
-                                               m_meshnode->setRotation(parent_animated_mesh->getRotation());
+                                               m_meshnode->setParent(parent_animated_mesh);
+                                               m_meshnode->setPosition(m_attachment_position);
+                                               m_meshnode->setRotation(m_attachment_rotation);
                                                m_meshnode->updateAbsolutePosition();
-                                               //m_meshnode->setParent(parent_animated_mesh);
                                        }
                                        else if(parent_sprite){
-                                               m_meshnode->setPosition(parent_sprite->getPosition());
-                                               m_meshnode->setRotation(parent_sprite->getRotation());
+                                               m_meshnode->setParent(parent_sprite);
+                                               m_meshnode->setPosition(m_attachment_position);
+                                               m_meshnode->setRotation(m_attachment_rotation);
                                                m_meshnode->updateAbsolutePosition();
-                                               //m_meshnode->setParent(parent_sprite);
                                        }
                                }
                        }
                        if(m_animated_meshnode){
                                if(parent_bone){
-                                       m_animated_meshnode->setPosition(parent_bone->getPosition());
-                                       m_animated_meshnode->setRotation(parent_bone->getRotation());
+                                       m_animated_meshnode->setParent(parent_bone);
+                                       m_animated_meshnode->setPosition(m_attachment_position);
+                                       m_animated_meshnode->setRotation(m_attachment_rotation);
                                        m_animated_meshnode->updateAbsolutePosition();
-                                       //m_animated_meshnode->setParent(parent_bone);
                                }
                                else
                                {
                                        if(parent_mesh){
-                                               m_animated_meshnode->setPosition(parent_mesh->getPosition());
-                                               m_animated_meshnode->setRotation(parent_mesh->getRotation());
+                                               m_animated_meshnode->setParent(parent_mesh);
+                                               m_animated_meshnode->setPosition(m_attachment_position);
+                                               m_animated_meshnode->setRotation(m_attachment_rotation);
                                                m_animated_meshnode->updateAbsolutePosition();
-                                               //m_animated_meshnode->setParent(parent_mesh);
                                        }
                                        else if(parent_animated_mesh){
-                                               m_animated_meshnode->setPosition(parent_animated_mesh->getPosition());
-                                               m_animated_meshnode->setRotation(parent_animated_mesh->getRotation());
+                                               m_animated_meshnode->setParent(parent_animated_mesh);
+                                               m_animated_meshnode->setPosition(m_attachment_position);
+                                               m_animated_meshnode->setRotation(m_attachment_rotation);
                                                m_animated_meshnode->updateAbsolutePosition();
-                                               //m_animated_meshnode->setParent(parent_animated_mesh);
                                        }
                                        else if(parent_sprite){
-                                               m_animated_meshnode->setPosition(parent_sprite->getPosition());
-                                               m_animated_meshnode->setRotation(parent_sprite->getRotation());
+                                               m_animated_meshnode->setParent(parent_sprite);
+                                               m_animated_meshnode->setPosition(m_attachment_position);
+                                               m_animated_meshnode->setRotation(m_attachment_rotation);
                                                m_animated_meshnode->updateAbsolutePosition();
-                                               //m_animated_meshnode->setParent(parent_sprite);
                                        }
                                }
                        }
                        if(m_spritenode){
                                if(parent_bone){
-                                       m_spritenode->setPosition(parent_bone->getPosition());
-                                       m_spritenode->setRotation(parent_bone->getRotation());
+                                       m_spritenode->setParent(parent_bone);
+                                       m_spritenode->setPosition(m_attachment_position);
+                                       m_spritenode->setRotation(m_attachment_rotation);
                                        m_spritenode->updateAbsolutePosition();
-                                       //m_spritenode->setParent(parent_bone);
                                }
                                else
                                {
                                        if(parent_mesh){
-                                               m_spritenode->setPosition(parent_mesh->getPosition());
-                                               m_spritenode->setRotation(parent_mesh->getRotation());
+                                               m_spritenode->setParent(parent_mesh);
+                                               m_spritenode->setPosition(m_attachment_position);
+                                               m_spritenode->setRotation(m_attachment_rotation);
                                                m_spritenode->updateAbsolutePosition();
-                                               //m_spritenode->setParent(parent_mesh);
                                        }
                                        else if(parent_animated_mesh){
-                                               m_spritenode->setPosition(parent_animated_mesh->getPosition());
-                                               m_spritenode->setRotation(parent_animated_mesh->getRotation());
+                                               m_spritenode->setParent(parent_animated_mesh);
+                                               m_spritenode->setPosition(m_attachment_position);
+                                               m_spritenode->setRotation(m_attachment_rotation);
                                                m_spritenode->updateAbsolutePosition();
-                                               //m_spritenode->setParent(parent_animated_mesh);
                                        }
                                        else if(parent_sprite){
-                                               m_spritenode->setPosition(parent_sprite->getPosition());
-                                               m_spritenode->setRotation(parent_sprite->getRotation());
+                                               m_spritenode->setParent(parent_sprite);
+                                               m_spritenode->setPosition(m_attachment_position);
+                                               m_spritenode->setRotation(m_attachment_rotation);
                                                m_spritenode->updateAbsolutePosition();
-                                               //m_spritenode->setParent(parent_sprite);
                                        }
                                }
                        }
@@ -1468,8 +1500,7 @@ public:
                        m_frame_speed = readF1000(is);
                        m_frame_blend = readF1000(is);
 
-                       updateAnimations();
-                       expireVisuals();
+                       expireVisuals(); // Automatically calls the proper function next
                }
                else if(cmd == GENERIC_CMD_SET_BONE_POSROT)
                {
@@ -1478,8 +1509,7 @@ public:
                        v3f rotation = readV3F1000(is);
                        m_bone_posrot[bone] = core::vector2d<v3f>(position, rotation);
 
-                       updateBonePosRot();
-                       expireVisuals();
+                       expireVisuals(); // Automatically calls the proper function next
                }
                else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
                {
@@ -1489,10 +1519,10 @@ public:
                                obj = NULL;
                        m_attachment_parent = obj;
                        m_attachment_bone = deSerializeString(is);
-                       m_attacmhent_position = readV3F1000(is);
+                       m_attachment_position = readV3F1000(is);
                        m_attachment_rotation = readV3F1000(is);
 
-                       updateAttachments();
+                       expireVisuals(); // Automatically calls the proper function next
                }
                else if(cmd == GENERIC_CMD_PUNCHED)
                {
index 3289f9077f5ba8ac8641d6646635490b5aa3f81e..7857df1aa17c0859bb2f8c76be32d37757e11391 100644 (file)
@@ -356,7 +356,10 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
        m_last_sent_velocity(0,0,0),
        m_last_sent_position_timer(0),
        m_last_sent_move_precision(0),
-       m_armor_groups_sent(false)
+       m_armor_groups_sent(false),
+       m_animations_sent(false),
+       m_animations_bone_sent(false),
+       m_attachment_sent(false)
 {
        // Only register type if no environment supplied
        if(env == NULL){
@@ -514,6 +517,32 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
                ActiveObjectMessage aom(getId(), true, str);
                m_messages_out.push_back(aom);
        }
+
+       if(m_animations_sent == false){
+               m_animations_sent = true;
+               std::string str = gob_cmd_set_animations(m_animation_frames, m_animation_speed, m_animation_blend);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, str);
+               m_messages_out.push_back(aom);
+       }
+
+       if(m_animations_bone_sent == false){
+               m_animations_bone_sent = true;
+               for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_animation_bone.begin(); ii != m_animation_bone.end(); ++ii){
+                       std::string str = gob_cmd_set_bone_posrot((*ii).first, (*ii).second.X, (*ii).second.Y);
+                       // create message and add to list
+                       ActiveObjectMessage aom(getId(), true, str);
+                       m_messages_out.push_back(aom);
+               }
+       }
+
+       if(m_attachment_sent == false){
+               m_attachment_sent = true;
+               std::string str = gob_cmd_set_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, str);
+               m_messages_out.push_back(aom);
+       }
 }
 
 std::string LuaEntitySAO::getClientInitializationData()
@@ -672,18 +701,16 @@ void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
 
 void LuaEntitySAO::setAnimations(v2f frames, float frame_speed, float frame_blend)
 {
-       std::string str = gob_cmd_set_animations(frames, frame_speed, frame_blend);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
+       m_animation_frames = frames;
+       m_animation_speed = frame_speed;
+       m_animation_blend = frame_blend;
+       m_animations_sent = false;
 }
 
 void LuaEntitySAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
 {
-       std::string str = gob_cmd_set_bone_posrot(bone, position, rotation);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
+       m_animation_bone[bone] = core::vector2d<v3f>(position, rotation);
+       m_animations_bone_sent = false;
 }
 
 void LuaEntitySAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation)
@@ -700,10 +727,11 @@ void LuaEntitySAO::setAttachment(ServerActiveObject *parent, std::string bone, v
        m_parent = parent;
 
        // Client attachment:
-       std::string str = gob_cmd_set_attachment(parent->getId(), bone, position, rotation);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
+       m_attachment_parent_id = parent->getId();
+       m_attachment_bone = bone;
+       m_attachment_position = position;
+       m_attachment_rotation = rotation;
+       m_attachment_sent = false;
 }
 
 ObjectProperties* LuaEntitySAO::accessObjectProperties()
@@ -831,6 +859,9 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
        m_properties_sent(true),
        m_privs(privs),
        m_is_singleplayer(is_singleplayer),
+       m_animations_sent(false),
+       m_animations_bone_sent(false),
+       m_attachment_sent(false),
        // public
        m_teleported(false),
        m_inventory_not_sent(false),
@@ -1051,6 +1082,32 @@ void PlayerSAO::step(float dtime, bool send_recommended)
                ActiveObjectMessage aom(getId(), true, str);
                m_messages_out.push_back(aom);
        }
+
+       if(m_animations_sent == false){
+               m_animations_sent = true;
+               std::string str = gob_cmd_set_animations(m_animation_frames, m_animation_speed, m_animation_blend);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, str);
+               m_messages_out.push_back(aom);
+       }
+
+       if(m_animations_bone_sent == false){
+               m_animations_bone_sent = true;
+               for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_animation_bone.begin(); ii != m_animation_bone.end(); ++ii){
+                       std::string str = gob_cmd_set_bone_posrot((*ii).first, (*ii).second.X, (*ii).second.Y);
+                       // create message and add to list
+                       ActiveObjectMessage aom(getId(), true, str);
+                       m_messages_out.push_back(aom);
+               }
+       }
+
+       if(m_attachment_sent == false){
+               m_attachment_sent = true;
+               std::string str = gob_cmd_set_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, str);
+               m_messages_out.push_back(aom);
+       }
 }
 
 void PlayerSAO::setBasePosition(const v3f &position)
@@ -1176,18 +1233,18 @@ void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
 
 void PlayerSAO::setAnimations(v2f frames, float frame_speed, float frame_blend)
 {
-       std::string str = gob_cmd_set_animations(frames, frame_speed, frame_blend);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
+       // store these so they can be updated to clients
+       m_animation_frames = frames;
+       m_animation_speed = frame_speed;
+       m_animation_blend = frame_blend;
+       m_animations_sent = false;
 }
 
 void PlayerSAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
 {
-       std::string str = gob_cmd_set_bone_posrot(bone, position, rotation);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
+       // store these so they can be updated to clients
+       m_animation_bone[bone] = core::vector2d<v3f>(position, rotation);
+       m_animations_bone_sent = false;
 }
 
 void PlayerSAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation)
@@ -1204,10 +1261,11 @@ void PlayerSAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f
        m_parent = parent;
 
        // Client attachment:
-       std::string str = gob_cmd_set_attachment(parent->getId(), bone, position, rotation);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
+       m_attachment_parent_id = parent->getId();
+       m_attachment_bone = bone;
+       m_attachment_position = position;
+       m_attachment_rotation = rotation;
+       m_attachment_sent = false;
 }
 
 ObjectProperties* PlayerSAO::accessObjectProperties()
index e4d81cd2d970d92805d1e2d7737aec59c7c88c2d..5bcd3c77f6a4991fc64c69c83ba29cab5eb06c68 100644 (file)
@@ -99,7 +99,21 @@ private:
        float m_last_sent_position_timer;
        float m_last_sent_move_precision;
        bool m_armor_groups_sent;
+       
+       v2f m_animation_frames;
+       float m_animation_speed;
+       float m_animation_blend;
+       bool m_animations_sent;
+
+       std::map<std::string, core::vector2d<v3f> > m_animation_bone;
+       bool m_animations_bone_sent;
+       
        ServerActiveObject *m_parent;
+       int m_attachment_parent_id;
+       std::string m_attachment_bone;
+       v3f m_attachment_position;
+       v3f m_attachment_rotation;
+       bool m_attachment_sent;
 };
 
 /*
@@ -236,13 +250,30 @@ private:
        bool m_position_not_sent;
        ItemGroupList m_armor_groups;
        bool m_armor_groups_sent;
-       ServerActiveObject *m_parent;
+
+
+
        bool m_properties_sent;
        struct ObjectProperties m_prop;
        // Cached privileges for enforcement
        std::set<std::string> m_privs;
        bool m_is_singleplayer;
 
+       v2f m_animation_frames;
+       float m_animation_speed;
+       float m_animation_blend;
+       bool m_animations_sent;
+
+       std::map<std::string, core::vector2d<v3f> > m_animation_bone;
+       bool m_animations_bone_sent;
+       
+       ServerActiveObject *m_parent;
+       int m_attachment_parent_id;
+       std::string m_attachment_bone;
+       v3f m_attachment_position;
+       v3f m_attachment_rotation;
+       bool m_attachment_sent;
+
 public:
        // Some flags used by Server
        bool m_teleported;