From: CoderForTheBetter Date: Wed, 28 Nov 2018 08:38:50 +0000 (-0500) Subject: Add Lua methods 'set_rotation()' and 'get_rotation()' (#7395) X-Git-Tag: 5.0.0~175 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=faa358e797128ab07bb5644ce305a832d59e5596;p=oweals%2Fminetest.git Add Lua methods 'set_rotation()' and 'get_rotation()' (#7395) * Adds Lua methods 'set_rotation()' and 'get_rotation'. Also changed some method names to be more clear. Instead of an f32 being sent over network for yaw, now a v3f is sent for rotation on xyz axes. Perserved Lua method set_yaw/setyaw so that old mods still work, other wise to set yaw they would need to switch to set_rotation(0, yaw, 0). --- diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 44902725d..a07356d00 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -5070,6 +5070,9 @@ This is basically a reference to a C++ `ServerActiveObject` * `set_acceleration(acc)` * `acc` is a vector * `get_acceleration()`: returns the acceleration, a vector +* `set_rotation(rot)` + * `rot` is a vector (radians) +* `get_rotation()` : returns the rotation, a vector (radians) * `set_yaw(radians)` * `get_yaw()`: returns number in radians * `set_texture_mod(mod)` diff --git a/src/clientiface.cpp b/src/clientiface.cpp index 53c3fe9cd..a55e0f7b5 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -134,8 +134,8 @@ void RemoteClient::GetNextBlocks ( // Camera position and direction v3f camera_pos = sao->getEyePosition(); v3f camera_dir = v3f(0,0,1); - camera_dir.rotateYZBy(sao->getPitch()); - camera_dir.rotateXZBy(sao->getYaw()); + camera_dir.rotateYZBy(sao->getLookPitch()); + camera_dir.rotateXZBy(sao->getRotation().Y); /*infostream<<"camera_dir=("< 180.f) + val_diff_v3f.X = 360.f - val_diff_v3f.X; + + if (val_diff_v3f.Y > 180.f) + val_diff_v3f.Y = 360.f - val_diff_v3f.Y; + + if (val_diff_v3f.Z > 180.f) + val_diff_v3f.Z = 360.f - val_diff_v3f.Z; + + f32 moveratio = 1.0; + if (anim_time > 0.001) + moveratio = anim_time_counter / anim_time; + f32 move_end = aim_is_end ? 1.0 : 1.5; + + // Move a bit less than should, to avoid oscillation + moveratio = std::min(moveratio * 0.8f, move_end); + wrappedApproachShortest(val_current.X, val_target.X, + val_diff_v3f.X * moveratio, 360.f); + + wrappedApproachShortest(val_current.Y, val_target.Y, + val_diff_v3f.Y * moveratio, 360.f); + + wrappedApproachShortest(val_current.Z, val_target.Z, + val_diff_v3f.Z * moveratio, 360.f); +} + /* Other stuff */ @@ -331,7 +366,7 @@ void GenericCAO::processInitData(const std::string &data) m_is_player = readU8(is); m_id = readU16(is); m_position = readV3F1000(is); - m_yaw = readF1000(is); + m_rotation = readV3F1000(is); m_hp = readS16(is); num_messages = readU8(is); } else { @@ -345,9 +380,9 @@ void GenericCAO::processInitData(const std::string &data) processMessage(message); } - m_yaw = wrapDegrees_0_360(m_yaw); + m_rotation = wrapDegrees_0_360_v3f(m_rotation); pos_translator.init(m_position); - yaw_translator.init(m_yaw); + rot_translator.init(m_rotation); updateNodePos(); } @@ -735,8 +770,7 @@ void GenericCAO::updateNodePos() v3s16 camera_offset = m_env->getCameraOffset(); node->setPosition(pos_translator.val_current - intToFloat(camera_offset, BS)); if (node != m_spritenode) { // rotate if not a sprite - v3f rot = node->getRotation(); - rot.Y = m_is_local_player ? -m_yaw : -yaw_translator.val_current; + v3f rot = m_is_local_player ? -m_rotation : -rot_translator.val_current; node->setRotation(rot); } } @@ -751,11 +785,11 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) int old_anim = player->last_animation; float old_anim_speed = player->last_animation_speed; m_position = player->getPosition(); - m_yaw = wrapDegrees_0_360(player->getYaw()); + m_rotation.Y = wrapDegrees_0_360(player->getYaw()); m_velocity = v3f(0,0,0); m_acceleration = v3f(0,0,0); pos_translator.val_current = m_position; - yaw_translator.val_current = m_yaw; + rot_translator.val_current = m_rotation; const PlayerControl &controls = player->getPlayerControl(); bool walking = false; @@ -867,7 +901,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) m_env->getLocalPlayer()->parent = getParent(); } } else { - yaw_translator.translate(dtime); + rot_translator.translate(dtime); v3f lastpos = pos_translator.val_current; if(m_prop.physical) @@ -938,8 +972,8 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } } if (!getParent() && std::fabs(m_prop.automatic_rotate) > 0.001) { - m_yaw += dtime * m_prop.automatic_rotate * 180 / M_PI; - yaw_translator.val_current = m_yaw; + m_rotation.Y += dtime * m_prop.automatic_rotate * 180 / M_PI; + rot_translator.val_current = m_rotation; updateNodePos(); } @@ -951,8 +985,9 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) float max_rotation_delta = dtime * m_prop.automatic_face_movement_max_rotation_per_sec; - wrappedApproachShortest(m_yaw, target_yaw, max_rotation_delta, 360.f); - yaw_translator.val_current = m_yaw; + wrappedApproachShortest(m_rotation.Y, target_yaw, max_rotation_delta, 360.f); + rot_translator.val_current = m_rotation; + updateNodePos(); } } @@ -980,7 +1015,7 @@ void GenericCAO::updateTexturePos() else { float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.; - float dir = mob_dir - m_yaw; + float dir = mob_dir - m_rotation.Y; dir = wrapDegrees_180(dir); if (std::fabs(wrapDegrees_180(dir - 0)) <= 45.1f) col += 2; @@ -1314,11 +1349,13 @@ void GenericCAO::processMessage(const std::string &data) m_position = readV3F1000(is); m_velocity = readV3F1000(is); m_acceleration = readV3F1000(is); + if (std::fabs(m_prop.automatic_rotate) < 0.001f) - m_yaw = readF1000(is); + m_rotation = readV3F1000(is); else - readF1000(is); - m_yaw = wrapDegrees_0_360(m_yaw); + readV3F1000(is); + + m_rotation = wrapDegrees_0_360_v3f(m_rotation); bool do_interpolate = readU8(is); bool is_end_position = readU8(is); float update_interval = readF1000(is); @@ -1338,7 +1375,7 @@ void GenericCAO::processMessage(const std::string &data) } else { pos_translator.init(m_position); } - yaw_translator.update(m_yaw, false, update_interval); + rot_translator.update(m_rotation, false, update_interval); updateNodePos(); } else if (cmd == GENERIC_CMD_SET_TEXTURE_MOD) { std::string mod = deSerializeString(is); diff --git a/src/content_cao.h b/src/content_cao.h index 9e688d78d..98932137e 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -59,6 +59,11 @@ struct SmoothTranslatorWrapped : SmoothTranslator void translate(f32 dtime); }; +struct SmoothTranslatorWrappedv3f : SmoothTranslator +{ + void translate(f32 dtime); +}; + class GenericCAO : public ClientActiveObject { private: @@ -80,10 +85,10 @@ private: v3f m_position = v3f(0.0f, 10.0f * BS, 0); v3f m_velocity; v3f m_acceleration; - float m_yaw = 0.0f; + v3f m_rotation; s16 m_hp = 1; SmoothTranslator pos_translator; - SmoothTranslatorWrapped yaw_translator; + SmoothTranslatorWrappedv3f rot_translator; // Spritesheet/animation stuff v2f m_tx_size = v2f(1,1); v2s16 m_tx_basepos; @@ -146,9 +151,10 @@ public: virtual bool getSelectionBox(aabb3f *toset) const; v3f getPosition(); - inline float getYaw() const + + inline const v3f &getRotation() { - return m_yaw; + return m_rotation; } const bool isImmortal(); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index f32294191..0b69e7bff 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -349,7 +349,7 @@ ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, std::string state; s16 hp = 1; v3f velocity; - float yaw = 0; + v3f rotation; if (!data.empty()) { std::istringstream is(data, std::ios::binary); // read version @@ -364,7 +364,7 @@ ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, state = deSerializeLongString(is); hp = readS16(is); velocity = readV3F1000(is); - yaw = readF1000(is); + rotation = readV3F1000(is); } } // create object @@ -373,7 +373,7 @@ ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos, LuaEntitySAO *sao = new LuaEntitySAO(env, pos, name, state); sao->m_hp = hp; sao->m_velocity = velocity; - sao->m_yaw = yaw; + sao->m_rotation = rotation; return sao; } @@ -443,8 +443,8 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) float max_rotation_delta = dtime * m_prop.automatic_face_movement_max_rotation_per_sec; - m_yaw = wrapDegrees_0_360(m_yaw); - wrappedApproachShortest(m_yaw, target_yaw, max_rotation_delta, 360.f); + m_rotation.Y = wrapDegrees_0_360(m_rotation.Y); + wrappedApproachShortest(m_rotation.Y, target_yaw, max_rotation_delta, 360.f); } } @@ -468,7 +468,10 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) move_d += m_last_sent_move_precision; float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity); if (move_d > minchange || vel_d > minchange || - std::fabs(m_yaw - m_last_sent_yaw) > 1.0) { + std::fabs(m_rotation.X - m_last_sent_rotation.X) > 1.0f || + std::fabs(m_rotation.Y - m_last_sent_rotation.Y) > 1.0f || + std::fabs(m_rotation.Z - m_last_sent_rotation.Z) > 1.0f) { + sendPosition(true, false); } } @@ -530,7 +533,7 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) writeU8(os, 0); // is_player writeS16(os, getId()); //id writeV3F1000(os, m_base_position); - writeF1000(os, m_yaw); + writeV3F1000(os, m_rotation); writeS16(os, m_hp); std::ostringstream msg_os(std::ios::binary); @@ -585,8 +588,9 @@ void LuaEntitySAO::getStaticData(std::string *result) const writeS16(os, m_hp); // velocity writeV3F1000(os, m_velocity); - // yaw - writeF1000(os, m_yaw); + // rotation + writeV3F1000(os, m_rotation); + *result = os.str(); } @@ -767,10 +771,10 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end) m_last_sent_move_precision = m_base_position.getDistanceFrom( m_last_sent_position); m_last_sent_position_timer = 0; - m_last_sent_yaw = m_yaw; m_last_sent_position = m_base_position; m_last_sent_velocity = m_velocity; //m_last_sent_acceleration = m_acceleration; + m_last_sent_rotation = m_rotation; float update_interval = m_env->getSendRecommendedInterval(); @@ -778,7 +782,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end) m_base_position, m_velocity, m_acceleration, - m_yaw, + m_rotation, do_interpolate, is_movement_end, update_interval @@ -919,9 +923,9 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeU8(os, 1); // version os << serializeString(m_player->getName()); // name writeU8(os, 1); // is_player - writeS16(os, getId()); //id + writeS16(os, getId()); // id writeV3F1000(os, m_base_position); - writeF1000(os, m_yaw); + writeV3F1000(os, m_rotation); writeS16(os, getHP()); std::ostringstream msg_os(std::ios::binary); @@ -1073,7 +1077,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) return; // If the object is attached client-side, don't waste bandwidth sending its - // position to clients. + // position or rotation to clients. if (m_position_not_sent && !isAttached()) { m_position_not_sent = false; float update_interval = m_env->getSendRecommendedInterval(); @@ -1087,7 +1091,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) pos, v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 0.0f, 0.0f), - m_yaw, + v3f(0.0f, 0.0f, 0.0f), true, false, update_interval @@ -1188,12 +1192,14 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) m_env->getGameDef()->SendMovePlayer(m_peer_id); } -void PlayerSAO::setYaw(const float yaw) +void PlayerSAO::setPlayerYaw(const float yaw) { - if (m_player && yaw != m_yaw) + v3f rotation(0, yaw, 0); + if (m_player && yaw != m_rotation.Y) m_player->setDirty(true); - UnitSAO::setYaw(yaw); + // Set player model yaw, not look view + UnitSAO::setRotation(rotation); } void PlayerSAO::setFov(const float fov) @@ -1212,13 +1218,13 @@ void PlayerSAO::setWantedRange(const s16 range) m_wanted_range = range; } -void PlayerSAO::setYawAndSend(const float yaw) +void PlayerSAO::setPlayerYawAndSend(const float yaw) { - setYaw(yaw); + setPlayerYaw(yaw); m_env->getGameDef()->SendMovePlayer(m_peer_id); } -void PlayerSAO::setPitch(const float pitch) +void PlayerSAO::setLookPitch(const float pitch) { if (m_player && pitch != m_pitch) m_player->setDirty(true); @@ -1226,9 +1232,9 @@ void PlayerSAO::setPitch(const float pitch) m_pitch = pitch; } -void PlayerSAO::setPitchAndSend(const float pitch) +void PlayerSAO::setLookPitchAndSend(const float pitch) { - setPitch(pitch); + setLookPitch(pitch); m_env->getGameDef()->SendMovePlayer(m_peer_id); } diff --git a/src/content_sao.h b/src/content_sao.h index e45a4028e..6d2f55b70 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -32,11 +32,12 @@ public: UnitSAO(ServerEnvironment *env, v3f pos); virtual ~UnitSAO() = default; - virtual void setYaw(const float yaw) { m_yaw = yaw; } - float getYaw() const { return m_yaw; }; - f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } + void setRotation(v3f rotation) { m_rotation = rotation; } + const v3f &getRotation() const { return m_rotation; } + v3f getRadRotation() { return m_rotation * core::DEGTORAD; } + // Deprecated - f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } + f32 getRadYawDep() const { return (m_rotation.Y + 90.) * core::DEGTORAD; } s16 getHP() const { return m_hp; } // Use a function, if isDead can be defined by other conditions @@ -64,7 +65,8 @@ public: void notifyObjectPropertiesModified(); protected: s16 m_hp = -1; - float m_yaw = 0.0f; + + v3f m_rotation; bool m_properties_sent = true; ObjectProperties m_prop; @@ -156,9 +158,9 @@ private: v3f m_velocity; v3f m_acceleration; - float m_last_sent_yaw = 0.0f; v3f m_last_sent_position; v3f m_last_sent_velocity; + v3f m_last_sent_rotation; float m_last_sent_position_timer = 0.0f; float m_last_sent_move_precision = 0.0f; std::string m_current_texture_modifier = ""; @@ -232,16 +234,16 @@ public: void setBasePosition(const v3f &position); void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); - void setYaw(const float yaw); + void setPlayerYaw(const float yaw); // Data should not be sent at player initialization - void setYawAndSend(const float yaw); - void setPitch(const float pitch); + void setPlayerYawAndSend(const float yaw); + void setLookPitch(const float pitch); // Data should not be sent at player initialization - void setPitchAndSend(const float pitch); - f32 getPitch() const { return m_pitch; } - f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } + void setLookPitchAndSend(const float pitch); + f32 getLookPitch() const { return m_pitch; } + f32 getRadLookPitch() const { return m_pitch * core::DEGTORAD; } // Deprecated - f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } + f32 getRadLookPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } void setFov(const float pitch); f32 getFov() const { return m_fov; } void setWantedRange(const s16 range); diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp index 64eca394e..09d76240e 100644 --- a/src/database/database-files.cpp +++ b/src/database/database-files.cpp @@ -41,8 +41,8 @@ void PlayerDatabaseFiles::serialize(std::ostringstream &os, RemotePlayer *player sanity_check(player->getPlayerSAO()); args.setS32("hp", player->getPlayerSAO()->getHP()); args.setV3F("position", player->getPlayerSAO()->getBasePosition()); - args.setFloat("pitch", player->getPlayerSAO()->getPitch()); - args.setFloat("yaw", player->getPlayerSAO()->getYaw()); + args.setFloat("pitch", player->getPlayerSAO()->getLookPitch()); + args.setFloat("yaw", player->getPlayerSAO()->getRotation().Y); args.setS32("breath", player->getPlayerSAO()->getBreath()); std::string extended_attrs; diff --git a/src/database/database-postgresql.cpp b/src/database/database-postgresql.cpp index 2d9c3b49e..eec838ef0 100644 --- a/src/database/database-postgresql.cpp +++ b/src/database/database-postgresql.cpp @@ -454,8 +454,8 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) verifyDatabase(); v3f pos = sao->getBasePosition(); - std::string pitch = ftos(sao->getPitch()); - std::string yaw = ftos(sao->getYaw()); + std::string pitch = ftos(sao->getLookPitch()); + std::string yaw = ftos(sao->getRotation().Y); std::string posx = ftos(pos.X); std::string posy = ftos(pos.Y); std::string posz = ftos(pos.Z); @@ -545,8 +545,8 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) return false; } - sao->setPitch(pg_to_float(results, 0, 0)); - sao->setYaw(pg_to_float(results, 0, 1)); + sao->setLookPitch(pg_to_float(results, 0, 0)); + sao->setRotation(v3f(0, pg_to_float(results, 0, 1), 0)); sao->setBasePosition(v3f( pg_to_float(results, 0, 2), pg_to_float(results, 0, 3), diff --git a/src/database/database-sqlite3.cpp b/src/database/database-sqlite3.cpp index 97b0fd36a..aa156bbbd 100644 --- a/src/database/database-sqlite3.cpp +++ b/src/database/database-sqlite3.cpp @@ -456,8 +456,8 @@ void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) if (!playerDataExists(player->getName())) { beginSave(); str_to_sqlite(m_stmt_player_add, 1, player->getName()); - double_to_sqlite(m_stmt_player_add, 2, sao->getPitch()); - double_to_sqlite(m_stmt_player_add, 3, sao->getYaw()); + double_to_sqlite(m_stmt_player_add, 2, sao->getLookPitch()); + double_to_sqlite(m_stmt_player_add, 3, sao->getRotation().Y); double_to_sqlite(m_stmt_player_add, 4, pos.X); double_to_sqlite(m_stmt_player_add, 5, pos.Y); double_to_sqlite(m_stmt_player_add, 6, pos.Z); @@ -468,8 +468,8 @@ void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) sqlite3_reset(m_stmt_player_add); } else { beginSave(); - double_to_sqlite(m_stmt_player_update, 1, sao->getPitch()); - double_to_sqlite(m_stmt_player_update, 2, sao->getYaw()); + double_to_sqlite(m_stmt_player_update, 1, sao->getLookPitch()); + double_to_sqlite(m_stmt_player_update, 2, sao->getRotation().Y); double_to_sqlite(m_stmt_player_update, 3, pos.X); double_to_sqlite(m_stmt_player_update, 4, pos.Y); double_to_sqlite(m_stmt_player_update, 5, pos.Z); @@ -542,8 +542,8 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao) sqlite3_reset(m_stmt_player_load); return false; } - sao->setPitch(sqlite_to_float(m_stmt_player_load, 0)); - sao->setYaw(sqlite_to_float(m_stmt_player_load, 1)); + sao->setLookPitch(sqlite_to_float(m_stmt_player_load, 0)); + sao->setPlayerYaw(sqlite_to_float(m_stmt_player_load, 1)); sao->setBasePosition(sqlite_to_v3f(m_stmt_player_load, 2)); sao->setHPRaw((s16) MYMIN(sqlite_to_int(m_stmt_player_load, 5), S16_MAX)); sao->setBreath((u16) MYMIN(sqlite_to_int(m_stmt_player_load, 6), U16_MAX), false); diff --git a/src/genericobject.cpp b/src/genericobject.cpp index d86c47eb9..ba5281093 100644 --- a/src/genericobject.cpp +++ b/src/genericobject.cpp @@ -40,7 +40,7 @@ std::string gob_cmd_update_position( v3f position, v3f velocity, v3f acceleration, - f32 yaw, + v3f rotation, bool do_interpolate, bool is_movement_end, f32 update_interval @@ -54,8 +54,8 @@ std::string gob_cmd_update_position( writeV3F1000(os, velocity); // acceleration writeV3F1000(os, acceleration); - // yaw - writeF1000(os, yaw); + // rotation + writeV3F1000(os, rotation); // do_interpolate writeU8(os, do_interpolate); // is_end_position (for interpolation) diff --git a/src/genericobject.h b/src/genericobject.h index 878300fbf..a182c65f3 100644 --- a/src/genericobject.h +++ b/src/genericobject.h @@ -48,7 +48,7 @@ std::string gob_cmd_update_position( v3f position, v3f velocity, v3f acceleration, - f32 yaw, + v3f rotation, bool do_interpolate, bool is_movement_end, f32 update_interval diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 91caee0bd..8299ad002 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -473,8 +473,8 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, playersao->setBasePosition(position); player->setSpeed(speed); - playersao->setPitch(pitch); - playersao->setYaw(yaw); + playersao->setLookPitch(pitch); + playersao->setPlayerYaw(yaw); playersao->setFov(fov); playersao->setWantedRange(wanted_range); player->keyPressed = keyPressed; diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index 3a72106de..d54caf924 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -110,10 +110,10 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, } catch (SettingNotFoundException &e) {} try { - sao->setPitch(args.getFloat("pitch")); + sao->setLookPitch(args.getFloat("pitch")); } catch (SettingNotFoundException &e) {} try { - sao->setYaw(args.getFloat("yaw")); + sao->setPlayerYaw(args.getFloat("yaw")); } catch (SettingNotFoundException &e) {} try { @@ -172,8 +172,8 @@ void RemotePlayer::serialize(std::ostream &os) assert(m_sao); args.setS32("hp", m_sao->getHP()); args.setV3F("position", m_sao->getBasePosition()); - args.setFloat("pitch", m_sao->getPitch()); - args.setFloat("yaw", m_sao->getYaw()); + args.setFloat("pitch", m_sao->getLookPitch()); + args.setFloat("yaw", m_sao->getRotation().Y); args.setS32("breath", m_sao->getBreath()); std::string extended_attrs; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 14010533e..f077d42a0 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -889,19 +889,51 @@ int ObjectRef::l_get_acceleration(lua_State *L) return 1; } +// set_rotation(self, {x=num, y=num, z=num}) +// Each 'num' is in radians +int ObjectRef::l_set_rotation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if (!co) + return 0; + + v3f rotation = check_v3f(L, 2) * core::RADTODEG; + co->setRotation(rotation); + return 0; +} + +// get_rotation(self) +// returns: {x=num, y=num, z=num} +// Each 'num' is in radians +int ObjectRef::l_get_rotation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if (!co) + return 0; + + lua_newtable(L); + v3f rotation = co->getRotation() * core::DEGTORAD; + push_v3f(L, rotation); + return 1; +} + // set_yaw(self, radians) int ObjectRef::l_set_yaw(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); LuaEntitySAO *co = getluaobject(ref); + if (co == NULL) return 0; if (isNaN(L, 2)) throw LuaError("ObjectRef::set_yaw: NaN value is not allowed."); float yaw = readParam(L, 2) * core::RADTODEG; - // Do it - co->setYaw(yaw); + co->setRotation(v3f(0, yaw, 0)); return 0; } @@ -911,9 +943,10 @@ int ObjectRef::l_get_yaw(lua_State *L) NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); LuaEntitySAO *co = getluaobject(ref); - if (co == NULL) return 0; - // Do it - float yaw = co->getYaw() * core::DEGTORAD; + if (!co) + return 0; + + float yaw = co->getRotation().Y * core::DEGTORAD; lua_pushnumber(L, yaw); return 1; } @@ -1046,7 +1079,7 @@ int ObjectRef::l_get_look_dir(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - float pitch = co->getRadPitchDep(); + float pitch = co->getRadLookPitchDep(); float yaw = co->getRadYawDep(); v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) * std::sin(yaw)); @@ -1067,7 +1100,7 @@ int ObjectRef::l_get_look_pitch(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - lua_pushnumber(L, co->getRadPitchDep()); + lua_pushnumber(L, co->getRadLookPitchDep()); return 1; } @@ -1096,7 +1129,7 @@ int ObjectRef::l_get_look_vertical(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - lua_pushnumber(L, co->getRadPitch()); + lua_pushnumber(L, co->getRadLookPitch()); return 1; } @@ -1108,7 +1141,7 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) PlayerSAO* co = getplayersao(ref); if (co == NULL) return 0; // Do it - lua_pushnumber(L, co->getRadYaw()); + lua_pushnumber(L, co->getRadRotation().Y); return 1; } @@ -1121,7 +1154,7 @@ int ObjectRef::l_set_look_vertical(lua_State *L) if (co == NULL) return 0; float pitch = readParam(L, 2) * core::RADTODEG; // Do it - co->setPitchAndSend(pitch); + co->setLookPitchAndSend(pitch); return 1; } @@ -1134,7 +1167,7 @@ int ObjectRef::l_set_look_horizontal(lua_State *L) if (co == NULL) return 0; float yaw = readParam(L, 2) * core::RADTODEG; // Do it - co->setYawAndSend(yaw); + co->setPlayerYawAndSend(yaw); return 1; } @@ -1152,7 +1185,7 @@ int ObjectRef::l_set_look_pitch(lua_State *L) if (co == NULL) return 0; float pitch = readParam(L, 2) * core::RADTODEG; // Do it - co->setPitchAndSend(pitch); + co->setLookPitchAndSend(pitch); return 1; } @@ -1170,7 +1203,7 @@ int ObjectRef::l_set_look_yaw(lua_State *L) if (co == NULL) return 0; float yaw = readParam(L, 2) * core::RADTODEG; // Do it - co->setYawAndSend(yaw); + co->setPlayerYawAndSend(yaw); return 1; } @@ -1861,6 +1894,8 @@ luaL_Reg ObjectRef::methods[] = { luamethod_aliased(ObjectRef, get_acceleration, getacceleration), luamethod_aliased(ObjectRef, set_yaw, setyaw), luamethod_aliased(ObjectRef, get_yaw, getyaw), + luamethod(ObjectRef, set_rotation), + luamethod(ObjectRef, get_rotation), luamethod_aliased(ObjectRef, set_texture_mod, settexturemod), luamethod_aliased(ObjectRef, set_sprite, setsprite), luamethod(ObjectRef, get_entity_name), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 6876ea512..c7d963d87 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -172,6 +172,12 @@ private: // get_acceleration(self) static int l_get_acceleration(lua_State *L); + // set_rotation(self, {x=num, y=num, z=num}) + static int l_set_rotation(lua_State *L); + + // get_rotation(self) + static int l_get_rotation(lua_State *L); + // set_yaw(self, radians) static int l_set_yaw(lua_State *L); diff --git a/src/server.cpp b/src/server.cpp index 895e2bb80..ed1ac326e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1835,14 +1835,14 @@ void Server::SendMovePlayer(session_t peer_id) assert(sao); NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); - pkt << sao->getBasePosition() << sao->getPitch() << sao->getYaw(); + pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y; { v3f pos = sao->getBasePosition(); verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER" << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" - << " pitch=" << sao->getPitch() - << " yaw=" << sao->getYaw() + << " pitch=" << sao->getLookPitch() + << " yaw=" << sao->getRotation().Y << std::endl; } diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 3b2983825..efb93b9a2 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -340,8 +340,8 @@ void ActiveBlockList::update(std::vector &active_players, // only do this if this would add blocks if (player_ao_range > active_block_range) { v3f camera_dir = v3f(0,0,1); - camera_dir.rotateYZBy(playersao->getPitch()); - camera_dir.rotateXZBy(playersao->getYaw()); + camera_dir.rotateYZBy(playersao->getLookPitch()); + camera_dir.rotateXZBy(playersao->getRotation().Y); fillViewConeBlock(pos, player_ao_range, playersao->getEyePosition(), diff --git a/src/util/numeric.h b/src/util/numeric.h index b1e2845b8..bfdff84a0 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -182,6 +182,23 @@ inline float wrapDegrees_0_360(float f) } +/** Returns \p v3f wrapped to the range [0, 360] + */ +inline v3f wrapDegrees_0_360_v3f(v3f v) +{ + v3f value_v3f; + value_v3f.X = modulo360f(v.X); + value_v3f.Y = modulo360f(v.Y); + value_v3f.Z = modulo360f(v.Z); + + // Now that values are wrapped, use to get values for certain ranges + value_v3f.X = value_v3f.X < 0 ? value_v3f.X + 360 : value_v3f.X; + value_v3f.Y = value_v3f.Y < 0 ? value_v3f.Y + 360 : value_v3f.Y; + value_v3f.Z = value_v3f.Z < 0 ? value_v3f.Z + 360 : value_v3f.Z; + return value_v3f; +} + + /** Returns \p f wrapped to the range [-180, 180] */ inline float wrapDegrees_180(float f)