Add recentering

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-08-11 09:29:38 +03:00
parent e3b2f44621
commit 794178668e
4 changed files with 89 additions and 18 deletions

View File

@@ -159,7 +159,6 @@ int config_load_ref(lua_State *L, int idx, Config *out)
// ======== DEFAULTS ========
out->space.offset = (Vector3) { 0, 0, 0 };
out->space.initial_center = (Vector3) { 0, 0, 0 };
out->space.radius = 1.0f;
out->space.window_scale = 0.001f;
out->displays.hud.size = 720;
@@ -262,11 +261,6 @@ int config_load_ref(lua_State *L, int idx, Config *out)
out->space.offset = lua_readVector3(L, lua_absindex(L, -1));
lua_pop(L, 1);
lua_getfield(L, -1, "initial_center");
if (lua_istable(L, -1) || lua_isuserdata(L, -1))
out->space.initial_center = lua_readVector3(L, lua_absindex(L, -1));
lua_pop(L, 1);
lua_getfield(L, -1, "radius");
if (lua_isnumber(L, -1))
out->space.radius = (float)lua_tonumber(L, -1);

View File

@@ -28,7 +28,6 @@ typedef struct {
struct {
Vector3 offset;
Vector3 initial_center;
float radius;
float window_scale;
} space;

View File

@@ -1638,7 +1638,26 @@ static int l_cycle_next(lua_State *L)
static int l_recenter(lua_State *L)
{
g_wm.renderer.center = g_wm.renderer.camera.position;
(void)L;
Vector3 pos = g_wm.renderer.camera.position;
Vector3 fwd
= Vector3Normalize(Vector3Subtract(g_wm.renderer.camera.target, pos));
float len_xz = sqrtf(fwd.x * fwd.x + fwd.z * fwd.z);
float yaw = (len_xz > 1e-6f) ? atan2f(fwd.x, fwd.z) : 0.0f;
Quaternion q_step = QuaternionFromAxisAngle((Vector3) { 0, 1, 0 }, -yaw);
Vector3 t_step = Vector3Negate(Vector3RotateByQuaternion(pos, q_step));
Quaternion q_total = QuaternionMultiply(q_step, g_wm.xr.recenter_rot);
Vector3 t_total = Vector3Add(
Vector3RotateByQuaternion(g_wm.xr.recenter_trans, q_step), t_step);
g_wm.xr.recenter_rot = q_total;
g_wm.xr.recenter_trans = t_total;
g_wm.xr.recenter_active = true;
lua_pushnil(L);
return 1;
}
@@ -1679,7 +1698,9 @@ bool LunarWM_init(LunarWM *this)
this->renderer.camera.up = (Vector3) { 0, 1, 0 };
this->renderer.camera.fovy = 45;
this->renderer.camera.projection = CAMERA_PERSPECTIVE;
this->renderer.center = (Vector3) { 0, 0, 0 };
this->xr.recenter_rot = (Quaternion) { 0, 0, 0, 1 };
this->xr.recenter_trans = (Vector3) { 0, 0, 0 };
this->xr.recenter_active = false;
}
this->cman = config_manager_create(get_config_path());
@@ -1702,8 +1723,6 @@ bool LunarWM_init(LunarWM *this)
lua_setglobal(L, "lunar");
config_manager_reload(this->cman);
this->renderer.center = this->cman->cfg.space.initial_center;
}
if (getenv("DISPLAY") != nullptr || getenv("WAYLAND_DISPLAY") != nullptr) {
@@ -2201,7 +2220,7 @@ void render_hud(LunarWM *this, float /*dt*/, int hud_size)
void render_3d(LunarWM *this, float /*dt*/)
{
Skybox_draw(this->renderer.skybox, this->renderer.center);
Skybox_draw(this->renderer.skybox, Vector3Zero());
// rlDisableBackfaceCulling();
for (size_t i = 0; i < vector_size(this->wayland.v_toplevels); i++) {
@@ -2214,10 +2233,8 @@ void render_3d(LunarWM *this, float /*dt*/)
// continue;
DrawTexture3D(tl->rl_texture,
Vector3Add(this->renderer.center,
(Vector3) {
0, 0, this->cman->cfg.space.radius - 0.01 * (float)i }),
this->renderer.center, this->cman->cfg.space.window_scale, false);
(Vector3) { 0, 0, this->cman->cfg.space.radius - 0.01 * (float)i },
Vector3Zero(), this->cman->cfg.space.window_scale, false);
}
// rlEnableBackfaceCulling();
@@ -2257,6 +2274,21 @@ void render_3d(LunarWM *this, float /*dt*/)
}
}
static inline Vector3 RecenterPoint(LunarWM *wm, Vector3 p)
{
if (!wm->xr.recenter_active)
return p;
return Vector3Add(Vector3RotateByQuaternion(p, wm->xr.recenter_rot),
wm->xr.recenter_trans);
}
static inline Quaternion RecenterOrient(LunarWM *wm, Quaternion q)
{
if (!wm->xr.recenter_active)
return q;
return QuaternionMultiply(wm->xr.recenter_rot, q);
}
static bool render_layer(LunarWM *this, LunarWM_RenderLayerInfo *info, float dt)
{
auto const view_count = (uint32_t)this->xr.view_configuration_views_count;
@@ -2395,6 +2427,23 @@ static bool render_layer(LunarWM *this, LunarWM_RenderLayerInfo *info, float dt)
= Vector3Add(this->renderer.camera.position, forward);
this->renderer.camera.up = up;
}
if (this->xr.recenter_active) {
Vector3 pos = this->renderer.camera.position;
Vector3 fwd = Vector3Normalize(
Vector3Subtract(this->renderer.camera.target, pos));
Vector3 up = this->renderer.camera.up;
pos = Vector3Add(
Vector3RotateByQuaternion(pos, this->xr.recenter_rot),
this->xr.recenter_trans);
fwd = Vector3RotateByQuaternion(fwd, this->xr.recenter_rot);
up = Vector3RotateByQuaternion(up, this->xr.recenter_rot);
this->renderer.camera.position = pos;
this->renderer.camera.target = Vector3Add(pos, fwd);
this->renderer.camera.up = up;
}
}
BeginMode3D(this->renderer.camera);
@@ -2592,6 +2641,33 @@ void LunarWM_run(LunarWM *this)
return;
}
}
for (int h = 0; h < 2; h++) {
auto *hand_info = &this->xr.hands[h];
for (size_t k = 0; k < XR_HAND_JOINT_COUNT_EXT; ++k) {
auto *jl = &hand_info->joint_locations[k];
Vector3 pos = { jl->pose.position.x, jl->pose.position.y,
jl->pose.position.z };
pos = RecenterPoint(this, pos);
Quaternion q
= { jl->pose.orientation.x, jl->pose.orientation.y,
jl->pose.orientation.z, jl->pose.orientation.w };
q = RecenterOrient(this, q);
jl->pose.position.x = pos.x;
jl->pose.position.y = pos.y;
jl->pose.position.z = pos.z;
jl->pose.orientation.x = q.x;
jl->pose.orientation.y = q.y;
jl->pose.orientation.z = q.z;
jl->pose.orientation.w = q.w;
DrawSphere(pos, jl->radius, (Color) { 255, 0, 0, 255 });
}
}
}
LunarWM_RenderLayerInfo render_layer_info = {

View File

@@ -190,6 +190,10 @@ typedef struct LunarWM {
PFN_xrDestroyHandTrackerEXT DestroyHandTrackerEXT;
PFN_xrLocateHandJointsEXT LocateHandJointsEXT;
Quaternion recenter_rot;
Vector3 recenter_trans;
bool recenter_active;
bool session_running;
} xr;
@@ -201,8 +205,6 @@ typedef struct LunarWM {
Camera3D camera;
Shader linear_srgb;
Vector3 center;
Skybox skybox;
} renderer;