Fix animation frame_speed and blend loosing precision due to incorrec… (#6357)
authorsapier <sapier@users.noreply.github.com>
Fri, 1 Sep 2017 09:15:12 +0000 (11:15 +0200)
committerLoïc Blot <nerzhul@users.noreply.github.com>
Fri, 1 Sep 2017 09:15:12 +0000 (11:15 +0200)
* Fix animation frame_speed and blend loosing precision due to incorrect data type
Add lua function set_animation_frame_speed to update the frame speed without resetting the animation to start

doc/lua_api.txt
src/content_cao.cpp
src/content_cao.h
src/content_sao.cpp
src/content_sao.h
src/genericobject.cpp
src/genericobject.h
src/script/lua_api/l_object.cpp
src/script/lua_api/l_object.h
src/serverobject.h

index b815d7ee37f2d79af03a778a71892aae5f72c6d2..4c0b3db2a8c52de7f0df4988489f1ebdf4816061 100644 (file)
@@ -3304,8 +3304,9 @@ This is basically a reference to a C++ `ServerActiveObject`
 * `set_wielded_item(item)`: replaces the wielded item, returns `true` if successful
 * `set_armor_groups({group1=rating, group2=rating, ...})`
 * `get_armor_groups()`: returns a table with the armor group ratings
-* `set_animation({x=1,y=1}, frame_speed=15, frame_blend=0, frame_loop=true)`
+* `set_animation({x=1,y=1}, frame_speed=15.0, frame_blend=0, frame_loop=true)`
 * `get_animation()`: returns `range`, `frame_speed`, `frame_blend` and `frame_loop`
+* `set_animation_frame_speed(frame_speed=15.0)`
 * `set_attach(parent, bone, position, rotation)`
     * `bone`: string
     * `position`: `{x=num, y=num, z=num}` (relative)
index 42f4e22a6de72a05f87ceb37cd6446a7d69f436b..7659871b691b578a7d0c0490f3952d04dc5b61dc 100644 (file)
@@ -1150,9 +1150,17 @@ void GenericCAO::updateAnimation()
 #endif
 }
 
+void GenericCAO::updateAnimationSpeed()
+{
+       if (!m_animated_meshnode)
+               return;
+        
+       m_animated_meshnode->setAnimationSpeed(m_animation_speed);
+}
+
 void GenericCAO::updateBonePosition()
 {
-       if(m_bone_position.empty() || !m_animated_meshnode)
+       if (m_bone_position.empty() || !m_animated_meshnode)
                return;
 
        m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
@@ -1351,6 +1359,9 @@ void GenericCAO::processMessage(const std::string &data)
                                        updateAnimation();
                        }
                }
+       } else if (cmd == GENERIC_CMD_SET_ANIMATION_SPEED) {
+               m_animation_speed = readF1000(is);
+               updateAnimationSpeed();
        } else if (cmd == GENERIC_CMD_SET_BONE_POSITION) {
                std::string bone = deSerializeString(is);
                v3f position = readV3F1000(is);
index 0b0e907c57ac7b8bcb060d654c0d95e16aade994..93b532aadd4083f632170d8c8c7d1cd31096a2e4 100644 (file)
@@ -83,8 +83,8 @@ private:
        bool m_initial_tx_basepos_set = false;
        bool m_tx_select_horiz_by_yawpitch = false;
        v2s32 m_animation_range;
-       int m_animation_speed = 15;
-       int m_animation_blend = 0;
+       float m_animation_speed = 15.0f;
+       float m_animation_blend = 0.0f;
        bool m_animation_loop = true;
        // stores position and rotation for each bone name
        std::unordered_map<std::string, core::vector2d<v3f>> m_bone_position;
@@ -197,6 +197,8 @@ public:
 
        void updateAnimation();
 
+       void updateAnimationSpeed();
+
        void updateBonePosition();
 
        void updateAttachments();
index c264473af4fdedb287b0628f8838529873b10dcc..ece9214726ba4d0cf5867516b71d00a655cff3a1 100644 (file)
@@ -155,6 +155,12 @@ void UnitSAO::getAnimation(v2f *frame_range, float *frame_speed, float *frame_bl
        *frame_loop = m_animation_loop;
 }
 
+void UnitSAO::setAnimationSpeed(float frame_speed)
+{
+       m_animation_speed = frame_speed;
+       m_animation_speed_sent = false;
+}
+
 void UnitSAO::setBonePosition(const std::string &bone, v3f position, v3f rotation)
 {
        // store these so they can be updated to clients
@@ -440,6 +446,14 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
                m_messages_out.push(aom);
        }
 
+       if (!m_animation_speed_sent) {
+               m_animation_speed_sent = true;
+               std::string str = gob_cmd_update_animation_speed(m_animation_speed);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, str);
+               m_messages_out.push(aom);
+       }
+
        if (!m_bone_position_sent) {
                m_bone_position_sent = true;
                for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator
index 160ac7f4381079a5e12c4c17ef3a62a30802cf58..019397d83ce75930498dcf71a1378a9c24c0bc36 100644 (file)
@@ -46,6 +46,7 @@ public:
        const ItemGroupList &getArmorGroups();
        void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop);
        void getAnimation(v2f *frame_range, float *frame_speed, float *frame_blend, bool *frame_loop);
