Get the new animation framework properly working
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Fri, 26 Oct 2012 15:03:24 +0000 (18:03 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 25 Nov 2012 16:14:15 +0000 (18:14 +0200)
Store start and end frames as v2f

Also move bone animations to their own function instead of object properties

doc/lua_api.txt
src/content_cao.cpp
src/content_sao.cpp
src/content_sao.h
src/genericobject.cpp
src/genericobject.h
src/object_properties.cpp
src/object_properties.h
src/scriptapi.cpp
src/serverobject.h

index 5515669d82eacdd9387fb2e2a845c9f4f2057633..c99e8035a471a707bf27d77021b5bbfd5eb57faf 100644 (file)
@@ -1103,6 +1103,8 @@ methods:
 - get_wielded_item() -> ItemStack
 - set_wielded_item(item): replaces the wielded item, returns true if successful
 - set_armor_groups({group1=rating, group2=rating, ...})
+- set_animations({x=1,y=1}, frame_speed=15, frame_blend=0)
+- set_bone_posrot("", {x=0,y=0,z=0}, {x=0,y=0,z=0})
 - set_properties(object property table)
 LuaEntitySAO-only: (no-op for other objects)
 - setvelocity({x=num, y=num, z=num})
@@ -1116,7 +1118,6 @@ LuaEntitySAO-only: (no-op for other objects)
 -           select_horiz_by_yawpitch=false)
   ^ Select sprite from spritesheet with optional animation and DM-style
     texture selection based on yaw relative to camera
-- setanimations(frame_start, frame_end, frame_speed, frame_blend)
 - get_entity_name() (DEPRECATED: Will be removed in a future version)
 - get_luaentity()
 Player-only: (no-op for other objects)
index 1cd3926caeaecd1d2d2d534cdd746f0c5b92f304..b12bfe1c858a0bf0ee3d6c5854d2de2755823d54 100644 (file)
@@ -576,6 +576,10 @@ private:
        v2s16 m_tx_basepos;
        bool m_initial_tx_basepos_set;
        bool m_tx_select_horiz_by_yawpitch;
+       v2f m_frames;
+       int m_frame_speed;
+       int m_frame_blend;
+       std::map<std::string, core::vector2d<v3f> > m_bone_posrot;
        int m_anim_frame;
        int m_anim_num_frames;
        float m_anim_framelength;
@@ -924,6 +928,8 @@ public:
                        m_visuals_expired = false;
                        removeFromScene();
                        addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
+                       updateAnimations();
+                       updateBonePosRot();
                }
 
                if(m_prop.physical){
@@ -1136,32 +1142,27 @@ public:
                }
        }
 
-       void updateAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend)
+       void updateAnimations()
        {
                if(!m_animated_meshnode)
                        return;
 
-               m_animated_meshnode->setFrameLoop(frame_start, frame_end);
-               m_animated_meshnode->setAnimationSpeed(frame_speed);
-               m_animated_meshnode->setTransitionTime(frame_blend);
+               m_animated_meshnode->setFrameLoop((int)m_frames.X, (int)m_frames.Y);
+               m_animated_meshnode->setAnimationSpeed(m_frame_speed);
+               m_animated_meshnode->setTransitionTime(m_frame_blend);
+       }
 
