Add frustum constructors and use to implement Projection->Frustum conversions
This commit is contained in:
parent
8c17832bf8
commit
279aa261a8
3 changed files with 50 additions and 4 deletions
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
//! View frustum for visibility determination
|
//! View frustum for visibility determination
|
||||||
|
|
||||||
|
use matrix::{Matrix, Mat4};
|
||||||
use plane::Plane;
|
use plane::Plane;
|
||||||
use point::Point3;
|
use point::Point3;
|
||||||
|
use vector::{Vector, EuclideanVector};
|
||||||
|
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Frustum<S> {
|
pub struct Frustum<S> {
|
||||||
|
@ -28,6 +30,32 @@ pub struct Frustum<S> {
|
||||||
far: Plane<S>,
|
far: Plane<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Float> Frustum<S> {
|
||||||
|
/// Constructs a frustum
|
||||||
|
pub fn new(left: Plane<S>, right: Plane<S>,
|
||||||
|
bottom: Plane<S>, top: Plane<S>,
|
||||||
|
near: Plane<S>, far: Plane<S>) -> Frustum<S> {
|
||||||
|
Frustum {
|
||||||
|
left: left,
|
||||||
|
right: right,
|
||||||
|
bottom: bottom,
|
||||||
|
top: top,
|
||||||
|
near: near,
|
||||||
|
far: far,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts frustum planes from a projection matrix
|
||||||
|
pub fn from_mat4(mat: Mat4<S>) -> Frustum<S> {
|
||||||
|
Frustum::new(Plane::from_vec4(mat.r(3).add_v(&mat.r(0)).normalize()),
|
||||||
|
Plane::from_vec4(mat.r(3).sub_v(&mat.r(0)).normalize()),
|
||||||
|
Plane::from_vec4(mat.r(3).add_v(&mat.r(1)).normalize()),
|
||||||
|
Plane::from_vec4(mat.r(3).sub_v(&mat.r(1)).normalize()),
|
||||||
|
Plane::from_vec4(mat.r(3).add_v(&mat.r(2)).normalize()),
|
||||||
|
Plane::from_vec4(mat.r(3).sub_v(&mat.r(2)).normalize()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct FrustumPoints<S> {
|
pub struct FrustumPoints<S> {
|
||||||
near_top_left: Point3<S>,
|
near_top_left: Point3<S>,
|
||||||
|
|
|
@ -13,10 +13,13 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::cast::transmute;
|
||||||
|
|
||||||
use intersect::Intersect;
|
use intersect::Intersect;
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use ray::Ray3;
|
use ray::Ray3;
|
||||||
use vector::{Vector, EuclideanVector, Vec3};
|
use vector::{Vec3, Vec4};
|
||||||
|
use vector::{Vector, EuclideanVector};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
@ -57,6 +60,11 @@ impl<S: Float> Plane<S> {
|
||||||
Plane { n: Vec3::new(a, b, c), d: d }
|
Plane { n: Vec3::new(a, b, c), d: d }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a plane from the components of a four-dimensional vector
|
||||||
|
pub fn from_vec4(v: Vec4<S>) -> Plane<S> {
|
||||||
|
unsafe { transmute(v) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a plane that passes through the the three points `a`, `b` and `c`
|
/// Constructs a plane that passes through the the three points `a`, `b` and `c`
|
||||||
pub fn from_points(a: Point3<S>, b: Point3<S>, c: Point3<S>) -> Option<Plane<S>> {
|
pub fn from_points(a: Point3<S>, b: Point3<S>, c: Point3<S>) -> Option<Plane<S>> {
|
||||||
// create two vectors that run parallel to the plane
|
// create two vectors that run parallel to the plane
|
||||||
|
|
|
@ -18,6 +18,7 @@ use std::num::{zero, one, cast};
|
||||||
use angle::{Angle, tan, cot};
|
use angle::{Angle, tan, cot};
|
||||||
use frustum::Frustum;
|
use frustum::Frustum;
|
||||||
use matrix::{Mat4, ToMat4};
|
use matrix::{Mat4, ToMat4};
|
||||||
|
use plane::Plane;
|
||||||
|
|
||||||
/// Create a perspective projection matrix.
|
/// Create a perspective projection matrix.
|
||||||
///
|
///
|
||||||
|
@ -94,7 +95,8 @@ impl<S: Float, A: Angle<S>> PerspectiveFov<S, A> {
|
||||||
|
|
||||||
impl<S: Float, A: Angle<S>> Projection<S> for PerspectiveFov<S, A> {
|
impl<S: Float, A: Angle<S>> Projection<S> for PerspectiveFov<S, A> {
|
||||||
fn to_frustum(&self) -> Frustum<S> {
|
fn to_frustum(&self) -> Frustum<S> {
|
||||||
self.to_perspective().to_frustum()
|
// TODO: Could this be faster?
|
||||||
|
Frustum::from_mat4(self.to_mat4())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +150,8 @@ pub struct Perspective<S> {
|
||||||
|
|
||||||
impl<S: Float> Projection<S> for Perspective<S> {
|
impl<S: Float> Projection<S> for Perspective<S> {
|
||||||
fn to_frustum(&self) -> Frustum<S> {
|
fn to_frustum(&self) -> Frustum<S> {
|
||||||
fail!("Not yet implemented!");
|
// TODO: Could this be faster?
|
||||||
|
Frustum::from_mat4(self.to_mat4())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +198,14 @@ pub struct Ortho<S> {
|
||||||
|
|
||||||
impl<S: Float> Projection<S> for Ortho<S> {
|
impl<S: Float> Projection<S> for Ortho<S> {
|
||||||
fn to_frustum(&self) -> Frustum<S> {
|
fn to_frustum(&self) -> Frustum<S> {
|
||||||
fail!("Not yet implemented!");
|
Frustum {
|
||||||
|
left: Plane::from_abcd( one::<S>(), zero::<S>(), zero::<S>(), self.left.clone()),
|
||||||
|
right: Plane::from_abcd(-one::<S>(), zero::<S>(), zero::<S>(), self.right.clone()),
|
||||||
|
bottom: Plane::from_abcd(zero::<S>(), one::<S>(), zero::<S>(), self.bottom.clone()),
|
||||||
|
top: Plane::from_abcd(zero::<S>(), -one::<S>(), zero::<S>(), self.top.clone()),
|
||||||
|
near: Plane::from_abcd(zero::<S>(), zero::<S>(), -one::<S>(), self.near.clone()),
|
||||||
|
far: Plane::from_abcd(zero::<S>(), zero::<S>(), one::<S>(), self.far.clone()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue