Add support for client side movement/acceleration end prediction
authorsapier <Sapier at GMX dot net>
Tue, 15 Jul 2014 18:23:14 +0000 (20:23 +0200)
committerZefram <zefram@fysh.org>
Fri, 8 Aug 2014 23:37:03 +0000 (00:37 +0100)
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

index 3d8038f877e111d28200dfb681b0d9db854de6aa..19269ebf54cc7289f2dc4994f84ff03db3210a0c 100644 (file)
@@ -1898,9 +1898,11 @@ methods:
   ^ rotation = {x=num, y=num, z=num}
 - set_properties(object property table)
 LuaEntitySAO-only: (no-op for other objects)
-- setvelocity({x=num, y=num, z=num})
+- setvelocity({x=num, y=num, z=num}, time, {x=num, y=num, z=num})
+  ^ velocity to set, time to apply this velocity (optional), value after time passed(optional)
 - getvelocity() -> {x=num, y=num, z=num}
-- setacceleration({x=num, y=num, z=num})
+- setacceleration({x=num, y=num, z=num}, time, {x=num, y=num, z=num})
+^ acceleration to set, time to apply this acceleration (optional), value after time passed(optional)
 - getacceleration() -> {x=num, y=num, z=num}
 - setyaw(radians)
 - getyaw() -> radians
index 02622f5b48b113754be2bb9225fe12bb934c3968..66aec2228616e8add22fe950e14935be42d31ddd 100644 (file)
@@ -737,7 +737,7 @@ ClientActiveObject* GenericCAO::getParent()
 void GenericCAO::removeFromScene(bool permanent)
 {
        // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
-       if((m_env != NULL) && (permanent)) 
+       if((m_env != NULL) && (permanent))
        {
                for(std::vector<u16>::iterator ci = m_children.begin();
                                                ci != m_children.end(); ci++)
@@ -1165,6 +1165,14 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
        } else {
                v3f lastpos = pos_translator.vect_show;
 
+               if ((m_vel_time_left > 0) && ((m_vel_time_left - dtime) < 0)) {
+                       m_velocity = m_vel_reset_value;
+               }
+
+               if ((m_accel_time_left > 0) && ((m_accel_time_left - dtime) < 0)) {
+                       m_acceleration = m_accel_reset_value;
+               }
+
                if(m_prop.physical)
                {
                        core::aabbox3d<f32> box = m_prop.collisionbox;
@@ -1214,6 +1222,14 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                }
        }
 
+       if (m_accel_time_left > 0) {
+               m_accel_time_left -= dtime;
+       }
+
+       if (m_vel_time_left > 0) {
+               m_vel_time_left -= dtime;
+       }
+
        m_anim_timer += dtime;
        if(m_anim_timer >= m_anim_framelength)
        {
@@ -1723,6 +1739,16 @@ void GenericCAO::processMessage(const std::string &data)
                } else {
                        pos_translator.init(m_position);
                }
+
+               // read more detailed movement information available from new servers only
+               try {
+                       m_accel_time_left = readF1000(is);
+                       m_accel_reset_value = readV3F1000(is);
+                       m_vel_time_left = readF1000(is);
+                       m_vel_reset_value = readV3F1000(is);
+               }
+               catch(SerializationError &e) {}
+
                updateNodePos();
        }
        else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) {
index bf1ac5b3fa02db8d7e03d8a78bb6ae2d1468ad63..b99676e022260f870a3f50a74f5cb2759d27160b 100644 (file)
@@ -102,6 +102,11 @@ private:
        u8 m_last_light;
        bool m_is_visible;
 
+       float m_accel_time_left;
+       float m_vel_time_left;
+       v3f m_accel_reset_value;
+       v3f m_vel_reset_value;
+
        std::vector<u16> m_children;
 
 public:
index 4ee92f4d34255408e83f1159cfadb73f359fb26b..a93ca43abcc757a4ba6e1a86cea555ab27f5eaed 100644 (file)
@@ -379,6 +379,10 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
        m_last_sent_position_timer(0),
        m_last_sent_move_precision(0),
        m_armor_groups_sent(false),
+       m_accel_time_left(-1),
+       m_accel_reset_value(v3f(0,0,0)),
+       m_vel_time_left(-1),
+       m_vel_reset_value(v3f(0,0,0)),
        m_animation_speed(0),
        m_animation_blend(0),
        m_animation_sent(false),
@@ -527,12 +531,29 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
                        m_velocity += dtime * m_acceleration;
                }
 