+       void setAnimationSpeed(float frame_speed);
        void setBonePosition(const std::string &bone, v3f position, v3f rotation);
        void getBonePosition(const std::string &bone, v3f *position, v3f *rotation);
        void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation);
@@ -70,6 +71,7 @@ protected:
        float m_animation_blend = 0.0f;
        bool m_animation_loop = true;
        bool m_animation_sent = false;
+        bool m_animation_speed_sent = false;
 
        // Stores position and rotation for each bone name
        std::unordered_map<std::string, core::vector2d<v3f>> m_bone_position;
index 15977b0e034d7479e4f5a87580cecd35572a461a..d86c47eb93b565393dbc53fff49caeef7da89834 100644 (file)
@@ -147,6 +147,16 @@ std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_
        return os.str();
 }
 
+std::string gob_cmd_update_animation_speed(float frame_speed)
+{
+       std::ostringstream os(std::ios::binary);
+       // command
+       writeU8(os, GENERIC_CMD_SET_ANIMATION_SPEED);
+       // parameters
+       writeF1000(os, frame_speed);
+       return os.str();
+}
+
 std::string gob_cmd_update_bone_position(const std::string &bone, v3f position,
                v3f rotation)
 {
index 3ebc85fa36fac708b64339c1c363d8e12878dfbc..878300fbf4f63278274c7524c4ce5334d1fd5f2e 100644 (file)
@@ -36,7 +36,8 @@ enum GenericCMD {
        GENERIC_CMD_ATTACH_TO,
        GENERIC_CMD_SET_PHYSICS_OVERRIDE,
        GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES,
-       GENERIC_CMD_SPAWN_INFANT
+       GENERIC_CMD_SPAWN_INFANT,
+       GENERIC_CMD_SET_ANIMATION_SPEED
 };
 
 #include "object_properties.h"
@@ -72,6 +73,8 @@ std::string gob_cmd_update_physics_override(float physics_override_speed,
 
 std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend, bool frame_loop);
 
+std::string gob_cmd_update_animation_speed(float frame_speed);
+
 std::string gob_cmd_update_bone_position(const std::string &bone, v3f position,
                v3f rotation);
 
index 24fdeca4bfce9b955778eb4079550c24a645cade..9b312b3ee526ab32cfe841b56db22ba041d228cc 100644 (file)
@@ -604,6 +604,26 @@ int ObjectRef::l_get_eye_offset(lua_State *L)
        return 2;
 }
 
+// set_animation_frame_speed(self, frame_speed)
+int ObjectRef::l_set_animation_frame_speed(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       ObjectRef *ref = checkobject(L, 1);
+       ServerActiveObject *co = getobject(ref);
+       if (co == NULL)
+               return 0;
+
+       // Do it
+       if (!lua_isnil(L, 2)) {
+               float frame_speed = lua_tonumber(L, 2);
+               co->setAnimationSpeed(frame_speed);
+               lua_pushboolean(L, true);
+       } else {
+               lua_pushboolean(L, false);
+       }
+       return 1;
+}
+
 // set_bone_position(self, std::string bone, v3f position, v3f rotation)
 int ObjectRef::l_set_bone_position(lua_State *L)
 {
@@ -1937,6 +1957,7 @@ const luaL_Reg ObjectRef::methods[] = {
        luamethod(ObjectRef, get_armor_groups),
        luamethod(ObjectRef, set_animation),
        luamethod(ObjectRef, get_animation),
+       luamethod(ObjectRef, set_animation_frame_speed),
        luamethod(ObjectRef, set_bone_position),
        luamethod(ObjectRef, get_bone_position),
        luamethod(ObjectRef, set_attach),
index 19cc890c7d5d070044d4f2d70926965eca3a3f22..2a76d8a706c32d1929b40c11a31f5187fa3edb97 100644 (file)
@@ -126,6 +126,9 @@ private:
        // set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
        static int l_set_animation(lua_State *L);
 
+       // set_animation_frame_speed(self, frame_speed)
+       static int l_set_animation_frame_speed(lua_State *L);
+
        // get_animation(self)
        static int l_get_animation(lua_State *L);
 
index 7d87a0f59ba960bccca7989fed8a5eae70ec0602..33fc3e4a8d57377ce0120a63dc70db806ba9aeec 100644 (file)
@@ -154,6 +154,8 @@ public:
        {}
        virtual void getAnimation(v2f *frames, float *frame_speed, float *frame_blend, bool *frame_loop)
        {}
+       virtual void setAnimationSpeed(float frame_speed)
+       {}
        virtual void setBonePosition(const std::string &bone, v3f position, v3f rotation)
        {}
        virtual void getBonePosition(const std::string &bone, v3f *position, v3f *lotation)