From d7d759b43f99c999fedd9376edbf5f4e1384dafa Mon Sep 17 00:00:00 2001 From: MirceaKitsune Date: Sun, 4 Nov 2012 14:33:30 +0200 Subject: [PATCH] Enable client-side attachments, add detachment code --- src/content_cao.cpp | 132 +++++++++++++++++++++++++++----------------- src/content_sao.cpp | 108 +++++++++++++++++++++++++++--------- src/content_sao.h | 33 ++++++++++- 3 files changed, 196 insertions(+), 77 deletions(-) diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 60d458318..deb9aa903 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -583,7 +583,7 @@ private: std::map > 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: "<getPosition().X<<","<getPosition().Y<<","<getPosition().Z<getAbsolutePosition().X<<","<getAbsolutePosition().Y<<","<getAbsolutePosition().Z<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(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) { diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 3289f9077..7857df1aa 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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 >::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(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 >::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(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() diff --git a/src/content_sao.h b/src/content_sao.h index e4d81cd2d..5bcd3c77f 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -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 > 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 m_privs; bool m_is_singleplayer; + v2f m_animation_frames; + float m_animation_speed; + float m_animation_blend; + bool m_animations_sent; + + std::map > 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;