Moved bound implementations into the corresponding modules

This commit is contained in:
Dzmitry Malyshau 2015-03-13 11:32:23 +03:00
parent 2722815d84
commit d3d7241c86
5 changed files with 105 additions and 49 deletions

View file

@ -20,11 +20,13 @@
//! dimension) where the slope of every line is either 0 or undefined. These
//! are useful for very cheap collision detection.
use bound::*;
use point::{Point, Point2, Point3};
use vector::{Vector, Vector2, Vector3};
use ray::{Ray2};
use intersect::Intersect;
use num::{zero, one, BaseNum, BaseFloat};
use plane::Plane;
use std::fmt;
use std::num::Float;
@ -217,3 +219,14 @@ impl<S: BaseFloat> Intersect<Option<Point2<S>>> for (Ray2<S>, Aabb2<S>) {
}
}
}
impl<S: BaseNum> Bound<S> for Aabb3<S> {
fn relate(&self, plane: &Plane<S>) -> Relation {
//TODO: match all 8 corners
match (self.min.relate(plane), self.max.relate(plane)) {
(Relation::In, Relation::In) => Relation::In,
(Relation::Out, Relation::Out) => Relation::Out,
(_, _) => Relation::Cross,
}
}
}

View file

@ -15,60 +15,22 @@
//! Generic spatial bounds.
use aabb::{Aabb, Aabb3};
use num::BaseNum;
use plane::Plane;
use point::{Point, Point3};
use sphere::Sphere;
/// Spatial relation between two objects.
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
#[repr(u8)]
pub enum Relation {
/// Completely inside
In,
/// Crosses the boundary
Cross,
/// Completely outside
Out,
/// Completely inside
In,
/// Crosses the boundary
Cross,
/// Completely outside
Out,
}
/// Generic bound.
pub trait Bound<S> {
/// Classify the spatial relation with a plane
fn relate(&self, &Plane<S>) -> Relation;
}
impl<S: BaseNum> Bound<S> for Point3<S> {
fn relate(&self, plane: &Plane<S>) -> Relation {
let dist = self.dot(&plane.n);
if dist > plane.d {
Relation::In
}else if dist < plane.d {
Relation::Out
}else {
Relation::Cross
}
}
}
impl<S: BaseNum> Bound<S> for Aabb3<S> {
fn relate(&self, plane: &Plane<S>) -> Relation {
match (self.min.relate(plane), self.max.relate(plane)) {
(Relation::In, Relation::In) => Relation::In,
(Relation::Out, Relation::Out) => Relation::Out,
(_, _) => Relation::Cross,
}
}
}
impl<S: BaseNum> Bound<S> for Sphere<S> {
fn relate(&self, plane: &Plane<S>) -> Relation {
let dist = self.center.dot(&plane.n) - plane.d;
if dist > self.radius {
Relation::In
}else if dist < - self.radius {
Relation::Out
}else {
Relation::Cross
}
}
/// Classify the spatial relation with a plane
fn relate(&self, &Plane<S>) -> Relation;
}

View file

@ -23,7 +23,9 @@ use std::ops::*;
use approx::ApproxEq;
use array::{Array1, FixedArray};
use bound::*;
use num::{BaseNum, BaseFloat, one, zero};
use plane::Plane;
use vector::*;
/// A point in 2-dimensional space.
@ -445,3 +447,16 @@ impl<S: BaseNum> fmt::Debug for Point3<S> {
write!(f, "[{:?}, {:?}, {:?}]", self.x, self.y, self.z)
}
}
impl<S: BaseNum> Bound<S> for Point3<S> {
fn relate(&self, plane: &Plane<S>) -> Relation {
let dist = self.dot(&plane.n);
if dist > plane.d {
Relation::In
}else if dist < plane.d {
Relation::Out
}else {
Relation::Cross
}
}
}

View file

@ -15,9 +15,11 @@
//! Bounding sphere
use bound::*;
use intersect::Intersect;
use num::{BaseFloat, zero};
use num::{BaseNum, BaseFloat, zero};
use point::{Point, Point3};
use plane::Plane;
use ray::Ray3;
use vector::Vector;
@ -42,3 +44,16 @@ impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
}
}
}
impl<S: BaseNum> Bound<S> for Sphere<S> {
fn relate(&self, plane: &Plane<S>) -> Relation {
let dist = self.center.dot(&plane.n) - plane.d;
if dist > self.radius {
Relation::In
}else if dist < - self.radius {
Relation::Out
}else {
Relation::Cross
}
}
}

51
tests/bound.rs Normal file
View file

@ -0,0 +1,51 @@
// Copyright 2013-2015 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate cgmath;
use cgmath::{Aabb3, Bound, Plane, Point, Point3, Relation, Sphere, Vector, vec3};
#[test]
fn point() {
let point = Point3::new(1f32, 2.0, 3.0);
let normal = vec3(0f32, -0.8, -0.36);
let plane = Plane::from_point_normal(point, normal);
assert_eq!(point.relate(&plane), Relation::Cross);
assert_eq!(point.add_v(&normal).relate(&plane), Relation::In);
assert_eq!(point.add_v(&normal.mul_s(-1.0)).relate(&plane), Relation::Out);
}
#[test]
fn sphere() {
let point = Point3::new(1f32, 2.0, 3.0);
let sphere = Sphere { center: point, radius: 1.0 };
let normal = vec3(0f32, 0.0, 1.0);
assert_eq!(sphere.relate(
&Plane::from_point_normal(point, normal)
), Relation::Cross);
assert_eq!(sphere.relate(
&Plane::from_point_normal(point.add_v(&normal.mul_s(-3.0)), normal),
), Relation::In);
assert_eq!(sphere.relate(
&Plane::from_point_normal(point.add_v(&normal.mul_s(3.0)), normal),
), Relation::Out);
}
#[test]
fn aabb() {
//TODO
}