-               if(m_prop.animation_bone_position.size() > 0)
+       void updateBonePosRot()
+       {
+               if(m_bone_posrot.size() > 0)
                {
-                       for(std::map<std::string, v3f>::const_iterator ii = m_prop.animation_bone_position.begin(); ii != m_prop.animation_bone_position.end(); ++ii){
-                               m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
+                       m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
+                       for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_posrot.begin(); ii != m_bone_posrot.end(); ++ii){
                                std::string bone_name = (*ii).first;
-                               v3f bone_pos = (*ii).second;
+                               v3f bone_pos = (*ii).second.X;
+                               v3f bone_rot = (*ii).second.Y;
                                irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
                                bone->setPosition(bone_pos);
-                       }
-               }
-               if(m_prop.animation_bone_rotation.size() > 0)
-               {
-                       for(std::map<std::string, v3f>::const_iterator ii = m_prop.animation_bone_rotation.begin(); ii != m_prop.animation_bone_rotation.end(); ++ii){
-                               m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
-                               std::string bone_name = (*ii).first;
-                               v3f bone_rot = (*ii).second;
-                               irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
                                bone->setRotation(bone_rot);
                        }
                }
@@ -1236,12 +1237,22 @@ public:
                }
                else if(cmd == GENERIC_CMD_SET_ANIMATIONS)
                {
-                       int frame_start = readU16(is);
-                       int frame_end = readU16(is);
-                       float frame_speed = readF1000(is);
-                       float frame_blend = readF1000(is);
+                       m_frames = readV2F1000(is);
+                       m_frame_speed = readF1000(is);
+                       m_frame_blend = readF1000(is);
+
+                       updateAnimations();
+                       expireVisuals();
+               }
+               else if(cmd == GENERIC_CMD_SET_BONE_POSROT)
+               {
+                       std::string bone = deSerializeString(is);
+                       v3f position = readV3F1000(is);
+                       v3f rotation = readV3F1000(is);
+                       m_bone_posrot[bone] = core::vector2d<v3f>(position, rotation);
 
-                       updateAnimations(frame_start, frame_end, frame_speed, frame_blend);
+                       updateBonePosRot();
+                       expireVisuals();
                }
                else if(cmd == GENERIC_CMD_PUNCHED)
                {
index 9aeb88e71bda027dcf7196e8715e6c0cc318fea4..bb38fa10ec7a7e8bda49faf11c807d3e691a8bae 100644 (file)
@@ -644,6 +644,22 @@ void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
        m_armor_groups_sent = false;
 }
 
+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);
+}
+
+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);
+}
+
 ObjectProperties* LuaEntitySAO::accessObjectProperties()
 {
        return &m_prop;
@@ -706,14 +722,6 @@ void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
        m_messages_out.push_back(aom);
 }
 
-void LuaEntitySAO::setAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend)
-{
-       std::string str = gob_cmd_set_animations(frame_start, frame_end, frame_speed, frame_blend);
-       // create message and add to list
-       ActiveObjectMessage aom(getId(), true, str);
-       m_messages_out.push_back(aom);
-}
-
 std::string LuaEntitySAO::getName()
 {
        return m_init_name;
@@ -1085,6 +1093,22 @@ void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
        m_armor_groups_sent = false;
 }
 
+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);
+}
+
+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);
+}
+
 ObjectProperties* PlayerSAO::accessObjectProperties()
 {
        return &m_prop;
index 1cbf492b1fccefe354d0a1a0b2731cbb30361d6d..cba2729aea7bbfb392fdc577f73300ef9be627a3 100644 (file)
@@ -61,6 +61,8 @@ public:
        void setHP(s16 hp);
        s16 getHP() const;
        void setArmorGroups(const ItemGroupList &armor_groups);
+       void setAnimations(v2f frames, float frame_speed, float frame_blend);
+       void setBonePosRot(std::string bone, v3f position, v3f rotation);
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
        /* LuaEntitySAO-specific */
@@ -73,7 +75,6 @@ public:
        void setTextureMod(const std::string &mod);
        void setSprite(v2s16 p, int num_frames, float framelength,
                        bool select_horiz_by_yawpitch);
-       void setAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend);
        std::string getName();
 private:
        std::string getPropertyPacket();
@@ -143,6 +144,8 @@ public:
        void setHP(s16 hp);
        
        void setArmorGroups(const ItemGroupList &armor_groups);
+       void setAnimations(v2f frames, float frame_speed, float frame_blend);
+       void setBonePosRot(std::string bone, v3f position, v3f rotation);
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
 
index 0914a13c55a64787992503cdd5f6c2bd9d43a3d2..d915d78a548c55b12a43a07a1c87e6023b41fae1 100644 (file)
@@ -92,19 +92,30 @@ std::string gob_cmd_set_sprite(
        return os.str();
 }
 
-std::string gob_cmd_set_animations(int frame_start, int frame_end, float frame_speed, float frame_blend)
+std::string gob_cmd_set_animations(v2f frames, float frame_speed, float frame_blend)
 {
        std::ostringstream os(std::ios::binary);
        // command 
        writeU8(os, GENERIC_CMD_SET_ANIMATIONS);
        // parameters
-       writeU16(os, frame_start);
-       writeU16(os, frame_end);
+       writeV2F1000(os, frames);
        writeF1000(os, frame_speed);
        writeF1000(os, frame_blend);
        return os.str();
 }
 
+std::string gob_cmd_set_bone_posrot(std::string bone, v3f position, v3f rotation)
+{
+       std::ostringstream os(std::ios::binary);
+       // command 
+       writeU8(os, GENERIC_CMD_SET_BONE_POSROT);
+       // parameters
+       os<<serializeString(bone);
+       writeV3F1000(os, position);
+       writeV3F1000(os, rotation);
+       return os.str();
+}
+
 std::string gob_cmd_punched(s16 damage, s16 result_hp)
 {
        std::ostringstream os(std::ios::binary);
index c57cce8ba613d69127ffc8649d2fd1c5e6c90865..7e3e9d96f766835faf9e446113c116f3dfde0dfb 100644 (file)
@@ -29,8 +29,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define GENERIC_CMD_SET_TEXTURE_MOD 2
 #define GENERIC_CMD_SET_SPRITE 3
 #define GENERIC_CMD_SET_ANIMATIONS 4
-#define GENERIC_CMD_PUNCHED 5
-#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 6
+#define GENERIC_CMD_SET_BONE_POSROT 5
+#define GENERIC_CMD_PUNCHED 6
+#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 7
 
 #include "object_properties.h"
 std::string gob_cmd_set_properties(const ObjectProperties &prop);
@@ -55,7 +56,9 @@ std::string gob_cmd_set_sprite(
        bool select_horiz_by_yawpitch
 );
 
-std::string gob_cmd_set_animations(int frame_start, int frame_end, float frame_speed, float frame_blend);
+std::string gob_cmd_set_animations(v2f frames, float frame_speed, float frame_blend);
+
+std::string gob_cmd_set_bone_posrot(std::string bone, v3f position, v3f rotation);
 
 std::string gob_cmd_punched(s16 damage, s16 result_hp);
 
index 6b98356ac0ba1dd95650257f84855f1b62001a18..57e255f583f0b584d76960caaffd84674ac6cc53 100644 (file)
@@ -39,8 +39,6 @@ ObjectProperties::ObjectProperties():
        makes_footstep_sound(false),
        automatic_rotate(0)
 {
-       // Nothing to do for animation_bone_position
-       // Nothing to do for animation_bone_rotation
        textures.push_back("unknown_object.png");
 }
 
@@ -54,22 +52,6 @@ std::string ObjectProperties::dump()
        os<<", visual="<<visual;
        os<<", mesh="<<mesh;
        os<<", visual_size="<<PP2(visual_size);
-
-       os<<", animation_bone_position=[";
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){
-               std::string bone_name = (*ii).first;
-               v3f bone_pos = (*ii).second;
-               os<<bone_name<<" "<<bone_pos.X<<","<<bone_pos.Y<<","<<bone_pos.Z<<"\"";
-       }
-       os<<"]";
-       os<<", animation_bone_rotation=[";
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_rotation.begin(); ii != animation_bone_rotation.end(); ++ii){
-               std::string bone_name = (*ii).first;
-               v3f bone_rot = (*ii).second;
-               os<<bone_name<<" "<<bone_rot.X<<","<<bone_rot.Y<<","<<bone_rot.Z<<"\"";
-       }
-       os<<"]";
-
        os<<", textures=[";
        for(u32 i=0; i<textures.size(); i++){
                os<<"\""<<textures[i]<<"\" ";
@@ -93,24 +75,11 @@ void ObjectProperties::serialize(std::ostream &os) const
        writeV3F1000(os, collisionbox.MaxEdge);
        os<<serializeString(visual);
        os<<serializeString(mesh);
-
-       writeU16(os, animation_bone_position.size());
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){
-               os<<serializeString((*ii).first);
-               writeV3F1000(os, (*ii).second);
-       }
-       writeU16(os, animation_bone_rotation.size());
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_rotation.begin(); ii != animation_bone_rotation.end(); ++ii){
-               os<<serializeString((*ii).first);
-               writeV3F1000(os, (*ii).second);
-       }
-
        writeV2F1000(os, visual_size);
        writeU16(os, textures.size());
        for(u32 i=0; i<textures.size(); i++){
                os<<serializeString(textures[i]);
        }
