Enable client-side attachments, add detachment code

This commit is contained in:
MirceaKitsune 2012-11-04 14:33:30 +02:00 committed by Perttu Ahola
parent ba3fd63e29
commit d7d759b43f
3 changed files with 196 additions and 77 deletions

@ -583,7 +583,7 @@ private:
std::map<std::string, core::vector2d<v3f> > m_bone_posrot; std::map<std::string, core::vector2d<v3f> > m_bone_posrot;
ClientActiveObject* m_attachment_parent; ClientActiveObject* m_attachment_parent;
std::string m_attachment_bone; std::string m_attachment_bone;
v3f m_attacmhent_position; v3f m_attachment_position;
v3f m_attachment_rotation; v3f m_attachment_rotation;
int m_anim_frame; int m_anim_frame;
int m_anim_num_frames; int m_anim_num_frames;
@ -626,7 +626,7 @@ public:
// Nothing to do for m_bone_posrot // Nothing to do for m_bone_posrot
m_attachment_parent(NULL), m_attachment_parent(NULL),
m_attachment_bone(""), 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_attachment_rotation(v3f(0,0,0)),
m_anim_frame(0), m_anim_frame(0),
m_anim_num_frames(1), m_anim_num_frames(1),
@ -852,7 +852,6 @@ public:
if(mesh) if(mesh)
{ {
m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL); 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->animateJoints(); // Needed for some animations
m_animated_meshnode->setScale(v3f(m_prop.visual_size.X, m_animated_meshnode->setScale(v3f(m_prop.visual_size.X,
m_prop.visual_size.Y, m_prop.visual_size.Y,
@ -1053,8 +1052,12 @@ public:
updateNodePos(); updateNodePos();
} }
if(m_animated_meshnode) // REMAINING ATTACHMENT ISSUES:
errorstream<<"Attachment position: "<<m_animated_meshnode->getPosition().X<<","<<m_animated_meshnode->getPosition().Y<<","<<m_animated_meshnode->getPosition().Z<<std::endl; // 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() void updateTexturePos()
@ -1280,11 +1283,42 @@ public:
// http://gamedev.stackexchange.com/questions/27363/finding-the-endpoint-of-a-named-bone-in-irrlicht // http://gamedev.stackexchange.com/questions/27363/finding-the-endpoint-of-a-named-bone-in-irrlicht
// Irrlicht documentation: http://irrlicht.sourceforge.net/docu/ // 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: // REMAINING ATTACHMENT ISSUES:
// The code below should cause the child to get attached, but for some reason it's not working // 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; scene::IMeshSceneNode *parent_mesh = NULL;
if(m_attachment_parent->getMeshSceneNode()) if(m_attachment_parent->getMeshSceneNode())
@ -1299,94 +1333,92 @@ public:
scene::IBoneSceneNode *parent_bone = NULL; scene::IBoneSceneNode *parent_bone = NULL;
if(parent_animated_mesh && m_attachment_bone != "") if(parent_animated_mesh && m_attachment_bone != "")
parent_bone = parent_animated_mesh->getJointNode(m_attachment_bone.c_str()); 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 // TODO: Perhaps use polymorphism here to save code duplication
if(m_meshnode){ if(m_meshnode){
if(parent_bone){ if(parent_bone){
m_meshnode->setPosition(parent_bone->getPosition()); m_meshnode->setParent(parent_bone);
m_meshnode->setRotation(parent_bone->getRotation()); m_meshnode->setPosition(m_attachment_position);
m_meshnode->setRotation(m_attachment_rotation);
m_meshnode->updateAbsolutePosition(); m_meshnode->updateAbsolutePosition();
//m_meshnode->setParent(parent_bone);
} }
else else
{ {
if(parent_mesh){ if(parent_mesh){
m_meshnode->setPosition(parent_mesh->getPosition()); m_meshnode->setParent(parent_mesh);
m_meshnode->setRotation(parent_mesh->getRotation()); m_meshnode->setPosition(m_attachment_position);
m_meshnode->setRotation(m_attachment_rotation);
m_meshnode->updateAbsolutePosition(); m_meshnode->updateAbsolutePosition();
//m_meshnode->setParent(parent_mesh);
} }
else if(parent_animated_mesh){ else if(parent_animated_mesh){
m_meshnode->setPosition(parent_animated_mesh->getPosition()); m_meshnode->setParent(parent_animated_mesh);
m_meshnode->setRotation(parent_animated_mesh->getRotation()); m_meshnode->setPosition(m_attachment_position);
m_meshnode->setRotation(m_attachment_rotation);
m_meshnode->updateAbsolutePosition(); m_meshnode->updateAbsolutePosition();
//m_meshnode->setParent(parent_animated_mesh);
} }
else if(parent_sprite){ else if(parent_sprite){
m_meshnode->setPosition(parent_sprite->getPosition()); m_meshnode->setParent(parent_sprite);
m_meshnode->setRotation(parent_sprite->getRotation()); m_meshnode->setPosition(m_attachment_position);
m_meshnode->setRotation(m_attachment_rotation);
m_meshnode->updateAbsolutePosition(); m_meshnode->updateAbsolutePosition();
//m_meshnode->setParent(parent_sprite);
} }
} }
} }
if(m_animated_meshnode){ if(m_animated_meshnode){
if(parent_bone){ if(parent_bone){
m_animated_meshnode->setPosition(parent_bone->getPosition()); m_animated_meshnode->setParent(parent_bone);
m_animated_meshnode->setRotation(parent_bone->getRotation()); m_animated_meshnode->setPosition(m_attachment_position);
m_animated_meshnode->setRotation(m_attachment_rotation);
m_animated_meshnode->updateAbsolutePosition(); m_animated_meshnode->updateAbsolutePosition();
//m_animated_meshnode->setParent(parent_bone);
} }
else else
{ {
if(parent_mesh){ if(parent_mesh){
m_animated_meshnode->setPosition(parent_mesh->getPosition()); m_animated_meshnode->setParent(parent_mesh);
m_animated_meshnode->setRotation(parent_mesh->getRotation()); m_animated_meshnode->setPosition(m_attachment_position);
m_animated_meshnode->setRotation(m_attachment_rotation);
m_animated_meshnode->updateAbsolutePosition(); m_animated_meshnode->updateAbsolutePosition();
//m_animated_meshnode->setParent(parent_mesh);
} }
else if(parent_animated_mesh){ else if(parent_animated_mesh){
m_animated_meshnode->setPosition(parent_animated_mesh->getPosition()); m_animated_meshnode->setParent(parent_animated_mesh);
m_animated_meshnode->setRotation(parent_animated_mesh->getRotation()); m_animated_meshnode->setPosition(m_attachment_position);
m_animated_meshnode->setRotation(m_attachment_rotation);
m_animated_meshnode->updateAbsolutePosition(); m_animated_meshnode->updateAbsolutePosition();
//m_animated_meshnode->setParent(parent_animated_mesh);
} }
else if(parent_sprite){ else if(parent_sprite){
m_animated_meshnode->setPosition(parent_sprite->getPosition()); m_animated_meshnode->setParent(parent_sprite);
m_animated_meshnode->setRotation(parent_sprite->getRotation()); m_animated_meshnode->setPosition(m_attachment_position);
m_animated_meshnode->setRotation(m_attachment_rotation);
m_animated_meshnode->updateAbsolutePosition(); m_animated_meshnode->updateAbsolutePosition();
//m_animated_meshnode->setParent(parent_sprite);
} }
} }
} }
if(m_spritenode){ if(m_spritenode){
if(parent_bone){ if(parent_bone){
m_spritenode->setPosition(parent_bone->getPosition()); m_spritenode->setParent(parent_bone);
m_spritenode->setRotation(parent_bone->getRotation()); m_spritenode->setPosition(m_attachment_position);
m_spritenode->setRotation(m_attachment_rotation);
m_spritenode->updateAbsolutePosition(); m_spritenode->updateAbsolutePosition();
//m_spritenode->setParent(parent_bone);
} }
else else
{ {
if(parent_mesh){ if(parent_mesh){
m_spritenode->setPosition(parent_mesh->getPosition()); m_spritenode->setParent(parent_mesh);
m_spritenode->setRotation(parent_mesh->getRotation()); m_spritenode->setPosition(m_attachment_position);
m_spritenode->setRotation(m_attachment_rotation);
m_spritenode->updateAbsolutePosition(); m_spritenode->updateAbsolutePosition();
//m_spritenode->setParent(parent_mesh);
} }
else if(parent_animated_mesh){ else if(parent_animated_mesh){
m_spritenode->setPosition(parent_animated_mesh->getPosition()); m_spritenode->setParent(parent_animated_mesh);
m_spritenode->setRotation(parent_animated_mesh->getRotation()); m_spritenode->setPosition(m_attachment_position);
m_spritenode->setRotation(m_attachment_rotation);
m_spritenode->updateAbsolutePosition(); m_spritenode->updateAbsolutePosition();
//m_spritenode->setParent(parent_animated_mesh);
} }
else if(parent_sprite){ else if(parent_sprite){
m_spritenode->setPosition(parent_sprite->getPosition()); m_spritenode->setParent(parent_sprite);
m_spritenode->setRotation(parent_sprite->getRotation()); m_spritenode->setPosition(m_attachment_position);
m_spritenode->setRotation(m_attachment_rotation);
m_spritenode->updateAbsolutePosition(); m_spritenode->updateAbsolutePosition();
//m_spritenode->setParent(parent_sprite);
} }
} }
} }
@ -1468,8 +1500,7 @@ public:
m_frame_speed = readF1000(is); m_frame_speed = readF1000(is);
m_frame_blend = readF1000(is); m_frame_blend = readF1000(is);
updateAnimations(); expireVisuals(); // Automatically calls the proper function next
expireVisuals();
} }
else if(cmd == GENERIC_CMD_SET_BONE_POSROT) else if(cmd == GENERIC_CMD_SET_BONE_POSROT)
{ {
@ -1478,8 +1509,7 @@ public:
v3f rotation = readV3F1000(is); v3f rotation = readV3F1000(is);
m_bone_posrot[bone] = core::vector2d<v3f>(position, rotation); m_bone_posrot[bone] = core::vector2d<v3f>(position, rotation);
updateBonePosRot(); expireVisuals(); // Automatically calls the proper function next
expireVisuals();
} }
else if(cmd == GENERIC_CMD_SET_ATTACHMENT) else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
{ {
@ -1489,10 +1519,10 @@ public:
obj = NULL; obj = NULL;
m_attachment_parent = obj; m_attachment_parent = obj;
m_attachment_bone = deSerializeString(is); m_attachment_bone = deSerializeString(is);
m_attacmhent_position = readV3F1000(is); m_attachment_position = readV3F1000(is);
m_attachment_rotation = readV3F1000(is); m_attachment_rotation = readV3F1000(is);
updateAttachments(); expireVisuals(); // Automatically calls the proper function next
} }
else if(cmd == GENERIC_CMD_PUNCHED) else if(cmd == GENERIC_CMD_PUNCHED)
{ {

@ -356,7 +356,10 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
m_last_sent_velocity(0,0,0), m_last_sent_velocity(0,0,0),
m_last_sent_position_timer(0), m_last_sent_position_timer(0),
m_last_sent_move_precision(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 // Only register type if no environment supplied
if(env == NULL){ if(env == NULL){
@ -514,6 +517,32 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom); 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() 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) void LuaEntitySAO::setAnimations(v2f frames, float frame_speed, float frame_blend)
{ {
std::string str = gob_cmd_set_animations(frames, frame_speed, frame_blend); m_animation_frames = frames;
// create message and add to list m_animation_speed = frame_speed;
ActiveObjectMessage aom(getId(), true, str); m_animation_blend = frame_blend;
m_messages_out.push_back(aom); m_animations_sent = false;
} }
void LuaEntitySAO::setBonePosRot(std::string bone, v3f position, v3f rotation) void LuaEntitySAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
{ {
std::string str = gob_cmd_set_bone_posrot(bone, position, rotation); m_animation_bone[bone] = core::vector2d<v3f>(position, rotation);
// create message and add to list m_animations_bone_sent = false;
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
} }
void LuaEntitySAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation) 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; m_parent = parent;
// Client attachment: // Client attachment:
std::string str = gob_cmd_set_attachment(parent->getId(), bone, position, rotation); m_attachment_parent_id = parent->getId();
// create message and add to list m_attachment_bone = bone;
ActiveObjectMessage aom(getId(), true, str); m_attachment_position = position;
m_messages_out.push_back(aom); m_attachment_rotation = rotation;
m_attachment_sent = false;
} }
ObjectProperties* LuaEntitySAO::accessObjectProperties() ObjectProperties* LuaEntitySAO::accessObjectProperties()
@ -831,6 +859,9 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
m_properties_sent(true), m_properties_sent(true),
m_privs(privs), m_privs(privs),
m_is_singleplayer(is_singleplayer), m_is_singleplayer(is_singleplayer),
m_animations_sent(false),
m_animations_bone_sent(false),
m_attachment_sent(false),
// public // public
m_teleported(false), m_teleported(false),
m_inventory_not_sent(false), m_inventory_not_sent(false),
@ -1051,6 +1082,32 @@ void PlayerSAO::step(float dtime, bool send_recommended)
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom); 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) 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) void PlayerSAO::setAnimations(v2f frames, float frame_speed, float frame_blend)
{ {
std::string str = gob_cmd_set_animations(frames, frame_speed, frame_blend); // store these so they can be updated to clients
// create message and add to list m_animation_frames = frames;
ActiveObjectMessage aom(getId(), true, str); m_animation_speed = frame_speed;
m_messages_out.push_back(aom); m_animation_blend = frame_blend;
m_animations_sent = false;
} }
void PlayerSAO::setBonePosRot(std::string bone, v3f position, v3f rotation) void PlayerSAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
{ {
std::string str = gob_cmd_set_bone_posrot(bone, position, rotation); // store these so they can be updated to clients
// create message and add to list m_animation_bone[bone] = core::vector2d<v3f>(position, rotation);
ActiveObjectMessage aom(getId(), true, str); m_animations_bone_sent = false;
m_messages_out.push_back(aom);
} }
void PlayerSAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation) 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; m_parent = parent;
// Client attachment: // Client attachment:
std::string str = gob_cmd_set_attachment(parent->getId(), bone, position, rotation); m_attachment_parent_id = parent->getId();
// create message and add to list m_attachment_bone = bone;
ActiveObjectMessage aom(getId(), true, str); m_attachment_position = position;
m_messages_out.push_back(aom); m_attachment_rotation = rotation;
m_attachment_sent = false;
} }
ObjectProperties* PlayerSAO::accessObjectProperties() ObjectProperties* PlayerSAO::accessObjectProperties()

@ -99,7 +99,21 @@ private:
float m_last_sent_position_timer; float m_last_sent_position_timer;
float m_last_sent_move_precision; float m_last_sent_move_precision;
bool m_armor_groups_sent; 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; 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; bool m_position_not_sent;
ItemGroupList m_armor_groups; ItemGroupList m_armor_groups;
bool m_armor_groups_sent; bool m_armor_groups_sent;
ServerActiveObject *m_parent;
bool m_properties_sent; bool m_properties_sent;
struct ObjectProperties m_prop; struct ObjectProperties m_prop;
// Cached privileges for enforcement // Cached privileges for enforcement
std::set<std::string> m_privs; std::set<std::string> m_privs;
bool m_is_singleplayer; 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: public:
// Some flags used by Server // Some flags used by Server
bool m_teleported; bool m_teleported;