Skip to main content

polytope_playground/
scene.rs

1use glam::Vec4;
2use loam::math::EuclideanR4;
3use loam::render::raymarch::scene::{Scene4, SceneNode4};
4use loam::render::raymarch::{
5    polytope_extended_sdfs_wgsl, BodyUniform, Hyperslice4DUniforms, HYPERSLICE_KERNEL_WGSL,
6};
7use loam::render::sky_ground::{
8    Ground, Sky, DEFAULT_FOG_PER_UNIT, GROUND_DARK_GREY, GROUND_LIGHT_GREY,
9};
10use loam::runtime::Eye;
11use loam::runtime::Pose;
12
13use crate::catalog::ShapeEntry;
14use crate::consts::FLOOR_Y;
15
16pub(crate) fn shader_source() -> String {
17    let scene = Scene4::new(SceneNode4::halfspace(Vec4::Y, FLOOR_Y));
18    format!(
19        "{kernel}\n{polytope}\n{scene}\n",
20        kernel = HYPERSLICE_KERNEL_WGSL,
21        polytope = polytope_extended_sdfs_wgsl(),
22        scene = scene.to_hyperslice_wgsl_gated("u.w_slice", "u.params.x"),
23    )
24}
25
26pub(crate) fn ground(visible: bool) -> Ground {
27    Ground {
28        y: FLOOR_Y,
29        dark: GROUND_DARK_GREY,
30        light: GROUND_LIGHT_GREY,
31        fog_per_unit: DEFAULT_FOG_PER_UNIT,
32        fog_start: 0.0,
33        visible,
34    }
35}
36
37pub(crate) fn body_of(entry: &ShapeEntry, pose: &Pose<EuclideanR4>, size: f32) -> BodyUniform {
38    BodyUniform::polytope_with_rotor(
39        pose.point.to_array(),
40        entry.shape.shape_id(),
41        size,
42        pose.frame,
43        entry.body_color,
44    )
45}
46
47pub(crate) fn uniforms(
48    eye: &Eye,
49    sky: Sky,
50    w_slice: f32,
51    floor_visible: bool,
52) -> Hyperslice4DUniforms {
53    Hyperslice4DUniforms {
54        sky_below: sky.below,
55        sky_above: sky.above,
56        camera_pos: eye.position,
57        camera_forward: eye.forward,
58        camera_right: eye.right,
59        camera_up: eye.up,
60        fov_y_tan: (eye.fov_y * 0.5).tan(),
61        w_slice,
62        params: [if floor_visible { 1.0 } else { 0.0 }, 0.0, 0.0, 0.0],
63        near: eye.near,
64        ..Hyperslice4DUniforms::default()
65    }
66}