Joint positioning and rotation code, and fix a problem related to their lua API
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Fri, 26 Oct 2012 08:46:46 +0000 (11:46 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 25 Nov 2012 16:14:15 +0000 (18:14 +0200)
Attempt to move the animation system to a more correct implementation, rather than using object properties. Incomplete and breaks functionality

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

index 2b2b6c6f152941ed210c2ba347b3fbebc70ae1d5..5515669d82eacdd9387fb2e2a845c9f4f2057633 100644 (file)
@@ -1116,6 +1116,7 @@ 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)
@@ -1230,9 +1231,6 @@ Object Properties
     visual = "cube"/"sprite"/"upright_sprite"/"mesh",
     visual_size = {x=1, y=1},
     mesh = "model",
-    animation_frames = {1, 1},
-    animation_speed = 15,
-    animation_blend = 0,
     animation_bone_position = {"", {x=0, y=0, z=0}}, -- bone name followed by position vector
     animation_bone_rotation = {"", {x=0, y=0, z=0}}, -- bone name followed by rotation vector
     textures = {}, -- number of required textures depends on visual
index 4df238b249c551ced6bf3a38cf7137b4d8581895..1cd3926caeaecd1d2d2d534cdd746f0c5b92f304 100644 (file)
@@ -924,7 +924,6 @@ public:
                        m_visuals_expired = false;
                        removeFromScene();
                        addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
-                       updateAnimations();
                }
 
                if(m_prop.physical){
@@ -1137,22 +1136,34 @@ public:
                }
        }
 
-       void updateAnimations()
+       void updateAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend)
        {
                if(!m_animated_meshnode)
                        return;
 
-               m_animated_meshnode->setFrameLoop(m_prop.animation_frames.X, m_prop.animation_frames.Y);
-               m_animated_meshnode->setAnimationSpeed(m_prop.animation_speed);
-               m_animated_meshnode->setTransitionTime(m_prop.animation_blend);
+               m_animated_meshnode->setFrameLoop(frame_start, frame_end);
+               m_animated_meshnode->setAnimationSpeed(frame_speed);
+               m_animated_meshnode->setTransitionTime(frame_blend);
 
-               for(std::map<std::string, v3f>::const_iterator ii = m_prop.animation_bone_position.begin(); ii != m_prop.animation_bone_position.end(); ++ii){
-                       if((*ii).second.X || (*ii).second.Y || (*ii).second.Z) { }
-                       // Bone positioning code will go here
+               if(m_prop.animation_bone_position.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
+                               std::string bone_name = (*ii).first;
+                               v3f bone_pos = (*ii).second;
+                               irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
+                               bone->setPosition(bone_pos);
+                       }
                }
-               for(std::map<std::string, v3f>::const_iterator ii = m_prop.animation_bone_rotation.begin(); ii != m_prop.animation_bone_rotation.end(); ++ii){
-                       if((*ii).second.X || (*ii).second.Y || (*ii).second.Z) { }
-                       // Bone rotation code will go here
+               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);
+                       }
                }
        }
 
@@ -1223,6 +1234,15 @@ public:
 
                        updateTexturePos();
                }
