Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
jmdevy authored and nerzhul committed Nov 28, 2018
1 parent 9519d57 commit faa358e
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 99 deletions.
3 changes: 3 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -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)`
Expand Down
4 changes: 2 additions & 2 deletions src/clientiface.cpp
Expand Up @@ -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=("<<camera_dir.X<<","<<camera_dir.Y<<","
<<camera_dir.Z<<")"<<std::endl;*/
Expand Down
71 changes: 54 additions & 17 deletions src/content_cao.cpp
Expand Up @@ -114,6 +114,41 @@ void SmoothTranslatorWrapped::translate(f32 dtime)
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
*/
Expand Down Expand Up @@ -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 {
Expand All @@ -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();
}

Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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();
}

Expand All @@ -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();
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
14 changes: 10 additions & 4 deletions src/content_cao.h
Expand Up @@ -59,6 +59,11 @@ struct SmoothTranslatorWrapped : SmoothTranslator<f32>
void translate(f32 dtime);
};

struct SmoothTranslatorWrappedv3f : SmoothTranslator<v3f>
{
void translate(f32 dtime);
};

class GenericCAO : public ClientActiveObject
{
private:
Expand All @@ -80,10 +85,10 @@ class GenericCAO : public ClientActiveObject
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;
Expand Down Expand Up @@ -146,9 +151,10 @@ class GenericCAO : public ClientActiveObject
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();
Expand Down
52 changes: 29 additions & 23 deletions src/content_sao.cpp
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -767,18 +771,18 @@ 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();

std::string str = gob_cmd_update_position(
m_base_position,
m_velocity,
m_acceleration,
m_yaw,
m_rotation,
do_interpolate,
is_movement_end,
update_interval
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -1212,23 +1218,23 @@ 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);

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);
}

Expand Down

0 comments on commit faa358e

Please sign in to comment.