Refactor loading
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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),
|
||||
));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user