use {glium, log, rand_xorshift};
use rand_xorshift::XorShiftRng;
use macro_machines::def_machine_nodefault;
use gl_utils::*;
use crate::{bounding_volume, penetration, simulation};
use simulation::Simulation;
def_machine_nodefault!{
Testbed (
render_context : Render <render::resource::Default>,
rng : XorShiftRng = rand::SeedableRng::seed_from_u64 (0),
running : bool = true
) @ testbed {
STATES [
state SimulationDropTest (
playback : simulation::Playback,
simulation : Simulation = simulation::init_drop_test (render_context)
)
state SimulationCollideCapsuleCapsule (
playback : simulation::Playback,
simulation_generation : (Simulation, u64) = {
let (simulation, generation) =
simulation::init_collide_capsule_capsule (render_context, rng);
log::info!("simulation collide capsule capsule generation [{generation}]");
(simulation, generation)
}
)
state SimulationStackTest (
playback : simulation::Playback,
simulation : Simulation = simulation::init_stack_test (render_context)
)
state SimulationBallPitTest (
playback : simulation::Playback,
simulation_generation : (Simulation, u64) = {
let (simulation, generation) =
simulation::init_ball_pit_test (render_context, rng);
log::info!("simulation ball pit generation [{generation}]");
(simulation, generation)
}
)
state SimulationHullPitTest (
playback : simulation::Playback,
simulation_generation : (Simulation, u64) = {
let (simulation, generation) =
simulation::init_hull_pit_test (render_context, rng);
log::info!("simulation hull pit generation [{generation}]");
(simulation, generation)
}
)
state PenetrationCapsuleCapsule (
center_indices_lines : glium::IndexBuffer <u32> = {
use render::resource::draw3d::MeshId;
let capsule_range = render_context.resource.draw3d.instanced_meshes()
[MeshId::Capsule as usize].instances_range.clone();
glium::IndexBuffer::new (
&render_context.glium_display,
glium::index::PrimitiveType::LinesList,
&[capsule_range.start, capsule_range.start + 2,
capsule_range.start + 1, capsule_range.start + 3]
).unwrap()
}
)
state PenetrationCuboidCuboid (
center_indices_lines : glium::IndexBuffer <u32> = {
let cuboid_range = render_context.resource.draw3d
.instanced_aabb_lines().clone();
glium::IndexBuffer::new (
&render_context.glium_display,
glium::index::PrimitiveType::LinesList,
&[cuboid_range.start, cuboid_range.start + 2,
cuboid_range.start + 1, cuboid_range.start + 3]
).unwrap()
}
)
state PenetrationCapsuleCuboid (
center_indices_lines : glium::IndexBuffer <u32> = {
use render::resource::draw3d::MeshId;
let capsule_range = render_context.resource.draw3d.instanced_meshes()
[MeshId::Capsule as usize].instances_range.clone();
let cuboid_range = render_context.resource.draw3d
.instanced_aabb_lines().clone();
glium::IndexBuffer::new (
&render_context.glium_display,
glium::index::PrimitiveType::LinesList,
&[capsule_range.start, capsule_range.start + 1,
cuboid_range.start, cuboid_range.start + 1]
).unwrap()
}
)
state PenetrationTriangleTriangle ()
state PenetrationHullHull ()
state BoundingVolumeObb ()
]
EVENTS [
event ToSimulationDropTest <*> => <SimulationDropTest> ()
event StepSimulationDropTest <SimulationDropTest> ()
{ playback } => { playback.single_step = true; }
event StepReverseSimulationDropTest <SimulationDropTest> ()
{ playback } => { playback.single_step_reverse = true; }
event PauseSimulationDropTest <SimulationDropTest> ()
{ playback } => { playback.paused = true; }
event ResumeSimulationDropTest <SimulationDropTest> ()
{ playback } => { playback.paused = false; }
event UpdateSimulationDropTest <SimulationDropTest> () {
simulation, playback
} => {
simulation::update (render_context, playback, simulation)
}
event RestartSimulationDropTest <SimulationDropTest> () {
simulation
} => { simulation::restart_drop_test (render_context, simulation) }
event ToSimulationCollideCapsuleCapsule
<*> => <SimulationCollideCapsuleCapsule> ()
event StepSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ playback } => { playback.single_step = true; }
event StepReverseSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ playback } => { playback.single_step_reverse = true; }
event PauseSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ playback } => { playback.paused = true; }
event ResumeSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ playback } => { playback.paused = false; }
event UpdateSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ simulation_generation, playback } => {
simulation::update (render_context, playback, &mut simulation_generation.0)
}
event NextSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ simulation_generation } => {
let (simulation, generation_counter) = simulation_generation;
*simulation = Simulation::new_collide_capsule_capsule (rng);
*generation_counter += 1;
log::info!("simulation collide capsule capsule generation [{generation_counter}]");
}
event RestartSimulationCollideCapsuleCapsule
<SimulationCollideCapsuleCapsule> ()
{ simulation_generation } => {
simulation::restart_collide_capsule_capsule (render_context,
&mut simulation_generation.0)
}
event ToSimulationStackTest <*> => <SimulationStackTest> ()
event StepSimulationStackTest <SimulationStackTest> ()
{ playback } => { playback.single_step = true; }
event StepReverseSimulationStackTest <SimulationStackTest> ()
{ playback } => { playback.single_step_reverse = true; }
event PauseSimulationStackTest <SimulationStackTest> ()
{ playback } => { playback.paused = true; }
event ResumeSimulationStackTest <SimulationStackTest> ()
{ playback } => { playback.paused = false; }
event UpdateSimulationStackTest <SimulationStackTest> () {
simulation, playback
} => {
simulation::update (render_context, playback, simulation)
}
event RestartSimulationStackTest <SimulationStackTest> () {
simulation
} => { simulation::restart_stack_test (render_context, simulation) }
event ToSimulationBallPitTest <*> => <SimulationBallPitTest> ()
event StepSimulationBallPitTest <SimulationBallPitTest> ()
{ playback } => { playback.single_step = true; }
event StepReverseSimulationBallPitTest <SimulationBallPitTest> ()
{ playback } => { playback.single_step_reverse = true; }
event PauseSimulationBallPitTest <SimulationBallPitTest> ()
{ playback } => { playback.paused = true; }
event ResumeSimulationBallPitTest <SimulationBallPitTest> ()
{ playback } => { playback.paused = false; }
event UpdateSimulationBallPitTest <SimulationBallPitTest> () {
simulation_generation, playback
} => {
simulation::update (render_context, playback, &mut simulation_generation.0)
}
event RestartSimulationBallPitTest <SimulationBallPitTest> () {
simulation_generation
} => {
simulation::restart_ball_pit_test (render_context, &mut simulation_generation.0)
}
event NextSimulationBallPitTest
<SimulationBallPitTest> ()
{ simulation_generation } => {
let (simulation, generation_counter) = simulation_generation;
*simulation = Simulation::new_ball_pit_test (rng);
*generation_counter += 1;
log::info!("simulation ball pit test generation [{generation_counter}]");
}
event ToSimulationHullPitTest <*> => <SimulationHullPitTest> ()
event StepSimulationHullPitTest <SimulationHullPitTest> ()
{ playback } => { playback.single_step = true; }
event StepReverseSimulationHullPitTest <SimulationHullPitTest> ()
{ playback } => { playback.single_step_reverse = true; }
event PauseSimulationHullPitTest <SimulationHullPitTest> ()
{ playback } => { playback.paused = true; }
event ResumeSimulationHullPitTest <SimulationHullPitTest> ()
{ playback } => { playback.paused = false; }
event UpdateSimulationHullPitTest <SimulationHullPitTest> () {
simulation_generation, playback
} => {
simulation::update (render_context, playback, &mut simulation_generation.0)
}
event RestartSimulationHullPitTest <SimulationHullPitTest> () {
simulation_generation
} => {
simulation::restart_hull_pit_test (render_context, &mut simulation_generation.0)
}
event NextSimulationHullPitTest
<SimulationHullPitTest> ()
{ simulation_generation } => {
let (simulation, generation_counter) = simulation_generation;
*simulation = Simulation::new_hull_pit_test (rng);
*generation_counter += 1;
log::info!("simulation hull pit test generation [{generation_counter}]");
}
event ToPenetrationCapsuleCapsule <*> => <PenetrationCapsuleCapsule> ()
{} => { penetration::init_capsule_capsule (render_context, rng) }
event NextPenetrationCapsuleCapsule <PenetrationCapsuleCapsule> ()
{} => { penetration::next_capsule_capsule (render_context, rng) }
event DrawPenetrationCapsuleCapsule <PenetrationCapsuleCapsule>
(glium_frame : &'event mut glium::Frame)
{ center_indices_lines } => {
penetration::draw_capsule_capsule (
render_context, glium_frame, center_indices_lines)
}
event ToPenetrationCuboidCuboid <*> => <PenetrationCuboidCuboid> ()
{} => { penetration::init_cuboid_cuboid (render_context, rng) }
event NextPenetrationCuboidCuboid <PenetrationCuboidCuboid> ()
{} => { penetration::next_cuboid_cuboid (render_context, rng) }
event DrawPenetrationCuboidCuboid <PenetrationCuboidCuboid>
(glium_frame : &'event mut glium::Frame)
{ center_indices_lines } => {
penetration::draw_cuboid_cuboid (
render_context, glium_frame, center_indices_lines)
}
event ToPenetrationCapsuleCuboid <*> => <PenetrationCapsuleCuboid> ()
{} => { penetration::init_capsule_cuboid (render_context, rng) }
event NextPenetrationCapsuleCuboid <PenetrationCapsuleCuboid> ()
{} => { penetration::next_capsule_cuboid (render_context, rng) }
event DrawPenetrationCapsuleCuboid <PenetrationCapsuleCuboid>
(glium_frame : &'event mut glium::Frame)
{ center_indices_lines } => {
penetration::draw_capsule_cuboid (
render_context, glium_frame, center_indices_lines)
}
event ToPenetrationTriangleTriangle <*> => <PenetrationTriangleTriangle> ()
{} => { penetration::init_triangle_triangle (render_context, rng) }
event NextPenetrationTriangleTriangle <PenetrationTriangleTriangle> ()
{} => { penetration::next_triangle_triangle (render_context, rng) }
event ToPenetrationHullHull <*> => <PenetrationHullHull> ()
{} => { penetration::init_hull_hull (render_context, rng) }
event NextPenetrationHullHull <PenetrationHullHull> ()
{} => { penetration::next_hull_hull (render_context, rng) }
event ToBoundingVolumeObb <*> => <BoundingVolumeObb> ()
{} => { bounding_volume::init_obb (render_context, rng) }
event NextBoundingVolumeObb <BoundingVolumeObb> ()
{} => { bounding_volume::next_obb (render_context, rng) }
event DrawBoundingVolumeObb <BoundingVolumeObb>
(glium_frame : &'event mut glium::Frame)
{} => {
bounding_volume::draw_obb (render_context, glium_frame)
}
]
initial_state: SimulationDropTest
}
}
pub (crate) fn print_testbed_modes_prompt() {
println!(">>> linear-sim testbed modes of operation:");
println!(" Press 'SHIFT+1' for simulation tests");
println!(" Press 'SHIFT+2' for penetration resolution tests");
println!(" Press 'SHIFT+3' for bouding volume tests");
}
pub (crate) fn reset_render_context (
render : &mut Render <render::resource::Default>
) {
use render::resource::*;
use crate::{INITIAL_CLEAR_COLOR, INITIAL_2D_ZOOM, INITIAL_3D_POSITION};
render.reset();
render.clear_color = INITIAL_CLEAR_COLOR;
render.camera3d_position_set (INITIAL_3D_POSITION.into());
render.camera2d_zoom_set (INITIAL_2D_ZOOM);
let (width, height) = render.window.inner_size().into();
let [_tile_width, tile_height] = render.resource
.tile_dimensions (DefaultTilesetId::EasciiAcorn128);
let fps_row = ((height / tile_height) - 1) as i32;
let tile_2d_vertices = tile::vertices ("FPS: 0 ", (fps_row, 1));
render.resource.draw2d.tile_2d_vertices = glium::VertexBuffer::dynamic (
&render.glium_display, &tile_2d_vertices[..]
).unwrap();
render.resource.draw2d.viewport_resources_set (OVERLAY_VIEWPORT,
draw2d::ViewportResources {
draw_indices: vec![draw2d::DrawIndices {
draw_tiles: Some (draw2d::Tiles {
vertex_range: 0..tile_2d_vertices.len() as u32,
origin: (0, 0).into(),
tileset_id: DefaultTilesetId::EasciiAcorn128
}),
.. draw2d::DrawIndices::default()
}],
draw_lineloop: false,
draw_crosshair: false
}
);
let overlay = render::viewport::Builder::new (glium::Rect {
width,
height,
left: 0,
bottom: 0
}).with_camera_3d (false)
.build();
assert!(render.viewports_mut().insert (OVERLAY_VIEWPORT, overlay)
.is_none());
}