+
+               if ((m_vel_time_left > 0) && ((m_vel_time_left - dtime) < 0)) {
+                       m_velocity = m_vel_reset_value;
+               }
+
+               if ((m_accel_time_left > 0) && ((m_accel_time_left - dtime) < 0)) {
+                       m_acceleration = m_accel_reset_value;
+               }
+
                if((m_prop.automatic_face_movement_dir) &&
                                (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)){
                        m_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI + m_prop.automatic_face_movement_dir_offset;
                }
        }
 
+       if (m_accel_time_left > 0) {
+               m_accel_time_left -= dtime;
+       }
+
+       if (m_vel_time_left > 0) {
+               m_vel_time_left -= dtime;
+       }
+
        if(m_registered){
                m_env->getScriptIface()->luaentity_Step(m_id, dtime);
        }
@@ -670,7 +691,7 @@ int LuaEntitySAO::punch(v3f dir,
                return 0;
        }
 
-       // It's best that attachments cannot be punched 
+       // It's best that attachments cannot be punched
        if(isAttached())
                return 0;
        
@@ -819,9 +840,12 @@ void LuaEntitySAO::notifyObjectPropertiesModified()
        m_properties_sent = false;
 }
 
-void LuaEntitySAO::setVelocity(v3f velocity)
+void LuaEntitySAO::setVelocity(v3f velocity, float application_time,
+               v3f reset_value)
 {
        m_velocity = velocity;
+       m_vel_time_left = application_time;
+       m_vel_reset_value = reset_value;
 }
 
 v3f LuaEntitySAO::getVelocity()
@@ -829,9 +853,12 @@ v3f LuaEntitySAO::getVelocity()
        return m_velocity;
 }
 
-void LuaEntitySAO::setAcceleration(v3f acceleration)
+void LuaEntitySAO::setAcceleration(v3f acceleration, float application_time,
+               v3f reset_value)
 {
        m_acceleration = acceleration;
+       m_accel_time_left = application_time;
+       m_accel_reset_value = reset_value;
 }
 
 v3f LuaEntitySAO::getAcceleration()
@@ -904,7 +931,11 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
                m_yaw,
                do_interpolate,
                is_movement_end,
-               update_interval
+               update_interval,
+               m_accel_time_left,
+               m_accel_reset_value,
+               m_vel_time_left,
+               m_vel_reset_value
        );
        // create message and add to list
        ActiveObjectMessage aom(getId(), false, str);
