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
|
||||
|
||||
use matrix::{Matrix, Mat4};
|
||||
use plane::Plane;
|
||||
use point::Point3;
|
||||
use vector::{Vector, EuclideanVector};
|
||||
|
||||
#[deriving(Clone, Eq)]
|
||||
pub struct Frustum<S> {
|
||||
|
@ -28,6 +30,32 @@ pub struct Frustum<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)]
|
||||
pub struct FrustumPoints<S> {
|
||||
near_top_left: Point3<S>,
|
||||
|
|
|
@ -13,10 +13,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::cast::transmute;
|
||||
|
||||
use intersect::Intersect;
|
||||
use point::{Point, Point3};
|
||||
use ray::Ray3;
|
||||
use vector::{Vector, EuclideanVector, Vec3};
|
||||
use vector::{Vec3, Vec4};
|
||||
use vector::{Vector, EuclideanVector};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
@ -57,6 +60,11 @@ impl<S: Float> Plane<S> {
|
|||
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`
|
||||
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
|
||||
|
|
|
@ -18,6 +18,7 @@ use std::num::{zero, one, cast};
|
|||
use angle::{Angle, tan, cot};
|
||||
use frustum::Frustum;
|
||||
use matrix::{Mat4, ToMat4};
|
||||
use plane::Plane;
|
||||
|
||||
/// 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> {
|
||||
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> {
|
||||
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> {
|
||||
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