169
									
								
								src/LunarWM.c
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								src/LunarWM.c
									
									
									
									
									
								
							| @@ -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 = { | ||||
|   | ||||
| @@ -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(); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user