@@ -1276,7 +1307,7 @@ int PlayerSAO::punch(v3f dir,
        ServerActiveObject *puncher,
        float time_from_last_punch)
 {
-       // It's best that attachments cannot be punched 
+       // It's best that attachments cannot be punched
        if(isAttached())
                return 0;
 
index 63e8ef4601f3234a3c0170d67acac704dfa74337..b99a3a967f878f78856fa63263df40a51e85c4b4 100644 (file)
@@ -68,9 +68,9 @@ public:
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
        /* LuaEntitySAO-specific */
-       void setVelocity(v3f velocity);
+       void setVelocity(v3f velocity, float application_time, v3f reset_value);
        v3f getVelocity();
-       void setAcceleration(v3f acceleration);
+       void setAcceleration(v3f acceleration, float application_time, v3f reset_value);
        v3f getAcceleration();
        void setYaw(float yaw);
        float getYaw();
@@ -103,6 +103,12 @@ private:
        float m_last_sent_move_precision;
        bool m_armor_groups_sent;
 
+
+       float m_accel_time_left;
+       v3f m_accel_reset_value;
+       float m_vel_time_left;
+       v3f m_vel_reset_value;
+
        v2f m_animation_range;
        float m_animation_speed;
        float m_animation_blend;
index 9a1b9d8d0dc657b109220b3d2a2d5877cce5277d..9e339d9436051a453d9426ca60190911ef3e689e 100644 (file)
@@ -43,7 +43,11 @@ std::string gob_cmd_update_position(
        f32 yaw,
        bool do_interpolate,
        bool is_movement_end,
-       f32 update_interval
+       f32 update_interval,
+       float accel_time_left,
+       v3f accel_reset_value,
+       float m_vel_time_left,
+       v3f vel_reset_value
 ){
        std::ostringstream os(std::ios::binary);
        // command
@@ -62,13 +66,20 @@ std::string gob_cmd_update_position(
        writeU8(os, is_movement_end);
        // update_interval (for interpolation)
        writeF1000(os, update_interval);
+       // update automatic acceleration disable values
+       writeF1000(os, accel_time_left);
+       writeV3F1000(os, accel_reset_value);
+       // update automatic velocity disable values
+       writeF1000(os, m_vel_time_left);
+       writeV3F1000(os, vel_reset_value);
+
        return os.str();
 }
 
 std::string gob_cmd_set_texture_mod(const std::string &mod)
 {
        std::ostringstream os(std::ios::binary);
-       // command 
+       // command
        writeU8(os, GENERIC_CMD_SET_TEXTURE_MOD);
        // parameters
        os<<serializeString(mod);
@@ -95,7 +106,7 @@ std::string gob_cmd_set_sprite(
 std::string gob_cmd_punched(s16 damage, s16 result_hp)
 {
        std::ostringstream os(std::ios::binary);
-       // command 
+       // command
        writeU8(os, GENERIC_CMD_PUNCHED);
        // damage
        writeS16(os, damage);
@@ -121,7 +132,7 @@ std::string gob_cmd_update_physics_override(float physics_override_speed, float
                float physics_override_gravity, bool sneak, bool sneak_glitch)
 {
        std::ostringstream os(std::ios::binary);
-       // command 
+       // command
        writeU8(os, GENERIC_CMD_SET_PHYSICS_OVERRIDE);
        // parameters
        writeF1000(os, physics_override_speed);
@@ -136,7 +147,7 @@ std::string gob_cmd_update_physics_override(float physics_override_speed, float
 std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend)
 {
        std::ostringstream os(std::ios::binary);
-       // command 
+       // command
        writeU8(os, GENERIC_CMD_SET_ANIMATION);
        // parameters
        writeV2F1000(os, frames);
@@ -148,7 +159,7 @@ std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_
 std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation)
 {
        std::ostringstream os(std::ios::binary);
-       // command 
+       // command
        writeU8(os, GENERIC_CMD_SET_BONE_POSITION);
        // parameters
        os<<serializeString(bone);
@@ -160,7 +171,7 @@ std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rot
 std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f position, v3f rotation)
 {
        std::ostringstream os(std::ios::binary);
-       // command 
+       // command
        writeU8(os, GENERIC_CMD_SET_ATTACHMENT);
        // parameters
        writeS16(os, parent_id);
index 29e5e29cb67481fc30846d6649bda20581eeb83d..b9cb38365c305713e693d79cb0e2edbb2133e261 100644 (file)
@@ -46,7 +46,11 @@ std::string gob_cmd_update_position(
        f32 yaw,
        bool do_interpolate,
        bool is_movement_end,
-       f32 update_interval
+       f32 update_interval,
+       float accel_time_left = -1,
+       v3f accel_reset_value = v3f(0,0,0),
+       float m_vel_time_left = -1,
+       v3f vel_reset_value = v3f(0,0,0)
 );
 
 std::string gob_cmd_set_texture_mod(const std::string &mod);
index a556439dca36c8e2d1e4a035b2f538752d13d848..cd1c8de3b58c25ea927affc084102b040b610bf5 100644 (file)
@@ -543,8 +543,17 @@ int ObjectRef::l_setvelocity(lua_State *L)
        LuaEntitySAO *co = getluaobject(ref);
        if(co == NULL) return 0;
        v3f pos = checkFloatPos(L, 2);
+       float application_time = -1;
+       v3f reset_value = v3f(0,0,0);
+
+       if(!lua_isnoneornil(L, 3))
+               application_time = lua_tonumber(L, 3);
+
+       if(!lua_isnoneornil(L, 4))
+               reset_value = checkFloatPos(L, 4);
+
        // Do it
-       co->setVelocity(pos);
+       co->setVelocity(pos, application_time, reset_value);
        return 0;
 }
 
@@ -570,8 +579,17 @@ int ObjectRef::l_setacceleration(lua_State *L)
        if(co == NULL) return 0;
        // pos
        v3f pos = checkFloatPos(L, 2);
+       float application_time = -1;
+       v3f reset_value = v3f(0,0,0);
+
+       if(!lua_isnoneornil(L, 3))
+               application_time = lua_tonumber(L, 3);
+
+       if(!lua_isnoneornil(L, 4))
+               reset_value = checkFloatPos(L, 4);
+
        // Do it
-       co->setAcceleration(pos);
+       co->setAcceleration(pos, application_time, reset_value);
        return 0;
 }