Skip to content

Commit

Permalink
Different design to better match the way touch_use_crosshair=false wo…
Browse files Browse the repository at this point in the history
…rks for the player
  • Loading branch information
grorp committed Dec 20, 2024
1 parent fd7c2b3 commit 0b5e5e1
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 87 deletions.
14 changes: 10 additions & 4 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8403,14 +8403,20 @@ child will follow movement and rotation of that bone.
* `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.
* 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
valid 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.
* 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 valid 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
3 changes: 0 additions & 3 deletions irr/include/ICameraSceneNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ class ICameraSceneNode : public ISceneNode, public IEventReceiver
/** \return The current view frustum. */
virtual const SViewFrustum *getViewFrustum() const = 0;

//! Get the view frustum, relative. Warning: calculated, not cached
virtual SViewFrustum getViewFrustumRel() const = 0;

//! Disables or enables the camera to get key or mouse inputs.
/** If this is set to true, the camera will respond to key
inputs otherwise not. */
Expand Down
3 changes: 1 addition & 2 deletions irr/include/ISceneCollisionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ class ISceneCollisionManager : public virtual IReferenceCounted
at a length of the far value of the camera at a position which
would be behind the 2d screen coordinates. */
virtual core::line3d<f32> getRayFromScreenCoordinates(
const core::position2d<s32> &pos, const ICameraSceneNode *camera = 0,
bool relative = false) = 0;
const core::position2d<s32> &pos, const ICameraSceneNode *camera = 0) = 0;
};

} // end namespace scene
Expand Down
9 changes: 0 additions & 9 deletions irr/src/CCameraSceneNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,6 @@ const SViewFrustum *CCameraSceneNode::getViewFrustum() const
return &ViewArea;
}

SViewFrustum CCameraSceneNode::getViewFrustumRel() const
{
SViewFrustum rel;
rel.cameraPosition = core::vector3df(0.0f, 0.0f, 0.0f);
rel.setFarNearDistance(ZFar - ZNear);
rel.setFrom(ViewArea.getTransform(video::ETS_PROJECTION), false);
return rel;
}

void CCameraSceneNode::recalculateViewArea()
{
ViewArea.cameraPosition = getAbsolutePosition();
Expand Down
3 changes: 0 additions & 3 deletions irr/src/CCameraSceneNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ class CCameraSceneNode : public ICameraSceneNode
//! Returns the view area.
const SViewFrustum *getViewFrustum() const override;

//! Returns the view area, relative. Warning: calculated, not cached
SViewFrustum getViewFrustumRel() const override;

//! Disables or enables the camera to get key or mouse inputs.
//! If this is set to true, the camera will respond to key inputs
//! otherwise not.
Expand Down
19 changes: 7 additions & 12 deletions irr/src/CSceneCollisionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ CSceneCollisionManager::~CSceneCollisionManager()

//! Returns a 3d ray which would go through the 2d screen coordinates.
core::line3d<f32> CSceneCollisionManager::getRayFromScreenCoordinates(
const core::position2d<s32> &pos, const ICameraSceneNode *camera,
bool relative)
const core::position2d<s32> &pos, const ICameraSceneNode *camera)
{
core::line3d<f32> ln(0, 0, 0, 0, 0, 0);

Expand All @@ -44,15 +43,11 @@ core::line3d<f32> CSceneCollisionManager::getRayFromScreenCoordinates(
if (!camera)
return ln;

scene::SViewFrustum f;
if (relative)
f = camera->getViewFrustumRel();
else
f = *camera->getViewFrustum();
const scene::SViewFrustum *f = camera->getViewFrustum();

core::vector3df farLeftUp = f.getFarLeftUp();
core::vector3df lefttoright = f.getFarRightUp() - farLeftUp;
core::vector3df uptodown = f.getFarLeftDown() - farLeftUp;
core::vector3df farLeftUp = f->getFarLeftUp();
core::vector3df lefttoright = f->getFarRightUp() - farLeftUp;
core::vector3df uptodown = f->getFarLeftDown() - farLeftUp;

const core::rect<s32> &viewPort = Driver->getViewPort();
core::dimension2d<u32> screenSize(viewPort.getWidth(), viewPort.getHeight());
Expand All @@ -61,9 +56,9 @@ core::line3d<f32> CSceneCollisionManager::getRayFromScreenCoordinates(
f32 dy = pos.Y / (f32)screenSize.Height;

if (camera->isOrthogonal())
ln.start = f.cameraPosition + (lefttoright * (dx - 0.5f)) + (uptodown * (dy - 0.5f));
ln.start = f->cameraPosition + (lefttoright * (dx - 0.5f)) + (uptodown * (dy - 0.5f));
else
ln.start = f.cameraPosition;
ln.start = f->cameraPosition;

ln.end = farLeftUp + (lefttoright * dx) + (uptodown * dy);

Expand Down
3 changes: 1 addition & 2 deletions irr/src/CSceneCollisionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class CSceneCollisionManager : public ISceneCollisionManager

//! Returns a 3d ray which would go through the 2d screen coordinates.
virtual core::line3d<f32> getRayFromScreenCoordinates(
const core::position2d<s32> &pos, const ICameraSceneNode *camera = 0,
bool relative = false) override;
const core::position2d<s32> &pos, const ICameraSceneNode *camera = 0) override;

private:
ISceneManager *SceneManager;
Expand Down
8 changes: 4 additions & 4 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2718,13 +2718,13 @@ void Game::updatePointDir(const CameraOrientation &cam)
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_rel = g_touchcontrols->getShootlineRel().getVector().normalize();
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_rel = point_dir_rel.getHorizontalAngle();
const v3f point_rot = point_dir.getHorizontalAngle();

player->point_pitch = point_rot_rel.X;
player->point_yaw = point_rot_rel.Y;
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;
Expand Down
38 changes: 18 additions & 20 deletions src/gui/touchcontrols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,6 @@ TouchControls::TouchControls(IrrlichtDevice *device, ISimpleTextureSource *tsrc)
m_screensize = m_device->getVideoDriver()->getScreenSize();
m_button_size = ButtonLayout::getButtonSize(m_screensize);
applyLayout(ButtonLayout::loadFromSettings());
// This means the shootline starts out in the middle of the screen instead
// of the upper left corner with m_draw_crosshair == false.
// It's not strictly necessary, but it's nicer.
m_move_pos = v2s32(m_screensize.X / 2, m_screensize.Y / 2);
}

void TouchControls::applyLayout(const ButtonLayout &layout)
Expand Down Expand Up @@ -535,9 +531,11 @@ void TouchControls::translateEvent(const SEvent &event)
m_move_has_really_moved = false;
m_move_downtime = porting::getTimeMs();
m_move_pos = touch_pos;
m_had_move_id = true;
m_move_prevent_short_tap = prevent_short_tap;

// DON'T reset m_tap_state here, otherwise many short taps
// will be ignored if you tap very fast.
m_move_prevent_short_tap = prevent_short_tap;
}
}
}
Expand Down Expand Up @@ -656,22 +654,22 @@ void TouchControls::step(float dtime)
m_tap_state = TapState::LongTap;
}
}
}

line3d<f32> TouchControls::getShootline()
{
return m_device
->getSceneManager()
->getSceneCollisionManager()
->getRayFromScreenCoordinates(m_move_pos, nullptr, false);
}

line3d<f32> TouchControls::getShootlineRel()
{
return m_device
->getSceneManager()
->getSceneCollisionManager()
->getRayFromScreenCoordinates(m_move_pos, nullptr, true);
// Update the shootline.
// Since not only the pointer position, but also the player position and
// thus the camera position can change, it doesn't suffice to update the
// shootline when a touch event occurs.
// Note that the shootline isn't used if touch_use_crosshair is enabled.
// Only updating when m_has_move_id means that the shootline will stay at
// it's last in-world position when the player doesn't need it.
if (!m_draw_crosshair && (m_has_move_id || m_had_move_id)) {
v2s32 pointer_pos = getPointerPos();
m_shootline = m_device
->getSceneManager()
->getSceneCollisionManager()
->getRayFromScreenCoordinates(pointer_pos);
}
m_had_move_id = false;
}

void TouchControls::resetHotbarRects()
Expand Down
19 changes: 12 additions & 7 deletions src/gui/touchcontrols.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class TouchControls
}

/**
* Returns the pointer position.
* Returns the pointer position in pixels.
*
* May only be used if crosshair is disabled (see setUseCrosshair)
*/
Expand All @@ -113,12 +113,7 @@ class TouchControls
*
* May only be used if crosshair is disabled (see setUseCrosshair)
*/
line3d<f32> getShootline();
/**
* This has the same purpose as getShootline, but the returned shootline
* is relative to the camera.
*/
line3d<f32> getShootlineRel();
line3d<f32> getShootline() { return m_shootline; }

float getJoystickDirection() { return m_joystick_direction; }
float getJoystickSpeed() { return m_joystick_speed; }
Expand Down Expand Up @@ -158,12 +153,22 @@ class TouchControls
double m_camera_yaw_change = 0.0;
double m_camera_pitch_change = 0.0;

/**
* A line starting at the camera and pointing towards the selected object.
* The line ends on the camera's far plane.
* The coordinates do not contain the camera offset.
*/
line3d<f32> m_shootline;

bool m_has_move_id = false;
size_t m_move_id;
bool m_move_has_really_moved = false;
u64 m_move_downtime = 0;
// m_move_pos stays valid even after m_move_id has been released.
v2s32 m_move_pos;
// This is needed so that we don't miss if m_has_move_id is true for less
// than one client step, i.e. press and release happen in the same step.
bool m_had_move_id = false;
bool m_move_prevent_short_tap = false;

bool m_has_joystick_id = false;
Expand Down
9 changes: 6 additions & 3 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,15 @@ class Player
// 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);
// Point direction, represented as pitch/yaw in degrees
// Relative to look direction
// When using a crosshair, these are always 0
// 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, so the last
// valid value is kept.

PlayerPhysicsOverride physics_override;

// Returns non-empty `selected` ItemStack. `hand` is a fallback, if specified
Expand Down
27 changes: 9 additions & 18 deletions src/script/lua_api/l_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1246,12 +1246,7 @@ 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, v);
push_v3f(L, playersao->getLookDir());
return 1;
}

Expand All @@ -1260,11 +1255,10 @@ int ObjectRef::l_get_point_screen_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
PlayerSAO* playersao = getplayersao(ref);
if (playersao == nullptr)
RemotePlayer *player = getplayer(ref);
if (player == nullptr)
return 0;

RemotePlayer *player = playersao->getPlayer();
push_v2f(L, player->pointer_pos);
return 1;
}
Expand All @@ -1279,17 +1273,14 @@ int ObjectRef::l_get_point_dir(lua_State *L)
return 0;

RemotePlayer *player = playersao->getPlayer();
const v3f point_rot_rel = v3f(player->point_pitch, player->point_yaw, 0.0f);
const v3f point_dir_rel = point_rot_rel.rotationToDirection();

// "-1 * yaw" because that's how the yaw value is applied to the camera,
// no idea why it was chosen to be like that.
core::matrix4 look_rot_mat;
look_rot_mat.setRotationRadians(v3f(playersao->getRadLookPitch(),
-1.0f * playersao->getRadRotation().Y, 0.0f));

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

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
9 changes: 9 additions & 0 deletions src/server/player_sao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,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 0b5e5e1

Please sign in to comment.