diff --git a/src/Config.c b/src/Config.c index 17edc49..a860c8b 100644 --- a/src/Config.c +++ b/src/Config.c @@ -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); diff --git a/src/Config.h b/src/Config.h index de4c250..6f7a34a 100644 --- a/src/Config.h +++ b/src/Config.h @@ -28,7 +28,6 @@ typedef struct { struct { Vector3 offset; - Vector3 initial_center; float radius; float window_scale; } space; diff --git a/src/LunarWM.c b/src/LunarWM.c index c4c47b0..e0fb188 100644 --- a/src/LunarWM.c +++ b/src/LunarWM.c @@ -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 = { diff --git a/src/LunarWM.h b/src/LunarWM.h index 36a16d1..76d284d 100644 --- a/src/LunarWM.h +++ b/src/LunarWM.h @@ -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;