From c359b9d086d98fff3f4998cf9f02f3ce58937702 Mon Sep 17 00:00:00 2001 From: sapier Date: Tue, 15 Jul 2014 20:23:14 +0200 Subject: [PATCH] Add support for client side movement/acceleration end prediction --- doc/lua_api.txt | 6 +++-- src/content_cao.cpp | 28 +++++++++++++++++++++- src/content_cao.h | 5 ++++ src/content_sao.cpp | 41 +++++++++++++++++++++++++++++---- src/content_sao.h | 10 ++++++-- src/genericobject.cpp | 25 ++++++++++++++------ src/genericobject.h | 6 ++++- src/script/lua_api/l_object.cpp | 22 ++++++++++++++++-- 8 files changed, 123 insertions(+), 20 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 3d8038f8..19269ebf 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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 diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 02622f5b..66aec222 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -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::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 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) { diff --git a/src/content_cao.h b/src/content_cao.h index bf1ac5b3..b99676e0 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -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 m_children; public: diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 4ee92f4d..a93ca43a 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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; diff --git a/src/content_sao.h b/src/content_sao.h index 63e8ef46..b99a3a96 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -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; diff --git a/src/genericobject.cpp b/src/genericobject.cpp index 9a1b9d8d..9e339d94 100644 --- a/src/genericobject.cpp +++ b/src/genericobject.cpp @@ -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<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; } -- 2.30.2