+               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);
+
+                       updateAnimations(frame_start, frame_end, frame_speed, frame_blend);
+               }
                else if(cmd == GENERIC_CMD_PUNCHED)
                {
                        /*s16 damage =*/ readS16(is);
index 6c2abf8f6b3a7e91f253dbed26ff7e90ae945a73..9aeb88e71bda027dcf7196e8715e6c0cc318fea4 100644 (file)
@@ -706,6 +706,14 @@ 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;
index 05c77e2cb92e861b5be28437cca61255aeb281d8..1cbf492b1fccefe354d0a1a0b2731cbb30361d6d 100644 (file)
@@ -73,6 +73,7 @@ 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();
index 4ab031b5d2035f8e2052e1d63532006e8312e2d3..0914a13c55a64787992503cdd5f6c2bd9d43a3d2 100644 (file)
@@ -92,6 +92,19 @@ 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::ostringstream os(std::ios::binary);
+       // command 
+       writeU8(os, GENERIC_CMD_SET_ANIMATIONS);
+       // parameters
+       writeU16(os, frame_start);
+       writeU16(os, frame_end);
+       writeF1000(os, frame_speed);
+       writeF1000(os, frame_blend);
+       return os.str();
+}
+
 std::string gob_cmd_punched(s16 damage, s16 result_hp)
 {
        std::ostringstream os(std::ios::binary);
index 81563c19b8a532e0104b3c266eda03e10970fb7b..c57cce8ba613d69127ffc8649d2fd1c5e6c90865 100644 (file)
@@ -28,8 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define GENERIC_CMD_UPDATE_POSITION 1
 #define GENERIC_CMD_SET_TEXTURE_MOD 2
 #define GENERIC_CMD_SET_SPRITE 3
-#define GENERIC_CMD_PUNCHED 4
-#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 5
+#define GENERIC_CMD_SET_ANIMATIONS 4
+#define GENERIC_CMD_PUNCHED 5
+#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 6
 
 #include "object_properties.h"
 std::string gob_cmd_set_properties(const ObjectProperties &prop);
@@ -54,6 +55,8 @@ 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_punched(s16 damage, s16 result_hp);
 
 #include "itemgroup.h"
index eb26db8d3f5a01fafc067dbbabc29ef05d706a74..6b98356ac0ba1dd95650257f84855f1b62001a18 100644 (file)
@@ -32,9 +32,6 @@ ObjectProperties::ObjectProperties():
        collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
        visual("sprite"),
        mesh(""),
-       animation_frames(1,1),
-       animation_speed(15),
-       animation_blend(0),
        visual_size(1,1),
        spritediv(1,1),
        initial_sprite_basepos(0,0),
@@ -42,8 +39,8 @@ ObjectProperties::ObjectProperties():
        makes_footstep_sound(false),
        automatic_rotate(0)
 {
-       animation_bone_position[""] = v3f(0,0,0);
-       animation_bone_rotation[""] = v3f(0,0,0);
+       // Nothing to do for animation_bone_position
+       // Nothing to do for animation_bone_rotation
        textures.push_back("unknown_object.png");
 }
 
@@ -56,9 +53,6 @@ std::string ObjectProperties::dump()
        os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge);
        os<<", visual="<<visual;
        os<<", mesh="<<mesh;
-       os<<", animation_frames="<<animation_frames.X<<","<<animation_frames.Y;
-       os<<", animation_speed="<<animation_speed;
-       os<<", animation_blend="<<animation_blend;
        os<<", visual_size="<<PP2(visual_size);
 
        os<<", animation_bone_position=[";
@@ -99,10 +93,6 @@ void ObjectProperties::serialize(std::ostream &os) const
        writeV3F1000(os, collisionbox.MaxEdge);
        os<<serializeString(visual);
        os<<serializeString(mesh);
-       writeF1000(os, animation_frames.X);
-       writeF1000(os, animation_frames.Y);
-       writeF1000(os, animation_speed);
-       writeF1000(os, animation_blend);
 
        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){
@@ -140,10 +130,6 @@ void ObjectProperties::deSerialize(std::istream &is)
        collisionbox.MaxEdge = readV3F1000(is);
        visual = deSerializeString(is);
        mesh = deSerializeString(is);
-       animation_frames.X = readF1000(is);
-       animation_frames.Y = readF1000(is);
-       animation_speed = readF1000(is);
-       animation_blend = readF1000(is);
 
        u32 animation_bone_position_count = readU16(is);
        for(u32 i=0; i<animation_bone_position_count; i++){
index 3ab488f92bade29b843425926888dcd5bc225753..719b022ca2deda5e73635a3dedc1d3aa718610e7 100644 (file)
@@ -34,9 +34,6 @@ struct ObjectProperties
        core::aabbox3d<f32> collisionbox;
        std::string visual;
        std::string mesh;
-       core::vector2d<int> animation_frames;
-       float animation_speed;
-       float animation_blend;
        std::map<std::string, v3f> animation_bone_position;
        std::map<std::string, v3f> animation_bone_rotation;
        v2f visual_size;
index 74de50ef8c3e4e551e5075194540ba32ec45ad65..32fb6e9bd66e31066925f531287c2e1644efb9b2 100644 (file)
@@ -944,21 +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_frames");
-       if(lua_istable(L, -1))
-       {
-               lua_rawgeti (L, -1, 1);
-               lua_rawgeti (L, -2, 2);
-               prop->animation_frames.X = lua_tonumber(L, -2);
-               prop->animation_frames.Y = lua_tonumber(L, -1);
-               lua_pop(L, 2);
-       }
-       lua_pop(L, 1);
-
-       getfloatfield(L, -1, "animation_speed", prop->animation_speed);
-
-       getfloatfield(L, -1, "animation_blend", prop->animation_blend);
-
        lua_getfield(L, -1, "animation_bone_position");
        if(lua_istable(L, -1))
        {
@@ -2863,6 +2848,30 @@ 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)
@@ -3062,6 +3071,7 @@ 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