Skip to content

Commit

Permalink
Implement player:get_point_dir() and player:get_point_screen_pos()
Browse files Browse the repository at this point in the history
  • Loading branch information
grorp committed Feb 24, 2025
1 parent c4805e0 commit 2980a9a
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 8 deletions.
16 changes: 16 additions & 0 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8452,6 +8452,22 @@ child will follow movement and rotation of that bone.
table {x, y, z} representing the player's instantaneous velocity in nodes/s
* `add_player_velocity(vel)`: **DEPRECATED**, use add_velocity(vel) instead.
* `get_look_dir()`: get camera direction as a unit vector
* `get_point_dir()`: get pointing direction as a unit vector
* If the player uses a crosshair, this returns the same value as `get_look_dir`.
* If the player uses the touchscreen controls without a crosshair, ...
* ...the look direction and the pointing direction may differ.
* ...the player doesn't have a well-defined pointing direction when not
touching the screen. In this case, `get_point_dir` returns the last
pointing direction.
* `get_point_screen_pos()`: get pointer position in screen-space
* Returns a 2D vector in coordinates relative to the screen size:
`{x = 0..1, y = 0..1}`
* If the player uses a crosshair, this always returns `{x = 0.5, y = 0.5}`
* If the player uses the touchscreen controls without a crosshair, ...
* ...other values may be returned.
* ...the player doesn't have a well-defined pointer position when not
touching the screen. In this case, `get_point_screen_pos` returns the
last pointer position.
* `get_look_vertical()`: pitch in radians
* Angle ranges between -pi/2 and pi/2, which are straight up and down
respectively.
Expand Down
20 changes: 17 additions & 3 deletions src/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ void Client::Send(NetworkPacket* pkt)
m_con->Send(PEER_ID_SERVER, scf.channel, pkt, scf.reliable);
}

// Will fill up 12 + 12 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4 bytes
// Will fill up 12 + 12 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4 + 8 + 4 + 4 bytes
void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt, bool camera_inverted)
{
v3f pf = myplayer->getPosition() * 100;
Expand All @@ -1042,6 +1042,9 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *
std::ceil(clientMap->getWantedRange() * (1.0f / MAP_BLOCKSIZE)));
f32 movement_speed = myplayer->control.movement_speed;
f32 movement_dir = myplayer->control.movement_direction;
v2f pointer_pos = myplayer->pointer_pos;
f32 point_pitch = myplayer->point_pitch;
f32 point_yaw = myplayer->point_yaw;

v3s32 position(pf.X, pf.Y, pf.Z);
v3s32 speed(sf.X, sf.Y, sf.Z);
Expand All @@ -1058,11 +1061,16 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *
[12+12+4+4+4+1+1] u8 camera_inverted (bool)
[12+12+4+4+4+1+1+1] f32 movement_speed
[12+12+4+4+4+1+1+1+4] f32 movement_direction
[12+12+4+4+4+1+1+1+4+4] v2f pointer_pos
[12+12+4+4+4+1+1+1+4+4+8] f32 point_pitch
[12+12+4+4+4+1+1+1+4+4+8+4] f32 point_yaw
*/
*pkt << position << speed << pitch << yaw << keyPressed;
*pkt << fov << wanted_range;
*pkt << camera_inverted;
*pkt << movement_speed << movement_dir;
*pkt << pointer_pos;
*pkt << point_pitch << point_yaw;
}

void Client::interact(InteractAction action, const PointedThing& pointed)
Expand Down Expand Up @@ -1409,7 +1417,10 @@ void Client::sendPlayerPos()
player->last_camera_inverted == camera_inverted &&
player->last_wanted_range == wanted_range &&
player->last_movement_speed == movement_speed &&
player->last_movement_dir == movement_dir)
player->last_movement_dir == movement_dir &&
player->last_pointer_pos == player->pointer_pos &&
player->last_point_pitch == player->point_pitch &&
player->last_point_yaw == player->point_yaw)
return;

player->last_position = player->getPosition();
Expand All @@ -1422,8 +1433,11 @@ void Client::sendPlayerPos()
player->last_wanted_range = wanted_range;
player->last_movement_speed = movement_speed;
player->last_movement_dir = movement_dir;
player->last_pointer_pos = player->pointer_pos;
player->last_point_pitch = player->point_pitch;
player->last_point_yaw = player->point_yaw;

NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4);
NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4 + 8 + 4 + 4);

writePlayerPos(player, &map, &pkt, camera_inverted);

Expand Down
26 changes: 26 additions & 0 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ class Game {

void updateCameraDirection(CameraOrientation *cam, float dtime);
void updateCameraOrientation(CameraOrientation *cam, float dtime);
void updatePointDir(const CameraOrientation &cam);
void updatePlayerControl(const CameraOrientation &cam);
void updatePauseState();
void step(f32 dtime);
Expand Down Expand Up @@ -1014,6 +1015,7 @@ void Game::run()
cam_view.camera_yaw) * m_cache_cam_smoothing;
cam_view.camera_pitch += (cam_view_target.camera_pitch -
cam_view.camera_pitch) * m_cache_cam_smoothing;
updatePointDir(cam_view);
updatePlayerControl(cam_view);

updatePauseState();
Expand Down Expand Up @@ -2438,6 +2440,30 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
cam->camera_pitch = rangelim(cam->camera_pitch, -89.5, 89.5);
}

void Game::updatePointDir(const CameraOrientation &cam)
{
LocalPlayer *player = client->getEnv().getLocalPlayer();

if (isTouchShootlineUsed()) {
v2s32 pointer_pos = g_touchcontrols->getPointerPos();
v2u32 screensize = driver->getScreenSize();
player->pointer_pos.X = (f32)pointer_pos.X / (f32)screensize.X;
player->pointer_pos.Y = (f32)pointer_pos.Y / (f32)screensize.Y;

const v3f point_dir = g_touchcontrols->getShootline().getVector().normalize();
// getHorizontalAngle is Irrlicht's "direction to rotation" function
// Roll (Z) is always 0
const v3f point_rot = point_dir.getHorizontalAngle();
player->point_pitch = point_rot.X;
player->point_yaw = point_rot.Y;
} else {
player->pointer_pos.X = 0.5f;
player->pointer_pos.Y = 0.5f;
player->point_pitch = 0.0f;
player->point_yaw = 0.0f;
}
}


void Game::updatePlayerControl(const CameraOrientation &cam)
{
Expand Down
3 changes: 3 additions & 0 deletions src/client/localplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class LocalPlayer : public Player
bool last_camera_inverted = false;
f32 last_movement_speed = 0.0f;
f32 last_movement_dir = 0.0f;
v2f last_pointer_pos = v2f(0.5f, 0.5f);
float last_point_pitch = 0.0f;
float last_point_yaw = 0.0f;

float camera_impact = 0.0f;

Expand Down
8 changes: 8 additions & 0 deletions src/gui/touchcontrols.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ class TouchControls
*/
line3d<f32> getShootline() { return m_shootline; }

/**
* Returns the pointer position in pixels.
*
* This may only be used if isShootlineAvailable returns true.
* Otherwise, the normal crosshair position (center of the screen) must be used.
*/
v2s32 getPointerPos() { return m_move_pos; }

float getJoystickDirection() { return m_joystick_direction; }
float getJoystickSpeed() { return m_joystick_speed; }

Expand Down
3 changes: 3 additions & 0 deletions src/network/networkprotocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,9 @@ enum ToServerCommand : u16
[2+12+12+4+4+4+1+1] u8 camera_inverted (bool)
[2+12+12+4+4+4+1+1+1] f32 movement_speed
[2+12+12+4+4+4+1+1+1+4] f32 movement_direction
[2+12+12+4+4+4+1+1+1+4+4] v2f pointer_pos
[2+12+12+4+4+4+1+1+1+4+4+8] f32 point_pitch
[2+12+12+4+4+4+1+1+1+4+4+8+4] f32 point_yaw
*/

Expand Down
10 changes: 10 additions & 0 deletions src/network/serverpackethandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,16 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
player->control.setMovementFromKeys();
}

if (pkt->getRemainingBytes() >= 16) {
*pkt >> player->pointer_pos;
*pkt >> player->point_pitch >> player->point_yaw;
} else {
player->pointer_pos.X = 0.5f;
player->pointer_pos.Y = 0.5f;
player->point_pitch = 0.0f;
player->point_yaw = 0.0f;
}

