* 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).
* `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)`
// 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=("<<camera_dir.X<<","<<camera_dir.Y<<","
<<camera_dir.Z<<")"<<std::endl;*/
val_diff * moveratio, 360.f);
}
+void SmoothTranslatorWrappedv3f::translate(f32 dtime)
+{
+ anim_time_counter = anim_time_counter + dtime;
+
+ v3f val_diff_v3f;
+ val_diff_v3f.X = std::abs(val_target.X - val_old.X);
+ val_diff_v3f.Y = std::abs(val_target.Y - val_old.Y);
+ val_diff_v3f.Z = std::abs(val_target.Z - val_old.Z);
+
+ if (val_diff_v3f.X > 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
*/
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 {
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();
}
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);
}
}
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;
m_env->getLocalPlayer()->parent = getParent();
}
} else {
- yaw_translator.translate(dtime);
+ rot_translator.translate(dtime);
v3f lastpos = pos_translator.val_current;
if(m_prop.physical)
}
}
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();
}
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();
}
}
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;
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);
} 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);
void translate(f32 dtime);
};
+struct SmoothTranslatorWrappedv3f : SmoothTranslator<v3f>
+{
+ void translate(f32 dtime);
+};
+
class GenericCAO : public ClientActiveObject
{
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<v3f> pos_translator;
- SmoothTranslatorWrapped yaw_translator;
+ SmoothTranslatorWrappedv3f rot_translator;
// Spritesheet/animation stuff
v2f m_tx_size = v2f(1,1);
v2s16 m_tx_basepos;
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();
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
state = deSerializeLongString(is);
hp = readS16(is);
velocity = readV3F1000(is);
- yaw = readF1000(is);
+ rotation = readV3F1000(is);
}
}
// create object
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;
}
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);
}
}
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);
}
}
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);
writeS16(os, m_hp);
// velocity
writeV3F1000(os, m_velocity);
- // yaw
- writeF1000(os, m_yaw);
+ // rotation
+ writeV3F1000(os, m_rotation);
+
*result = os.str();
}
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();
m_base_position,
m_velocity,
m_acceleration,
- m_yaw,
+ m_rotation,
do_interpolate,
is_movement_end,
update_interval
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);
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();
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
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)
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);
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);
}
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
void notifyObjectPropertiesModified();
protected:
s16 m_hp = -1;
- float m_yaw = 0.0f;
+
+ v3f m_rotation;
bool m_properties_sent = true;
ObjectProperties m_prop;
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 = "";
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);
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;
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);
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),
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);
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);
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);
v3f position,
v3f velocity,
v3f acceleration,
- f32 yaw,
+ v3f rotation,
bool do_interpolate,
bool is_movement_end,
f32 update_interval
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)
v3f position,
v3f velocity,
v3f acceleration,
- f32 yaw,
+ v3f rotation,
bool do_interpolate,
bool is_movement_end,
f32 update_interval
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;
} 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 {
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;
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<float>(L, 2) * core::RADTODEG;
- // Do it
- co->setYaw(yaw);
+ co->setRotation(v3f(0, yaw, 0));
return 0;
}
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;
}
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));
PlayerSAO* co = getplayersao(ref);
if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, co->getRadPitchDep());
+ lua_pushnumber(L, co->getRadLookPitchDep());
return 1;
}
PlayerSAO* co = getplayersao(ref);
if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, co->getRadPitch());
+ lua_pushnumber(L, co->getRadLookPitch());
return 1;
}
PlayerSAO* co = getplayersao(ref);
if (co == NULL) return 0;
// Do it
- lua_pushnumber(L, co->getRadYaw());
+ lua_pushnumber(L, co->getRadRotation().Y);
return 1;
}
if (co == NULL) return 0;
float pitch = readParam<float>(L, 2) * core::RADTODEG;
// Do it
- co->setPitchAndSend(pitch);
+ co->setLookPitchAndSend(pitch);
return 1;
}
if (co == NULL) return 0;
float yaw = readParam<float>(L, 2) * core::RADTODEG;
// Do it
- co->setYawAndSend(yaw);
+ co->setPlayerYawAndSend(yaw);
return 1;
}
if (co == NULL) return 0;
float pitch = readParam<float>(L, 2) * core::RADTODEG;
// Do it
- co->setPitchAndSend(pitch);
+ co->setLookPitchAndSend(pitch);
return 1;
}
if (co == NULL) return 0;
float yaw = readParam<float>(L, 2) * core::RADTODEG;
// Do it
- co->setYawAndSend(yaw);
+ co->setPlayerYawAndSend(yaw);
return 1;
}
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),
// 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);
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;
}
// 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(),
}
+/** 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)