#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct AABB
{
pub position: (f32, f32),
pub width: f32,
pub height: f32
}
impl AABB
{
pub fn new(position: (f32, f32), width: f32, height: f32) -> AABB
{
return AABB { position, width, height };
}
fn points(&self) -> [(f32, f32); 4]
{
return
[
(0.0, 0.0),
(self.width, 0.0),
(self.width, self.height),
(0.0, self.height)
];
}
}
impl crate::Shape for AABB
{
fn position(&self) -> (f32, f32)
{
return self.position;
}
fn set_position(&mut self, position: (f32, f32))
{
self.position = position;
}
fn num_axes(&self) -> usize
{
return 2;
}
fn get_axis(&self, index: usize, _target: (f32, f32)) -> (f32, f32)
{
return match index
{
0 => (1.0, 0.0),
_ => (0.0, 1.0)
};
}
fn project(&self, axis: (f32, f32), _normalize: bool) -> (f32, f32)
{
return crate::project(self.position, axis, &self.points());
}
fn needs_closest(&self, _index: usize) -> bool
{
return false;
}
fn get_closest(&self, target: (f32, f32)) -> (f32, f32)
{
return crate::closest(self.position, target, &self.points());
}
fn point(&self, _index: usize) -> (f32, f32)
{
return self.position;
}
}
#[cfg(test)]
mod aabb_tests
{
use super::*;
use crate::{float_equal, Shape};
#[test]
fn test_num_axes()
{
let aabb = AABB::new((1.0, 2.0), 3.0, 2.0);
assert_eq!(aabb.num_axes(), 2);
}
#[test]
fn test_get_axis()
{
let aabb = AABB::new((4.0, 10.0), 2.0, 5.0);
let axis1 = aabb.get_axis(0, (1.0, 0.0));
let axis2 = aabb.get_axis(1, (13.0, 20.0));
assert!(float_equal(axis1.0, 1.0));
assert!(float_equal(axis1.1, 0.0));
assert!(float_equal(axis2.0, 0.0));
assert!(float_equal(axis2.1, 1.0));
}
#[test]
fn test_project()
{
let aabb = AABB::new((1.0, 2.0), 3.0, 4.0);
let axis1 = (1.0, 0.0);
let axis2 = (1.0, -1.0);
let projection1 = aabb.project(axis1, true);
let projection2 = aabb.project(axis2, false);
assert!(float_equal(projection1.0, 1.0));
assert!(float_equal(projection1.1, 4.0));
assert!(float_equal(projection2.0, -5.0));
assert!(float_equal(projection2.1, 2.0));
}
#[test]
fn test_needs_closest()
{
let aabb = AABB::new((1.0, 2.0), 3.0, 2.0);
assert!(!aabb.needs_closest(1));
}
}