Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-08-11 09:52:57 +03:00
parent 794178668e
commit bf3ed0dd0c
2 changed files with 88 additions and 89 deletions

View File

@@ -2139,56 +2139,101 @@ static void DrawBillboardNoShear(
DrawBillboardPro(cam, tex, src, pos, cam.up, size, origin, 0.0f, tint);
}
// pass yFlip from tl->attribs.invert_y
static void DrawTexture3D(
Texture2D tex, Vector3 position, Vector3 target, float scale, bool y_flip)
void DrawTextureCyl(
Texture2D tex, Vector3 center, float radius, float scale, bool y_flip)
{
if (!tex.id)
if (!tex.id || scale <= 0.0f || radius == 0.0f)
return;
Vector3 fwd = Vector3Normalize(Vector3Subtract(target, position));
Vector3 up_ref = (fabsf(fwd.y) > 0.99f) ? (Vector3) { 0, 0, 1 }
: (Vector3) { 0, 1, 0 };
Vector3 right = Vector3Normalize(Vector3CrossProduct(fwd, up_ref));
Vector3 up = Vector3CrossProduct(right, fwd);
float half_w = 0.5f * (float)tex.width * scale;
float r = fabsf(radius);
float arc_len = (float)tex.width * scale; // arc length in world units
float theta = arc_len / r; // radians across the panel
float half_t = 0.5f * theta;
float half_h = 0.5f * (float)tex.height * scale;
Vector3 tl
= Vector3Add(Vector3Subtract(position, Vector3Scale(right, half_w)),
Vector3Scale(up, half_h));
Vector3 tr = Vector3Add(Vector3Add(position, Vector3Scale(right, half_w)),
Vector3Scale(up, half_h));
Vector3 br
= Vector3Subtract(Vector3Add(position, Vector3Scale(right, half_w)),
Vector3Scale(up, half_h));
Vector3 bl = Vector3Subtract(
Vector3Subtract(position, Vector3Scale(right, half_w)),
Vector3Scale(up, half_h));
// mid-angle around Y so the segment's middle sits at 'center'
float a0 = atan2f(center.x, center.z);
// shift so the cylinder surface midpoint matches 'center'
Vector3 mid_ref = (Vector3) { sinf(a0) * r, center.y, cosf(a0) * r };
Vector3 delta = Vector3Subtract(center, mid_ref);
// tessellation: about 3° per slice (min 8)
int slices = (int)ceilf(fmaxf(theta * (180.0f / PI) / 3.0f, 8.0f));
if (slices > 1024)
slices = 1024;
float vt = y_flip ? 1.0f : 0.0f;
float vb = y_flip ? 0.0f : 1.0f;
rlDisableBackfaceCulling(); // ensure visible regardless of winding
rlDrawRenderBatchActive(); // flush any prior state
rlSetTexture(tex.id);
rlDisableBackfaceCulling();
rlColor4ub(255, 255, 255, 255);
rlBegin(RL_QUADS);
rlNormal3f(fwd.x, fwd.y, fwd.z);
// TL, TR, BR, BL with canonical UVs
rlTexCoord2f(1.0f, vt);
rlVertex3f(tl.x, tl.y, tl.z);
rlTexCoord2f(0.0f, vt);
rlVertex3f(tr.x, tr.y, tr.z);
rlTexCoord2f(0.0f, vb);
rlVertex3f(br.x, br.y, br.z);
rlTexCoord2f(1.0f, vb);
rlVertex3f(bl.x, bl.y, bl.z);
for (int i = 0; i < slices; ++i) {
float u0 = (float)i / (float)slices;
float u1 = (float)(i + 1) / (float)slices;
float aL = a0 - half_t + theta * u0;
float aR = a0 - half_t + theta * u1;
Vector3 nL = (Vector3) { sinf(aL), 0.0f, cosf(aL) };
Vector3 nR = (Vector3) { sinf(aR), 0.0f, cosf(aR) };
if (radius < 0.0f) {
nL = Vector3Negate(nL);
nR = Vector3Negate(nR);
}
Vector3 pLT = Vector3Add(
(Vector3) { nL.x * r, center.y + half_h, nL.z * r }, delta);
Vector3 pLB = Vector3Add(
(Vector3) { nL.x * r, center.y - half_h, nL.z * r }, delta);
Vector3 pRT = Vector3Add(
(Vector3) { nR.x * r, center.y + half_h, nR.z * r }, delta);
Vector3 pRB = Vector3Add(
(Vector3) { nR.x * r, center.y - half_h, nR.z * r }, delta);
// match your flat-quad U flip (so WL textures look correct)
float U0 = 1.0f - u0;
float U1 = 1.0f - u1;
// one normal per-vertex (simple cylindrical)
rlNormal3f(nL.x, nL.y, nL.z);
rlTexCoord2f(U0, vt);
rlVertex3f(pLT.x, pLT.y, pLT.z);
rlNormal3f(nR.x, nR.y, nR.z);
rlTexCoord2f(U1, vt);
rlVertex3f(pRT.x, pRT.y, pRT.z);
rlNormal3f(nR.x, nR.y, nR.z);
rlTexCoord2f(U1, vb);
rlVertex3f(pRB.x, pRB.y, pRB.z);
rlNormal3f(nL.x, nL.y, nL.z);
rlTexCoord2f(U0, vb);
rlVertex3f(pLB.x, pLB.y, pLB.z);
}
rlEnd();
rlSetTexture(0);
rlEnableBackfaceCulling();
}
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);
}
void render_hud(LunarWM *this, float /*dt*/, int hud_size)
{
ClearBackground((Color) { 0, 0, 0, 0 });
@@ -2220,33 +2265,30 @@ void render_hud(LunarWM *this, float /*dt*/, int hud_size)
void render_3d(LunarWM *this, float /*dt*/)
{
Skybox_draw(this->renderer.skybox, Vector3Zero());
Skybox_draw(this->renderer.skybox, this->renderer.camera.position);
// rlDisableBackfaceCulling();
for (size_t i = 0; i < vector_size(this->wayland.v_toplevels); i++) {
auto *tl = this->wayland.v_toplevels[i];
if (!tl || !tl->surface)
continue;
// if (!LunarWM_Toplevel_update(tl))
// continue;
auto const rad = this->cman->cfg.space.radius - 0.01 * (float)i;
DrawTexture3D(tl->rl_texture,
(Vector3) { 0, 0, this->cman->cfg.space.radius - 0.01 * (float)i },
Vector3Zero(), this->cman->cfg.space.window_scale, false);
DrawTextureCyl(tl->rl_texture, (Vector3) { 0, 0, rad }, rad,
this->cman->cfg.space.window_scale, false);
}
// rlEnableBackfaceCulling();
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 const *jl = &hand_info->joint_locations[k];
Vector3 const pos = {
Vector3 pos = {
jl->pose.position.x,
jl->pose.position.y,
jl->pose.position.z,
};
pos = RecenterPoint(this, pos);
DrawSphere(pos, jl->radius, (Color) { 255, 0, 0, 255 });
}
}
@@ -2274,21 +2316,6 @@ 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;
@@ -2448,6 +2475,7 @@ static bool render_layer(LunarWM *this, LunarWM_RenderLayerInfo *info, float dt)
BeginMode3D(this->renderer.camera);
{
ClearBackground(RED);
render_3d(this, dt);
}
EndMode3D();
@@ -2641,33 +2669,6 @@ 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

@@ -95,16 +95,14 @@ void Skybox_draw(Skybox const skybox, Vector3 position)
if (!skybox.ok)
return;
// Render behind everything without writing depth; cull disabled so we see
// inside faces
rlDisableBackfaceCulling();
rlDisableDepthMask();
rlDisableDepthTest();
rlDisableColorBlend();
DrawModel(skybox.cube, position, 500.0f, (Color) { 255, 255, 255, 255 });
DrawModel(skybox.cube, position, 5.0f, (Color) { 255, 255, 255, 255 });
rlDrawRenderBatchActive();
rlEnableColorBlend();
rlEnableDepthMask();
rlEnableDepthTest();
rlEnableBackfaceCulling();
}