Skip to content

Commit

Permalink
feat: Debug lines for colliders (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
suspistew authored Aug 21, 2021
1 parent 581fb77 commit 6198cfb
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 10 deletions.
2 changes: 1 addition & 1 deletion examples/mario/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl SimpleGameLayer for Mario {
let mut camera_transform = Transform::from_xy(-202., -320.);
camera_transform.set_global_translation_bounds(Some(0.), Some(2060.), Some(0.), Some(0.));
world.push((
Camera::new(500., 640., 10.),
Camera::new(500., 640.),
camera_transform,
Parent(self.hero.expect("Hero is mandatory")),
));
Expand Down
3 changes: 2 additions & 1 deletion examples/tetris/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use scion::{
};

use crate::{asset_path, resources::TetrisResource};
use scion::core::legion_ext::ScionWorldExtension;

#[derive(Default)]
pub struct TetrisLayer {
Expand All @@ -24,7 +25,7 @@ impl SimpleGameLayer for TetrisLayer {
add_main_ui_mask(world);
add_ui_top_overflow(world);
self.score = Some(add_score_ui(world));
world.push((Camera::new(544., 704., 10.), Transform::default()));
world.add_default_camera();
let _r = resources.timers().add_timer("piece", TimerType::Cyclic, 0.5);
let _r = resources.timers().add_timer("action_reset_timer", TimerType::Manual, 0.2);
let mut tetris = TetrisResource::default();
Expand Down
3 changes: 2 additions & 1 deletion src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::{
systems::{
animations_system::animation_executer_system,
asset_ref_resolver_system::{asset_ref_resolver_system, MaterialAssetResolverFn},
collider_systems::{colliders_cleaner_system, compute_collisions_system},
collider_systems::{colliders_cleaner_system, compute_collisions_system, debug_colliders_system},
default_camera_system::default_camera_system,
hide_propagation_system::{hide_propagated_deletion_system, hide_propagation_system},
hierarchy_system::children_manager_system,
Expand Down Expand Up @@ -276,6 +276,7 @@ impl ScionBuilder {
self.schedule_builder
.add_system(default_camera_system())
.add_system(ui_text_bitmap_update_system())
.add_system(debug_colliders_system())
.flush()
.add_system(children_manager_system())
.add_system(hide_propagated_deletion_system())
Expand Down
4 changes: 2 additions & 2 deletions src/core/components/maths/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct Camera {

impl Camera {
/// Creates a camera with a viewport of size (width;height;depth). In general the same width and height of the window.
pub fn new(width: f32, height: f32, depth: f32) -> Self {
Self { left: 0., right: width, top: 0., bottom: -1. * height, near: 0.0, far: depth }
pub fn new(width: f32, height: f32) -> Self {
Self { left: 0., right: width, top: 0., bottom: -1. * height, near: 0.0, far: 100. }
}
}
20 changes: 19 additions & 1 deletion src/core/components/maths/collider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct Collider {
collider_type: ColliderType,
collision_filter: Vec<ColliderMask>,
collisions: Vec<Collision>,
debug_lines: bool
}

impl Collider {
Expand All @@ -45,7 +46,12 @@ impl Collider {
collision_filter: Vec<ColliderMask>,
collider_type: ColliderType,
) -> Self {
Collider { collider_mask, collider_type, collision_filter, collisions: vec![] }
Collider { collider_mask, collider_type, collision_filter, collisions: vec![], debug_lines: false }
}

pub fn with_debug_lines(mut self) -> Self{
self.debug_lines = true;
self
}

/// Return whether or not this collider colliding to any other collider ?
Expand All @@ -57,6 +63,15 @@ impl Collider {
/// The mask of this collision
pub fn mask(&self) -> &ColliderMask { &self.collider_mask }

/// Retrieve the collider type of this collider
pub fn collider_type(&self) -> &ColliderType {
&self.collider_type
}

pub(crate) fn debug_lines(&self) -> bool{
self.debug_lines
}

pub(crate) fn passive(&self) -> bool {
self.collision_filter.len() == 1 && self.collision_filter.contains(&ColliderMask::None)
}
Expand Down Expand Up @@ -123,6 +138,9 @@ impl Collision {
pub fn coordinates(&self) -> &Coordinates { &self.coordinates }
}

/// Internal component used to keep track of a collider debug display
pub (crate) struct ColliderDebug;

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 1 addition & 3 deletions src/core/components/shapes/polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use crate::{
rendering::{gl_representations::TexturedGlVertex, Renderable2D},
};

const INDICES: &[u16] = &[0, 1];

/// Renderable 2D Polygon made of outlines.
pub struct Polygon {
pub vertices: Vec<Coordinates>,
Expand Down Expand Up @@ -78,5 +76,5 @@ impl Renderable2D for Polygon {

fn dirty(&self) -> bool { self.dirty }

fn set_dirty(&mut self, _is_dirty: bool) {}
fn set_dirty(&mut self, is_dirty: bool) { self.dirty = is_dirty;}
}
56 changes: 56 additions & 0 deletions src/core/systems/collider_systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ use crate::core::components::maths::{
collider::{Collider, Collision},
transform::Transform,
};
use legion::systems::CommandBuffer;
use crate::core::components::maths::hierarchy::{Children, Parent};
use crate::core::components::maths::collider::{ColliderDebug, ColliderType};
use std::collections::HashSet;
use crate::core::components::shapes::polygon::Polygon;
use crate::core::components::maths::coordinates::Coordinates;
use crate::core::components::material::Material;
use crate::core::components::color::Color;

#[system(for_each)]
pub(crate) fn colliders_cleaner(collider: &mut Collider) { collider.clear_collisions() }
Expand Down Expand Up @@ -53,6 +61,40 @@ pub(crate) fn compute_collisions(
}
}

/// System responsible to add a `ColliderDebug` component to each colliders that are in debug mode
#[system]
pub(crate) fn debug_colliders(
cmd: &mut CommandBuffer,
world: &mut SubWorld,
query_colliders: &mut Query<(Entity, &Transform, &mut Collider)>,
query_collider_debug: &mut Query<(&ColliderDebug, &Parent)>) {
let (mut collider_world, debug_world) = world.split_for_query(query_colliders);

let collider_debug: HashSet<Entity> = query_collider_debug.iter(&debug_world).map(|(_, p)| p.0).collect();

query_colliders.for_each_mut(&mut collider_world, |(entity, _, collider)| {
if collider.debug_lines() && !collider_debug.contains(entity) {
let ColliderType::Square(size) = collider.collider_type();
let size = *size as f32;
cmd.push((Parent(*entity),
ColliderDebug,
Transform::from_xyz(0., 0., 99),
Polygon::new(
vec![
Coordinates::new(0., 0.),
Coordinates::new(size, 0.),
Coordinates::new(size, size),
Coordinates::new(0., size),
Coordinates::new(0., 0.),
]
),
Material::Color(Color::new_rgb(0, 255, 0))
));
}
});
}


#[cfg(test)]
mod tests {
use legion::{EntityStore, Resources, Schedule, World};
Expand Down Expand Up @@ -127,4 +169,18 @@ mod tests {
let res = entry.get_component::<Collider>().unwrap();
assert_eq!(1, res.collisions().len());
}

#[test]
fn debug_colliders_system_test() {
let mut world = World::default();
let mut resources = Resources::default();
let mut schedule = Schedule::builder().add_system(debug_colliders_system()).build();

let collider = world.push((Transform::default(), Collider::new(ColliderMask::None, vec![], ColliderType::Square(100))
.with_debug_lines()));
schedule.execute(&mut world, &mut resources);

let res = <(&ColliderDebug, &Parent)>::query().iter(&world).count();
assert_eq!(1, res);
}
}
2 changes: 1 addition & 1 deletion src/core/systems/default_camera_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(crate) fn default_camera(
cmd.remove_component::<DefaultCamera>(*entity);
cmd.add_component(
*entity,
Camera::new(window_dimension.width() as f32, window_dimension.height() as f32, 10.),
Camera::new(window_dimension.width() as f32, window_dimension.height() as f32),
);
cmd.add_component(*entity, Transform::default());
}

0 comments on commit 6198cfb

Please # to comment.