cargo fmt

This commit is contained in:
Greg Shuflin
2026-03-17 15:31:08 -07:00
parent 7899000349
commit a4970114ad
4 changed files with 288 additions and 93 deletions
+8 -12
View File
@@ -80,8 +80,8 @@ impl App {
fn update(&mut self, dt: f32, time: f32) {
let speed = 8.0 * dt;
// Keyboard input
let grid_mode = self.input.is_pressed(KeyCode::ShiftLeft)
|| self.input.is_pressed(KeyCode::ShiftRight);
let grid_mode =
self.input.is_pressed(KeyCode::ShiftLeft) || self.input.is_pressed(KeyCode::ShiftRight);
if grid_mode {
// Axis-aligned movement
@@ -127,7 +127,8 @@ impl App {
for bullet in &mut self.bullets {
bullet.position += bullet.velocity * dt;
}
self.bullets.retain(|b| (time - b.spawn_time) < BULLET_LIFETIME);
self.bullets
.retain(|b| (time - b.spawn_time) < BULLET_LIFETIME);
// Touch input (WASM only)
#[cfg(target_arch = "wasm32")]
@@ -381,10 +382,7 @@ impl ApplicationHandler for App {
let time = web_time::Instant::now().duration_since(start).as_secs_f32();
let dir = self.camera.look_dir();
let right = self.camera.right();
let spawn_pos = self.camera.position
- dir * 0.5
- Vec3::Z * 0.4
+ right * 0.3;
let spawn_pos = self.camera.position - dir * 0.5 - Vec3::Z * 0.4 + right * 0.3;
self.bullets.push(Bullet {
position: spawn_pos,
direction: dir,
@@ -447,11 +445,9 @@ impl ApplicationHandler for App {
let renderer = self.renderer.as_ref().unwrap();
let (_, objects) = self.scene_meshes_and_objects.as_ref().unwrap();
let scanner_blips = self.scanner.compute_blips(
self.camera.position,
self.camera.yaw,
objects,
);
let scanner_blips =
self.scanner
.compute_blips(self.camera.position, self.camera.yaw, objects);
let bullet_data: Vec<(Mat4, f32)> = self
.bullets
+239 -46
View File
@@ -119,13 +119,37 @@ fn line_segments_mesh(
let v2 = [x1 - px, y1 - py, z];
let v3 = [x1 + px, y1 + py, z];
vertices.push(Vertex { position: v0, normal, color });
vertices.push(Vertex { position: v1, normal, color });
vertices.push(Vertex { position: v2, normal, color });
vertices.push(Vertex {
position: v0,
normal,
color,
});
vertices.push(Vertex {
position: v1,
normal,
color,
});
vertices.push(Vertex {
position: v2,
normal,
color,
});
vertices.push(Vertex { position: v0, normal, color });
vertices.push(Vertex { position: v2, normal, color });
vertices.push(Vertex { position: v3, normal, color });
vertices.push(Vertex {
position: v0,
normal,
color,
});
vertices.push(Vertex {
position: v2,
normal,
color,
});
vertices.push(Vertex {
position: v3,
normal,
color,
});
}
Mesh { vertices }
@@ -206,21 +230,51 @@ impl Mesh {
// Saturated axis colors
let x_pos: [f32; 3] = [1.0, 0.15, 0.15]; // red
let y_pos: [f32; 3] = [0.15, 1.0, 0.15]; // green
let z_pos: [f32; 3] = [0.3, 0.4, 1.0]; // blue
let z_pos: [f32; 3] = [0.3, 0.4, 1.0]; // blue
let x_neg = desat(x_pos);
let y_neg = desat(y_pos);
let z_neg = desat(z_pos);
// Axis lines — split at origin into positive and negative halves
// X axis
push_box(&mut vertices, Vec3::new(0.0, -axis_hw, -axis_hw), Vec3::new(extent, axis_hw, axis_hw), x_pos);
push_box(&mut vertices, Vec3::new(-extent, -axis_hw, -axis_hw), Vec3::new(0.0, axis_hw, axis_hw), x_neg);
push_box(
&mut vertices,
Vec3::new(0.0, -axis_hw, -axis_hw),
Vec3::new(extent, axis_hw, axis_hw),
x_pos,
);
push_box(
&mut vertices,
Vec3::new(-extent, -axis_hw, -axis_hw),
Vec3::new(0.0, axis_hw, axis_hw),
x_neg,
);
// Y axis
push_box(&mut vertices, Vec3::new(-axis_hw, 0.0, -axis_hw), Vec3::new(axis_hw, extent, axis_hw), y_pos);
push_box(&mut vertices, Vec3::new(-axis_hw, -extent, -axis_hw), Vec3::new(axis_hw, 0.0, axis_hw), y_neg);
push_box(
&mut vertices,
Vec3::new(-axis_hw, 0.0, -axis_hw),
Vec3::new(axis_hw, extent, axis_hw),
y_pos,
);
push_box(
&mut vertices,
Vec3::new(-axis_hw, -extent, -axis_hw),
Vec3::new(axis_hw, 0.0, axis_hw),
y_neg,
);
// Z axis
push_box(&mut vertices, Vec3::new(-axis_hw, -axis_hw, 0.0), Vec3::new(axis_hw, axis_hw, extent), z_pos);
push_box(&mut vertices, Vec3::new(-axis_hw, -axis_hw, -extent), Vec3::new(axis_hw, axis_hw, 0.0), z_neg);
push_box(
&mut vertices,
Vec3::new(-axis_hw, -axis_hw, 0.0),
Vec3::new(axis_hw, axis_hw, extent),
z_pos,
);
push_box(
&mut vertices,
Vec3::new(-axis_hw, -axis_hw, -extent),
Vec3::new(axis_hw, axis_hw, 0.0),
z_neg,
);
// Tick marks at each integer position
let min_tick = (-extent) as i32;
@@ -238,11 +292,26 @@ impl Mesh {
};
// Ticks on X axis: small bars in Y direction
push_box(&mut vertices, Vec3::new(p - tick_hw, -tick_len, -tick_hw), Vec3::new(p + tick_hw, tick_len, tick_hw), xc);
push_box(
&mut vertices,
Vec3::new(p - tick_hw, -tick_len, -tick_hw),
Vec3::new(p + tick_hw, tick_len, tick_hw),
xc,
);
// Ticks on Y axis: small bars in X direction
push_box(&mut vertices, Vec3::new(-tick_len, p - tick_hw, -tick_hw), Vec3::new(tick_len, p + tick_hw, tick_hw), yc);
push_box(
&mut vertices,
Vec3::new(-tick_len, p - tick_hw, -tick_hw),
Vec3::new(tick_len, p + tick_hw, tick_hw),
yc,
);
// Ticks on Z axis: small bars in Y direction
push_box(&mut vertices, Vec3::new(-tick_hw, -tick_len, p - tick_hw), Vec3::new(tick_hw, tick_len, p + tick_hw), zc);
push_box(
&mut vertices,
Vec3::new(-tick_hw, -tick_len, p - tick_hw),
Vec3::new(tick_hw, tick_len, p + tick_hw),
zc,
);
}
Self { vertices }
@@ -420,7 +489,11 @@ impl Mesh {
for i in 0..segments {
let a0 = (i as f32 / segments as f32) * std::f32::consts::TAU;
let a1 = ((i + 1) as f32 / segments as f32) * std::f32::consts::TAU;
vertices.push(Vertex { position: center, normal, color });
vertices.push(Vertex {
position: center,
normal,
color,
});
vertices.push(Vertex {
position: [a0.cos() * radius, a0.sin() * radius, 0.0],
normal,
@@ -437,7 +510,13 @@ impl Mesh {
}
/// Thin annulus in XY plane at given z height.
pub fn ring(segments: u32, inner_radius: f32, outer_radius: f32, z: f32, color: [f32; 3]) -> Self {
pub fn ring(
segments: u32,
inner_radius: f32,
outer_radius: f32,
z: f32,
color: [f32; 3],
) -> Self {
let mut vertices = Vec::new();
let normal = [0.0, 0.0, 1.0];
@@ -450,13 +529,37 @@ impl Mesh {
let out0 = [outer_radius * a0.cos(), outer_radius * a0.sin(), z];
let out1 = [outer_radius * a1.cos(), outer_radius * a1.sin(), z];
vertices.push(Vertex { position: in0, normal, color });
vertices.push(Vertex { position: out0, normal, color });
vertices.push(Vertex { position: out1, normal, color });
vertices.push(Vertex {
position: in0,
normal,
color,
});
vertices.push(Vertex {
position: out0,
normal,
color,
});
vertices.push(Vertex {
position: out1,
normal,
color,
});
vertices.push(Vertex { position: in0, normal, color });
vertices.push(Vertex { position: out1, normal, color });
vertices.push(Vertex { position: in1, normal, color });
vertices.push(Vertex {
position: in0,
normal,
color,
});
vertices.push(Vertex {
position: out1,
normal,
color,
});
vertices.push(Vertex {
position: in1,
normal,
color,
});
}
Self { vertices }
@@ -485,32 +588,104 @@ impl Mesh {
let p0_out = [outer * a0.cos(), outer * a0.sin(), z];
let p1_out = [outer * a1.cos(), outer * a1.sin(), z];
vertices.push(Vertex { position: p0_in, normal, color });
vertices.push(Vertex { position: p0_out, normal, color });
vertices.push(Vertex { position: p1_out, normal, color });
vertices.push(Vertex {
position: p0_in,
normal,
color,
});
vertices.push(Vertex {
position: p0_out,
normal,
color,
});
vertices.push(Vertex {
position: p1_out,
normal,
color,
});
vertices.push(Vertex { position: p0_in, normal, color });
vertices.push(Vertex { position: p1_out, normal, color });
vertices.push(Vertex { position: p1_in, normal, color });
vertices.push(Vertex {
position: p0_in,
normal,
color,
});
vertices.push(Vertex {
position: p1_out,
normal,
color,
});
vertices.push(Vertex {
position: p1_in,
normal,
color,
});
}
}
// Cross lines (flat quads through center)
// X-axis line
vertices.push(Vertex { position: [-radius, -hw, z], normal, color });
vertices.push(Vertex { position: [radius, -hw, z], normal, color });
vertices.push(Vertex { position: [radius, hw, z], normal, color });
vertices.push(Vertex { position: [-radius, -hw, z], normal, color });
vertices.push(Vertex { position: [radius, hw, z], normal, color });
vertices.push(Vertex { position: [-radius, hw, z], normal, color });
vertices.push(Vertex {
position: [-radius, -hw, z],
normal,
color,
});
vertices.push(Vertex {
position: [radius, -hw, z],
normal,
color,
});
vertices.push(Vertex {
position: [radius, hw, z],
normal,
color,
});
vertices.push(Vertex {
position: [-radius, -hw, z],
normal,
color,
});
vertices.push(Vertex {
position: [radius, hw, z],
normal,
color,
});
vertices.push(Vertex {
position: [-radius, hw, z],
normal,
color,
});
// Y-axis line
vertices.push(Vertex { position: [-hw, -radius, z], normal, color });
vertices.push(Vertex { position: [hw, -radius, z], normal, color });
vertices.push(Vertex { position: [hw, radius, z], normal, color });
vertices.push(Vertex { position: [-hw, -radius, z], normal, color });
vertices.push(Vertex { position: [hw, radius, z], normal, color });
vertices.push(Vertex { position: [-hw, radius, z], normal, color });
vertices.push(Vertex {
position: [-hw, -radius, z],
normal,
color,
});
vertices.push(Vertex {
position: [hw, -radius, z],
normal,
color,
});
vertices.push(Vertex {
position: [hw, radius, z],
normal,
color,
});
vertices.push(Vertex {
position: [-hw, -radius, z],
normal,
color,
});
vertices.push(Vertex {
position: [hw, radius, z],
normal,
color,
});
vertices.push(Vertex {
position: [-hw, radius, z],
normal,
color,
});
Self { vertices }
}
@@ -556,9 +731,21 @@ impl Mesh {
.flat_map(|[a, b, c]| {
let normal = (*b - *a).cross(*c - *a).normalize();
[
Vertex { position: (*a).into(), normal: normal.into(), color },
Vertex { position: (*b).into(), normal: normal.into(), color },
Vertex { position: (*c).into(), normal: normal.into(), color },
Vertex {
position: (*a).into(),
normal: normal.into(),
color,
},
Vertex {
position: (*b).into(),
normal: normal.into(),
color,
},
Vertex {
position: (*c).into(),
normal: normal.into(),
color,
},
]
})
.collect();
@@ -567,7 +754,13 @@ impl Mesh {
}
/// Compound axis label glyph: sign (+/-) on left, letter (X/Y) on right.
pub fn axis_label(positive: bool, is_x: bool, size: f32, thickness: f32, color: [f32; 3]) -> Self {
pub fn axis_label(
positive: bool,
is_x: bool,
size: f32,
thickness: f32,
color: [f32; 3],
) -> Self {
let mut segments: Vec<([f32; 2], [f32; 2])> = Vec::new();
let s = size;
+34 -33
View File
@@ -152,12 +152,11 @@ impl Renderer {
_padding: 0.0,
};
let _scanner_camera_buffer =
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("scanner_camera_buf"),
contents: bytemuck::bytes_of(&scanner_cam_uniform),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
});
let _scanner_camera_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("scanner_camera_buf"),
contents: bytemuck::bytes_of(&scanner_cam_uniform),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
});
let scanner_camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("scanner_camera_bg"),
@@ -169,8 +168,7 @@ impl Renderer {
});
// --- Model uniform (dynamic offsets for per-object transforms) ---
let model_uniform_alignment =
device.limits().min_uniform_buffer_offset_alignment as u64;
let model_uniform_alignment = device.limits().min_uniform_buffer_offset_alignment as u64;
let model_uniform_size = std::mem::size_of::<ModelUniform>() as u64;
// Each slot is padded to alignment
let slot_size = model_uniform_alignment.max(model_uniform_size);
@@ -274,15 +272,15 @@ impl Renderer {
// --- Scanner meshes ---
let scanner_mesh_start = gpu_meshes.len();
let scanner_meshes = [
Mesh::disc(64, 1.0, [0.02, 0.05, 0.02]), // 0: scanner disc
Mesh::scanner_grid(3, 1.0, 0.008, [0.0, 0.25, 0.0]), // 1: grid
Mesh::ring(64, 0.97, 1.0, 0.002, [0.0, 0.5, 0.0]), // 2: border ring
Mesh::octahedron([0.0, 1.0, 0.0]), // 3: blip dot
Mesh::thin_box(0.015, 1.0, [0.0, 0.5, 0.0]), // 4: blip stalk
Mesh::disc(32, 1.0, [0.0, 0.0, 0.0]), // 5: black panel bg
Mesh::axis_label(true, true, 1.0, 0.25, [0.7, 0.2, 0.2]), // 6: +X label
Mesh::axis_label(false, true, 1.0, 0.25, [0.7, 0.2, 0.2]), // 7: -X label
Mesh::axis_label(true, false, 1.0, 0.25, [0.2, 0.7, 0.2]), // 8: +Y label
Mesh::disc(64, 1.0, [0.02, 0.05, 0.02]), // 0: scanner disc
Mesh::scanner_grid(3, 1.0, 0.008, [0.0, 0.25, 0.0]), // 1: grid
Mesh::ring(64, 0.97, 1.0, 0.002, [0.0, 0.5, 0.0]), // 2: border ring
Mesh::octahedron([0.0, 1.0, 0.0]), // 3: blip dot
Mesh::thin_box(0.015, 1.0, [0.0, 0.5, 0.0]), // 4: blip stalk
Mesh::disc(32, 1.0, [0.0, 0.0, 0.0]), // 5: black panel bg
Mesh::axis_label(true, true, 1.0, 0.25, [0.7, 0.2, 0.2]), // 6: +X label
Mesh::axis_label(false, true, 1.0, 0.25, [0.7, 0.2, 0.2]), // 7: -X label
Mesh::axis_label(true, false, 1.0, 0.25, [0.2, 0.7, 0.2]), // 8: +Y label
Mesh::axis_label(false, false, 1.0, 0.25, [0.2, 0.7, 0.2]), // 9: -Y label
];
for m in &scanner_meshes {
@@ -357,9 +355,9 @@ impl Renderer {
});
// Write all per-object transforms to the dynamic uniform buffer
let slot_size = self.model_uniform_alignment.max(
std::mem::size_of::<ModelUniform>() as u64,
);
let slot_size = self
.model_uniform_alignment
.max(std::mem::size_of::<ModelUniform>() as u64);
for (i, obj) in objects.iter().enumerate() {
let transform = obj.transform(time);
let model_uniform = ModelUniform {
@@ -368,8 +366,11 @@ impl Renderer {
_padding: [0.0; 3],
};
let offset = i as u64 * slot_size;
self.queue
.write_buffer(&self.model_buffer, offset, bytemuck::bytes_of(&model_uniform));
self.queue.write_buffer(
&self.model_buffer,
offset,
bytemuck::bytes_of(&model_uniform),
);
}
// Write bullet uniforms after scene objects
@@ -391,7 +392,9 @@ impl Renderer {
bytemuck::bytes_of(&uniform),
);
}
let num_bullets_drawn = bullets.len().min(MAX_OBJECTS.saturating_sub(bullet_base_slot));
let num_bullets_drawn = bullets
.len()
.min(MAX_OBJECTS.saturating_sub(bullet_base_slot));
{
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
@@ -488,14 +491,14 @@ impl Renderer {
let label_radius = 1.12;
let label_scale = 0.09;
let label_positions = [
Vec3::new( yaw.sin() * label_radius, yaw.cos() * label_radius, 0.003), // +X
Vec3::new(yaw.sin() * label_radius, yaw.cos() * label_radius, 0.003), // +X
Vec3::new(-yaw.sin() * label_radius, -yaw.cos() * label_radius, 0.003), // -X
Vec3::new(-yaw.cos() * label_radius, yaw.sin() * label_radius, 0.003), // +Y
Vec3::new( yaw.cos() * label_radius, -yaw.sin() * label_radius, 0.003), // -Y
Vec3::new(-yaw.cos() * label_radius, yaw.sin() * label_radius, 0.003), // +Y
Vec3::new(yaw.cos() * label_radius, -yaw.sin() * label_radius, 0.003), // -Y
];
for (i, pos) in label_positions.iter().enumerate() {
let transform = Mat4::from_translation(*pos)
* Mat4::from_scale(Vec3::splat(label_scale));
let transform =
Mat4::from_translation(*pos) * Mat4::from_scale(Vec3::splat(label_scale));
let uniform = ModelUniform {
transform: transform.to_cols_array_2d(),
opacity: 1.0,
@@ -535,11 +538,9 @@ impl Renderer {
} else {
(blip.altitude, (-blip.altitude).max(0.001))
};
let stalk_transform = Mat4::from_translation(Vec3::new(
blip.disc_pos.x,
blip.disc_pos.y,
stalk_z,
)) * Mat4::from_scale(Vec3::new(1.0, 1.0, stalk_h));
let stalk_transform =
Mat4::from_translation(Vec3::new(blip.disc_pos.x, blip.disc_pos.y, stalk_z))
* Mat4::from_scale(Vec3::new(1.0, 1.0, stalk_h));
let uniform = ModelUniform {
transform: stalk_transform.to_cols_array_2d(),
opacity: 1.0,
+7 -2
View File
@@ -80,7 +80,11 @@ pub fn build_scene() -> (Vec<Mesh>, Vec<SceneObject>) {
// Rotating spiked ball at origin
let spiked_ball_index = meshes.len();
meshes.push(Mesh::icosphere_with_spike(2, [0.3, 0.5, 1.0], [1.0, 0.3, 0.35]));
meshes.push(Mesh::icosphere_with_spike(
2,
[0.3, 0.5, 1.0],
[1.0, 0.3, 0.35],
));
objects.push(SceneObject {
mesh_index: spiked_ball_index,
position: Vec3::ZERO,
@@ -109,7 +113,8 @@ pub fn build_scene() -> (Vec<Mesh>, Vec<SceneObject>) {
)
.normalize_or(Vec3::Z);
let rotation_speed = rng.random_range(0.2..1.5) * if rng.random_bool(0.5) { 1.0 } else { -1.0 };
let rotation_speed =
rng.random_range(0.2..1.5) * if rng.random_bool(0.5) { 1.0 } else { -1.0 };
let scale = rng.random_range(0.5..2.5);
let base_rotation = rng.random_range(0.0..std::f32::consts::TAU);