-
        writeV2S16(os, spritediv);
        writeV2S16(os, initial_sprite_basepos);
        writeU8(os, is_visible);
@@ -130,27 +99,12 @@ void ObjectProperties::deSerialize(std::istream &is)
        collisionbox.MaxEdge = readV3F1000(is);
        visual = deSerializeString(is);
        mesh = deSerializeString(is);
-
-       u32 animation_bone_position_count = readU16(is);
-       for(u32 i=0; i<animation_bone_position_count; i++){
-               std::string bone_name = deSerializeString(is);
-               v3f bone_pos = readV3F1000(is);
-               animation_bone_position[bone_name] = bone_pos;
-       }
-       u32 animation_bone_rotation_count = readU16(is);
-       for(u32 i=0; i<animation_bone_rotation_count; i++){
-               std::string bone_name = deSerializeString(is);
-               v3f bone_rot = readV3F1000(is);
-               animation_bone_rotation[bone_name] = bone_rot;
-       }
-
        visual_size = readV2F1000(is);
        textures.clear();
        u32 texture_count = readU16(is);
        for(u32 i=0; i<texture_count; i++){
                textures.push_back(deSerializeString(is));
        }
-
        spritediv = readV2S16(is);
        initial_sprite_basepos = readV2S16(is);
        is_visible = readU8(is);
index 719b022ca2deda5e73635a3dedc1d3aa718610e7..53d482904680b814758c00b4e1e01aedf4870762 100644 (file)
@@ -34,8 +34,6 @@ struct ObjectProperties
        core::aabbox3d<f32> collisionbox;
        std::string visual;
        std::string mesh;
-       std::map<std::string, v3f> animation_bone_position;
-       std::map<std::string, v3f> animation_bone_rotation;
        v2f visual_size;
        core::array<std::string> textures;
        v2s16 spritediv;
