Initial work on rollback and refactor

This commit is contained in:
2026-08-12 12:27:35 +02:00
parent ad6c1e17ac
commit a21f24b2d9
45 changed files with 1451 additions and 717 deletions
+16
View File
@@ -0,0 +1,16 @@
use bevy::{color::palettes::css::RED, prelude::*};
use crate::stage::StageLine;
pub fn debug_draw_scene(mut gizmos: Gizmos, planes: Query<&StageLine>) {
for plane in planes {
let from = plane.segment.point1();
let to = plane.segment.point2();
let from_3d = Vec3::new(from.x, from.y, 0.0);
let end_3d = Vec3::new(to.x, to.y, 0.0);
let normal_3d = Vec3::new(plane.normal.x, plane.normal.y, 0.0);
gizmos.line(from_3d, end_3d, RED);
let midpoint = (from_3d + end_3d) * 0.5;
gizmos.arrow(midpoint, midpoint + normal_3d, RED);
}
}
+34
View File
@@ -0,0 +1,34 @@
//! Stage collision geometry.
use bevy::{math::InvalidDirectionError, prelude::*};
use crate::math::SegmentIntersection;
#[derive(Component, Reflect, Clone, Default)]
#[reflect(Component)]
pub struct StageLine {
pub segment: Segment2d,
pub normal: Vec2,
}
pub struct StagePlaneIntersectResult {
pub position: Vec2,
}
impl StageLine {
pub fn new(start: Vec2, end: Vec2) -> Result<Self, InvalidDirectionError> {
let segment = Segment2d::new(start, end);
let normal = segment.left_normal().as_vec2();
Ok(Self { segment, normal })
}
pub fn intersect_ray(&self, segment: Segment2d) -> Option<StagePlaneIntersectResult> {
self.segment
.segment_intersection(&segment)
.map(|position| StagePlaneIntersectResult { position })
}
pub fn project(&self, vec: Vec2) -> Vec2 {
vec - vec.project_onto_normalized(self.normal)
}
}
+14 -80
View File
@@ -1,87 +1,21 @@
use bevy::{color::palettes::css::{GREEN, RED}, prelude::*};
//! The stage: its collision geometry, the scene that gets spawned, and how
//! both are drawn.
#[derive(Component, Reflect, Clone, Default)]
#[reflect(Component)]
pub struct StagePlane {
pub plane: Plane2d,
pub position: Vec2,
half_size: f32,
basis_x: Vec2,
}
use bevy::prelude::*;
pub struct StagePlaneIntersectResult {
pub position: Vec2
}
pub mod debug;
pub mod line;
pub mod scene;
impl StagePlane {
pub fn new(normal: Dir2, half_size: f32, position: Vec2) -> Self {
let orthogonal = normal.perp();
let basis_x = orthogonal * half_size;
pub use line::{StageLine, StagePlaneIntersectResult};
Self {
plane: Plane2d::new(*normal),
position,
half_size,
basis_x,
}
}
pub fn intersect_ray(&self, ray: Ray2d) -> Option<StagePlaneIntersectResult> {
if let Some(result) = ray.plane_intersection_point(self.position, self.plane) {
return Some(StagePlaneIntersectResult {
position: result
});
}
None
}
/// Owns the stage geometry: which scene gets spawned and how it is drawn.
#[derive(Default)]
pub struct StagePlugin;
pub fn project(&self, vec: Vec2) -> Vec2 {
vec - vec.project_onto_normalized(self.plane.normal.as_vec2())
impl Plugin for StagePlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, scene::test_scene.spawn())
.add_systems(Update, debug::debug_draw_scene);
}
}
pub fn debug_draw_scene(mut gizmos: Gizmos, planes: Query<&StagePlane>) {
for plane in planes {
let plane_pos_3d = Vec3::new(plane.position.x, plane.position.y, 0.0);
let plane_normal_3d = Vec3::new(plane.plane.normal.x, plane.plane.normal.y, 0.0);
let plane_basis_x_3d = Vec3::new(plane.basis_x.x, plane.basis_x.y, 0.0);
gizmos.rect(
Transform::from_translation(plane_pos_3d).looking_to(plane_normal_3d, Dir3::Z).to_isometry(),
Vec2::new(plane.half_size * 2.0, 1.0),
GREEN,
);
gizmos.line(plane_pos_3d, plane_pos_3d + plane_basis_x_3d, RED);
}
}
/// set up a simple 3D scene
pub fn test_scene() -> impl SceneList {
let up = Dir2::Y;
bsn_list! [
(
#Cube
Mesh3d(asset_value(Cuboid::new(5.0, 1.0, 1.0)))
MeshMaterial3d::<StandardMaterial>(asset_value(Color::srgb_u8(124, 144, 255)))
Transform::from_xyz(0.0, 0.5, 0.0)
),
(
#StagePlane
template_value(StagePlane::new(up, 2.5, Vec2::new(0.0, 1.0)))
),
(
PointLight {
shadow_maps_enabled: true,
}
Transform::from_xyz(4.0, 8.0, 4.0)
),
(
Camera3d
template_value(Transform::from_xyz(0.0, 1.5, 9.0))
/*FreeCamera {
sensitivity: 0.2,
friction: 25.0,
walk_speed: 3.0,
run_speed: 9.0,
}*/
)
]
}
+37
View File
@@ -0,0 +1,37 @@
//! The scene content that gets spawned at startup.
use bevy::prelude::*;
use crate::stage::StageLine;
/// set up a simple 3D scene
pub fn test_scene() -> impl SceneList {
bsn_list! [
(
#Cube
Mesh3d(asset_value(Cuboid::new(5.0, 1.0, 1.0)))
MeshMaterial3d::<StandardMaterial>(asset_value(Color::srgb_u8(124, 144, 255)))
Transform::from_xyz(0.0, 0.5, 0.0)
),
(
#StagePlane
template_value(StageLine::new(Vec2::new(-2.5, 1.0), Vec2::new(2.5, 1.0)).unwrap())
),
(
PointLight {
shadow_maps_enabled: true,
}
Transform::from_xyz(4.0, 8.0, 4.0)
),
(
Camera3d
template_value(Transform::from_xyz(0.0, 1.5, 9.0))
/*FreeCamera {
sensitivity: 0.2,
friction: 25.0,
walk_speed: 3.0,
run_speed: 9.0,
}*/
)
]
}