Refactor loading

This commit is contained in:
2026-08-26 19:08:58 +02:00
parent 4ff388f9c0
commit 21a5170dbc
40 changed files with 1034 additions and 426 deletions
-1
View File
@@ -14,6 +14,5 @@ pub fn debug_draw_scene(mut gizmos: Gizmos, stage_collision: Res<StageCollision>
let midpoint = (from_3d + end_3d) * 0.5;
gizmos.arrow(midpoint, midpoint + normal_3d, RED);
}
}
}
+60 -36
View File
@@ -4,51 +4,52 @@ use std::default;
use bevy::{math::InvalidDirectionError, prelude::*};
use crate::math::{segment::{FGSegment2d}, vec::FGVec2};
use crate::math::{segment::FGSegment2d, vec::FGVec2};
#[derive(Reflect, Clone, Copy, PartialEq)]
pub enum StagePolyLineSegmentType {
Floor, Wall, Ceiling
Floor,
Wall,
Ceiling,
}
#[derive(Reflect, Clone)]
pub struct StagePolyLineSegment {
pub segment: FGSegment2d,
pub normal: FGVec2,
pub segment_type: StagePolyLineSegmentType
pub segment_type: StagePolyLineSegmentType,
}
#[derive(Reflect, Clone, Default)]
pub enum StagePolyType {
#[default]
Closed,
Platform
Platform,
}
#[derive(Reflect, Hash, Debug, Clone, Copy, Default)]
pub struct StageLineID {
pub polygon: usize,
pub segment: usize
pub segment: usize,
}
#[derive(Component, Reflect, Clone, Default)]
#[reflect(Component)]
pub struct StagePoly {
poly_type: StagePolyType,
pub segments: Vec<StagePolyLineSegment>
pub segments: Vec<StagePolyLineSegment>,
}
pub struct StagePlaneIntersectResult {
pub position: FGVec2,
pub segment_idx: usize,
pub normal: FGVec2
pub normal: FGVec2,
}
#[derive(Resource, Reflect, Clone, Default)]
#[reflect(Resource)]
pub struct StageCollision {
pub stage_polys: Vec<StagePoly>
pub stage_polys: Vec<StagePoly>,
}
impl StagePoly {
@@ -134,20 +135,22 @@ impl StagePoly {
.zip(points.iter().cycle().skip(1))
.take(segment_count);
let segments = windows.map(|segment_window| {
let (first_point, segment_type) = segment_window.0;
let (second_point, _) = segment_window.1;
let segment = FGSegment2d::new(*first_point, *second_point);
StagePolyLineSegment {
segment_type: *segment_type,
segment,
normal: segment.left_normal()
}
}).collect();
let segments = windows
.map(|segment_window| {
let (first_point, segment_type) = segment_window.0;
let (second_point, _) = segment_window.1;
let segment = FGSegment2d::new(*first_point, *second_point);
StagePolyLineSegment {
segment_type: *segment_type,
segment,
normal: segment.left_normal(),
}
})
.collect();
Self {
poly_type,
segments
segments,
}
}
}
@@ -205,7 +208,10 @@ mod tests {
};
let hit = stage_poly
.intersect_ray(FGSegment2d::new(FGVec2::lit("0", "2"), FGVec2::lit("0", "-1")))
.intersect_ray(FGSegment2d::new(
FGVec2::lit("0", "2"),
FGVec2::lit("0", "-1"),
))
.unwrap();
assert_eq!(hit.segment_idx, 1);
@@ -214,35 +220,53 @@ mod tests {
#[test]
fn ray_intersection_test() {
let stage_poly = StagePoly::build(crate::stage::line::StagePolyType::Platform, &[
(FGVec2::lit("-4.5", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("4.5", "0.0"), StagePolyLineSegmentType::Floor),
]);
let stage_poly = StagePoly::build(
crate::stage::line::StagePolyType::Platform,
&[
(FGVec2::lit("-4.5", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("4.5", "0.0"), StagePolyLineSegmentType::Floor),
],
);
let res = stage_poly.intersect_ray(FGSegment2d::new(FGVec2::lit("0.0", "1.0"), FGVec2::lit("0.0", "-1.0")));
let res = stage_poly.intersect_ray(FGSegment2d::new(
FGVec2::lit("0.0", "1.0"),
FGVec2::lit("0.0", "-1.0"),
));
assert!(res.is_some());
assert_eq!(res.unwrap().position, FGVec2::ZERO);
}
#[test]
fn ray_intersection_test_side() {
let stage_poly = StagePoly::build(crate::stage::line::StagePolyType::Platform, &[
(FGVec2::lit("-4.5", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("4.5", "0.0"), StagePolyLineSegmentType::Floor),
]);
let stage_poly = StagePoly::build(
crate::stage::line::StagePolyType::Platform,
&[
(FGVec2::lit("-4.5", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("4.5", "0.0"), StagePolyLineSegmentType::Floor),
],
);
let res = stage_poly.intersect_ray(FGSegment2d::new(FGVec2::lit("2.0", "1.0"), FGVec2::lit("2.0", "-1.0")));
let res = stage_poly.intersect_ray(FGSegment2d::new(
FGVec2::lit("2.0", "1.0"),
FGVec2::lit("2.0", "-1.0"),
));
assert!(res.is_some());
assert!(res.unwrap().position.distance(FGVec2::lit("2.0", "0.0")) < FGi32::from_bits(4));
}
#[test]
fn ray_intersection_test_diagonal() {
let stage_poly = StagePoly::build(crate::stage::line::StagePolyType::Platform, &[
(FGVec2::lit("0.0", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("2.0", "2.0"), StagePolyLineSegmentType::Floor),
]);
let stage_poly = StagePoly::build(
crate::stage::line::StagePolyType::Platform,
&[
(FGVec2::lit("0.0", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("2.0", "2.0"), StagePolyLineSegmentType::Floor),
],
);
let res = stage_poly.intersect_ray(FGSegment2d::new(FGVec2::lit("1.0", "2.0"), FGVec2::lit("1.0", "-2.0")));
let res = stage_poly.intersect_ray(FGSegment2d::new(
FGVec2::lit("1.0", "2.0"),
FGVec2::lit("1.0", "-2.0"),
));
assert!(res.is_some());
assert_eq!(res.unwrap().position, FGVec2::lit("1.0", "1.0"));
}
+10 -3
View File
@@ -7,7 +7,7 @@ pub mod debug;
pub mod line;
pub mod scene;
pub use line::{StagePoly, StagePlaneIntersectResult};
pub use line::{StagePlaneIntersectResult, StagePoly};
/// Owns the stage geometry: which scene gets spawned and how it is drawn.
#[derive(Default)]
@@ -15,7 +15,14 @@ pub struct StagePlugin;
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);
app.add_systems(
Update,
debug::debug_draw_scene.run_if(resource_exists::<line::StageCollision>),
);
}
}
pub fn spawn_stage(commands: &mut Commands, match_root: Entity, visual: Handle<WorldAsset>) {
commands.entity(match_root).insert(WorldAssetRoot(visual));
scene::spawn_stage_support(commands, match_root);
}
+59 -41
View File
@@ -1,49 +1,67 @@
//! The scene content that gets spawned at startup.
//! Code-defined deterministic stage collision and development lighting.
use std::f32::consts::PI;
use bevy::{camera_controller::free_camera::FreeCamera, prelude::*};
use crate::{math::vec::FGVec2, stage::{StagePoly, line::{StageCollision, StagePolyLineSegmentType}}};
use crate::{
math::vec::FGVec2,
stage::{
StagePoly,
line::{StageCollision, StagePolyLineSegmentType, StagePolyType},
},
};
/// set up a simple 3D scene
pub fn test_scene() -> impl SceneList {
pub fn spawn_stage_support(commands: &mut Commands, match_root: Entity) {
let stage_poly = StagePoly::build(
StagePolyType::Closed,
&[
(
FGVec2::lit("-56.0", "-3.5"),
StagePolyLineSegmentType::Floor,
),
(FGVec2::lit("-39.2", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("0.0", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("39.2", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("56.0", "-3.5"), StagePolyLineSegmentType::Wall),
(
FGVec2::lit("56.0", "-200.0"),
StagePolyLineSegmentType::Ceiling,
),
(FGVec2::lit("-56", "-200.0"), StagePolyLineSegmentType::Wall),
],
);
let stage_poly = StagePoly::build(crate::stage::line::StagePolyType::Closed, &[
(FGVec2::lit("-56.0", "-3.5"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("-39.2", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("0.0", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("39.2", "0.0"), StagePolyLineSegmentType::Floor),
(FGVec2::lit("56.0", "-3.5"), StagePolyLineSegmentType::Wall),
(FGVec2::lit("56.0", "-200.0"), StagePolyLineSegmentType::Ceiling),
(FGVec2::lit("-56", "-200.0"), StagePolyLineSegmentType::Wall)
]);
bsn_list! [
(
#StageCollision
template_value(StageCollision {
stage_polys: vec!(stage_poly)
})
),
(
DirectionalLight {
shadow_maps_enabled: true,
}
Transform {
translation: Vec3::new(0.0, 2.0, 0.0),
rotation: Quat::from_rotation_x(-PI / 4.),
}
),
(
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,
}
)
]
commands.insert_resource(StageCollision {
stage_polys: vec![stage_poly.clone()],
});
commands.spawn((
Name::new("Stage Collision"),
stage_poly,
ChildOf(match_root),
));
commands.spawn((
DirectionalLight {
shadow_maps_enabled: true,
..default()
},
Transform {
translation: Vec3::new(0.0, 2.0, 0.0),
rotation: Quat::from_rotation_x(-PI / 4.0),
..default()
},
ChildOf(match_root),
));
commands.spawn((
Camera3d::default(),
Transform::from_xyz(0.0, 10.5, 150.0),
/*FreeCamera {
sensitivity: 0.2,
friction: 25.0,
walk_speed: 3.0,
run_speed: 9.0,
..default()
},*/
ChildOf(match_root),
));
}