index 32fb6e9bd66e31066925f531287c2e1644efb9b2..3e187d2f627e53aaa19e2be3f52c11084a3c720d 100644 (file)
@@ -944,30 +944,6 @@ static void read_object_properties(lua_State *L, int index,
                prop->visual_size = read_v2f(L, -1);
        lua_pop(L, 1);
 
-       lua_getfield(L, -1, "animation_bone_position");
-       if(lua_istable(L, -1))
-       {
-               lua_rawgeti (L, -1, 1);
-               lua_rawgeti (L, -2, 2);
-               std::string bone_name = lua_tostring(L, -2);
-               v3f bone_pos = read_v3f(L, -1);
-               prop->animation_bone_position[bone_name] = bone_pos;
-               lua_pop(L, 2);
-       }
-       lua_pop(L, 1);
-
-       lua_getfield(L, -1, "animation_bone_rotation");
-       if(lua_istable(L, -1))
-       {
-               lua_rawgeti (L, -1, 1);
-               lua_rawgeti (L, -2, 2);
-               std::string bone_name = lua_tostring(L, -2);
-               v3f bone_rot = read_v3f(L, -1);
-               prop->animation_bone_rotation[bone_name] = bone_rot;
-               lua_pop(L, 2);
-       }
-       lua_pop(L, 1);
-
        lua_getfield(L, -1, "textures");
        if(lua_istable(L, -1)){
                prop->textures.clear();
@@ -2723,6 +2699,48 @@ private:
                return 0;
        }
 
+       // setanimations(self, frames, frame_speed, frame_blend)
+       static int l_set_animations(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerActiveObject *co = getobject(ref);
+               if(co == NULL) return 0;
+               // Do it
+
+               v2f frames = v2f(1, 1);
+               if(!lua_isnil(L, 2))
+                       frames = read_v2f(L, 2);
+               float frame_speed = 15;
+               if(!lua_isnil(L, 3))
+                       frame_speed = lua_tonumber(L, 3);
+               float frame_blend = 0;
+               if(!lua_isnil(L, 4))
+                       frame_blend = lua_tonumber(L, 4);
+               co->setAnimations(frames, frame_speed, frame_blend);
+               return 0;
+       }
+
+       // setboneposrot(std::string bone, v3f position, v3f rotation)
+       static int l_set_bone_posrot(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerActiveObject *co = getobject(ref);
+               if(co == NULL) return 0;
+               // Do it
+
+               std::string bone = "";
+               if(!lua_isnil(L, 2))
+                       bone = lua_tostring(L, 2);
+               v3f position = v3f(0, 0, 0);
+               if(!lua_isnil(L, 3))
+                       position = read_v3f(L, 3);
+               v3f rotation = v3f(0, 0, 0);
+               if(!lua_isnil(L, 4))
+                       rotation = read_v3f(L, 4);
+               co->setBonePosRot(bone, position, rotation);
+               return 0;
+       }
+
        // set_properties(self, properties)
        static int l_set_properties(lua_State *L)
        {
@@ -2848,30 +2866,6 @@ private:
                return 0;
        }
 
-       // setanimations(self, mod)
-       static int l_setanimations(lua_State *L)
-       {
-               ObjectRef *ref = checkobject(L, 1);
-               LuaEntitySAO *co = getluaobject(ref);
-               if(co == NULL) return 0;
-               // Do it
-               v2s16 p(0,0);
-               int frame_start = 0;
-               if(!lua_isnil(L, 2))
-                       frame_start = lua_tonumber(L, 2);
-               int frame_end = 0;
-               if(!lua_isnil(L, 3))
-                       frame_end = lua_tonumber(L, 3);
-               float frame_speed = 15;
-               if(!lua_isnil(L, 4))
-                       frame_speed = lua_tonumber(L, 4);
-               float frame_blend = 0;
-               if(!lua_isnil(L, 5))
-                       frame_blend = lua_tonumber(L, 5);
-               co->setAnimations(frame_start, frame_end, frame_speed, frame_blend);
-               return 0;
-       }
-
        // DEPRECATED
        // get_entity_name(self)
        static int l_get_entity_name(lua_State *L)
@@ -3061,6 +3055,8 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, get_wielded_item),
        method(ObjectRef, set_wielded_item),
        method(ObjectRef, set_armor_groups),
+       method(ObjectRef, set_animations),
+       method(ObjectRef, set_bone_posrot),
        method(ObjectRef, set_properties),
        // LuaEntitySAO-only
        method(ObjectRef, setvelocity),
@@ -3071,7 +3067,6 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, getyaw),
        method(ObjectRef, settexturemod),
        method(ObjectRef, setsprite),
-       method(ObjectRef, setanimations),
        method(ObjectRef, get_entity_name),
        method(ObjectRef, get_luaentity),
        // Player-only
index ece53fd98f278e1255c20d2c053ad575a5de7130..61991bedf5944100b40257bb1b858e2dbbf448bd 100644 (file)
@@ -152,6 +152,10 @@ public:
 
        virtual void setArmorGroups(const ItemGroupList &armor_groups)
        {}
+       virtual void setAnimations(v2f frames, float frame_speed, float frame_blend)
+       {}
+       virtual void setBonePosRot(std::string bone, v3f position, v3f rotation)
+       {}
        virtual ObjectProperties* accessObjectProperties()
        { return NULL; }
        virtual void notifyObjectPropertiesModified()