v3f position((f32)ps.X / 100.0f, (f32)ps.Y / 100.0f, (f32)ps.Z / 100.0f);
v3f speed((f32)ss.X / 100.0f, (f32)ss.Y / 100.0f, (f32)ss.Z / 100.0f);

Expand Down
12 changes: 12 additions & 0 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ class Player
PlayerControl control;
const PlayerControl& getPlayerControl() { return control; }

// Pointer position, as screen coordinates in the range 0..1
// When using a crosshair, this is always (0.5, 0.5)
v2f pointer_pos = v2f(0.5f, 0.5f);
// Pointing direction, represented as pitch/yaw in degrees
// When using a crosshair, it's unspecified what values these will have.
f32 point_pitch = 0.0f;
f32 point_yaw = 0.0f;

// Note: If there is no crosshair and the player is not touching the screen,
// pointer position and pointing direction are not well-defined. In this
// case, the last values are kept.

PlayerPhysicsOverride physics_override;

// Returns non-empty `selected` ItemStack. `hand` is a fallback, if specified
Expand Down
42 changes: 37 additions & 5 deletions src/script/lua_api/l_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1279,12 +1279,42 @@ int ObjectRef::l_get_look_dir(lua_State *L)
if (playersao == nullptr)
return 0;

float pitch = playersao->getRadLookPitchDep();
float yaw = playersao->getRadYawDep();
v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) *
std::sin(yaw));
push_v3f(L, playersao->getLookDir());
return 1;
}

// get_point_screen_pos(self)
int ObjectRef::l_get_point_screen_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;

push_v2f(L, player->pointer_pos);
return 1;
}

// get_point_dir(self)
int ObjectRef::l_get_point_dir(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
return 0;

RemotePlayer *player = playersao->getPlayer();

if (player->pointer_pos.X == 0.5f && player->pointer_pos.Y == 0.5f) {
push_v3f(L, playersao->getLookDir());
return 1;
}

push_v3f(L, v);
const v3f point_rot = v3f(player->point_pitch, player->point_yaw, 0.0f);
const v3f point_dir = point_rot.rotationToDirection();
push_v3f(L, point_dir);
return 1;
}

Expand Down Expand Up @@ -2873,6 +2903,8 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, is_player),
luamethod(ObjectRef, get_player_name),
luamethod(ObjectRef, get_look_dir),
luamethod(ObjectRef, get_point_screen_pos),
luamethod(ObjectRef, get_point_dir),
luamethod(ObjectRef, get_look_pitch),
luamethod(ObjectRef, get_look_yaw),
luamethod(ObjectRef, get_look_vertical),
Expand Down
6 changes: 6 additions & 0 deletions src/script/lua_api/l_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ class ObjectRef : public ModApiBase {
// get_look_dir(self)
static int l_get_look_dir(lua_State *L);

// get_point_screen_pos(self)
static int l_get_point_screen_pos(lua_State *L);

// get_point_dir(self)
static int l_get_point_dir(lua_State *L);

// DEPRECATED
// get_look_pitch(self)
static int l_get_look_pitch(lua_State *L);
Expand Down
9 changes: 9 additions & 0 deletions src/server/player_sao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,15 @@ void PlayerSAO::setPlayerYaw(const float yaw)
UnitSAO::setRotation(rotation);
}

v3f PlayerSAO::getLookDir() const
{
// FIXME: get rid of deprecated method usage
float pitch = getRadLookPitchDep();
float yaw = getRadYawDep();
return v3f(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) *
std::sin(yaw));
}

void PlayerSAO::setFov(const float fov)
{
if (m_player && fov != m_fov)
Expand Down
1 change: 1 addition & 0 deletions src/server/player_sao.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class PlayerSAO : public UnitSAO
f32 getRadLookPitch() const { return m_pitch * core::DEGTORAD; }
// Deprecated
f32 getRadLookPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
v3f getLookDir() const;
void setFov(const float pitch);
f32 getFov() const { return m_fov; }
void setWantedRange(const s16 range);
Expand Down

0 comments on commit 2980a9a

Please sign in to comment.