-
-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bounding sphere example using macroquad
- Loading branch information
Showing
1 changed file
with
118 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,124 @@ | ||
mod common_macroquad; | ||
|
||
extern crate nalgebra as na; | ||
|
||
use common_macroquad::{draw_polyline, lissajous_2d, mquad_from_na, na_from_mquad}; | ||
use macroquad::prelude::*; | ||
use na::{Isometry2, Vector2}; | ||
use parry2d::bounding_volume::BoundingVolume; | ||
use parry2d::bounding_volume::{Aabb, BoundingVolume}; | ||
use parry2d::shape::Ball; | ||
use parry2d::shape::Cuboid; | ||
|
||
fn main() { | ||
/* | ||
* Initialize the shapes. | ||
*/ | ||
let cube1 = Cuboid::new(Vector2::repeat(0.5)); | ||
let cube2 = Cuboid::new(Vector2::new(1.0, 0.5)); | ||
|
||
let cube1_pos = Isometry2::translation(0.0, 1.0); | ||
let cube2_pos = Isometry2::identity(); | ||
|
||
/* | ||
* Compute their bounding spheres. | ||
*/ | ||
let bounding_sphere_cube1 = cube1.bounding_sphere(&cube1_pos); | ||
let bounding_sphere_cube2 = cube2.bounding_sphere(&cube2_pos); | ||
|
||
// Merge the two spheres. | ||
let bounding_bounding_sphere = bounding_sphere_cube1.merged(&bounding_sphere_cube2); | ||
|
||
// Enlarge the cube2 bounding sphere. | ||
let loose_bounding_sphere_cube2 = bounding_sphere_cube2.loosened(1.0); | ||
|
||
// Intersection and inclusion tests. | ||
assert!(bounding_sphere_cube1.intersects(&bounding_sphere_cube2)); | ||
assert!(bounding_bounding_sphere.contains(&bounding_sphere_cube1)); | ||
assert!(bounding_bounding_sphere.contains(&bounding_sphere_cube2)); | ||
assert!(!bounding_sphere_cube2.contains(&bounding_bounding_sphere)); | ||
assert!(!bounding_sphere_cube1.contains(&bounding_bounding_sphere)); | ||
assert!(loose_bounding_sphere_cube2.contains(&bounding_sphere_cube2)); | ||
const RENDER_SCALE: f32 = 30.0; | ||
|
||
#[macroquad::main("parry2d::utils::point_in_poly2d")] | ||
async fn main() { | ||
let render_pos = Vec2::new(300.0, 300.0); | ||
|
||
loop { | ||
let elapsed_time = get_time() as f32 * 0.7; | ||
clear_background(BLACK); | ||
|
||
/* | ||
* Initialize the shapes. | ||
*/ | ||
let cube1: Cuboid = Cuboid::new(Vector2::repeat(0.5)); | ||
let cube2 = Cuboid::new(Vector2::new(1., 0.5)); | ||
|
||
let cube1_pos = na_from_mquad(lissajous_2d(elapsed_time)) * 5f32; | ||
let cube1_pos = Isometry2::translation(cube1_pos.x, cube1_pos.y); | ||
let cube2_pos = Isometry2::identity(); | ||
|
||
/* | ||
* Compute their bounding spheres. | ||
*/ | ||
let bounding_sphere_cube1 = cube1.bounding_sphere(&cube1_pos); | ||
let bounding_sphere_cube2 = cube2.bounding_sphere(&cube2_pos); | ||
|
||
// Merge the two spheres. | ||
let bounding_bounding_sphere = bounding_sphere_cube1.merged(&bounding_sphere_cube2); | ||
|
||
// Enlarge the cube2 bounding sphere. | ||
let loose_bounding_sphere_cube2 = bounding_sphere_cube2.loosened(3.0); | ||
|
||
// Intersection test | ||
let color = if bounding_sphere_cube1.intersects(&bounding_sphere_cube2) { | ||
RED | ||
} else { | ||
GREEN | ||
}; | ||
|
||
//assert!(bounding_bounding_sphere.contains(&bounding_sphere_cube1)); | ||
//assert!(bounding_bounding_sphere.contains(&bounding_sphere_cube2)); | ||
assert!(loose_bounding_sphere_cube2.contains(&bounding_sphere_cube2)); | ||
|
||
let cube1_translation = | ||
mquad_from_na(cube1_pos.translation.vector.into()) * RENDER_SCALE + render_pos; | ||
draw_cuboid(cube1, cube1_translation, color); | ||
|
||
let cube2_translation = | ||
mquad_from_na(cube2_pos.translation.vector.into()) * RENDER_SCALE + render_pos; | ||
draw_cuboid(cube2, cube2_translation, color); | ||
draw_circle_lines( | ||
bounding_sphere_cube1.center.x * RENDER_SCALE + render_pos.x, | ||
bounding_sphere_cube1.center.y * RENDER_SCALE + render_pos.y, | ||
bounding_sphere_cube1.radius * RENDER_SCALE, | ||
2f32, | ||
color, | ||
); | ||
draw_circle_lines( | ||
bounding_sphere_cube2.center.x * RENDER_SCALE + render_pos.x, | ||
bounding_sphere_cube2.center.y * RENDER_SCALE + render_pos.y, | ||
bounding_sphere_cube2.radius * RENDER_SCALE, | ||
2f32, | ||
color, | ||
); | ||
draw_circle_lines( | ||
bounding_bounding_sphere.center.x * RENDER_SCALE + render_pos.x, | ||
bounding_bounding_sphere.center.y * RENDER_SCALE + render_pos.y, | ||
bounding_bounding_sphere.radius * RENDER_SCALE, | ||
2f32, | ||
YELLOW, | ||
); | ||
|
||
// Inclusion test | ||
let color_included: Color = if loose_bounding_sphere_cube2.contains(&bounding_sphere_cube1) | ||
{ | ||
BLUE | ||
} else { | ||
MAGENTA | ||
}; | ||
draw_circle_lines( | ||
loose_bounding_sphere_cube2.center.x * RENDER_SCALE + render_pos.x, | ||
loose_bounding_sphere_cube2.center.y * RENDER_SCALE + render_pos.y, | ||
loose_bounding_sphere_cube2.radius * RENDER_SCALE, | ||
2f32, | ||
color_included, | ||
); | ||
next_frame().await | ||
} | ||
} | ||
|
||
fn draw_cuboid(cuboid: Cuboid, pos: Vec2, color: Color) { | ||
let aabb = cuboid.local_aabb(); | ||
draw_aabb(aabb, pos, color) | ||
} | ||
|
||
fn draw_aabb(aabb: Aabb, offset: Vec2, color: Color) { | ||
let mins = mquad_from_na(aabb.mins) * RENDER_SCALE + offset; | ||
let maxs = mquad_from_na(aabb.maxs) * RENDER_SCALE + offset; | ||
|
||
let line = vec![ | ||
Vec2::new(mins.x, mins.y), | ||
Vec2::new(mins.x, maxs.y), | ||
Vec2::new(maxs.x, maxs.y), | ||
Vec2::new(maxs.x, mins.y), | ||
Vec2::new(mins.x, mins.y), | ||
]; | ||
let drawable_line = line | ||
.iter() | ||
.zip(line.iter().cycle().skip(1).take(line.len())) | ||
.map(|item| (item.0.clone(), item.1.clone())) | ||
.collect(); | ||
draw_polyline(drawable_line, color); | ||
} |