Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

frustum.cpp

Go to the documentation of this file.
00001 // frustum.cpp
00002 // 
00003 // Copyright (C) 2000, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include "frustum.h"
00011 
00012 
00013 Frustum::Frustum(float fov, float aspectRatio, float n) :
00014     infinite(true)
00015 {
00016     init(fov, aspectRatio, n, n);
00017 }
00018 
00019 
00020 Frustum::Frustum(float fov, float aspectRatio, float n, float f) :
00021     infinite(false)
00022 {
00023     init(fov, aspectRatio, n, f);
00024 }
00025 
00026 
00027 void Frustum::init(float fov, float aspectRatio, float n, float f)
00028 {
00029     float h = (float) tan(fov / 2.0f);
00030     float w = h * aspectRatio;
00031 
00032     Vec3f normals[4];
00033     normals[Bottom] = Vec3f(0, 1, -h);
00034     normals[Top]    = Vec3f(0, -1, -h);
00035     normals[Left]   = Vec3f(1, 0, -w);
00036     normals[Right]  = Vec3f(-1, 0, -w);
00037     for (int i = 0; i < 4; i++)
00038     {
00039         normals[i].normalize();
00040         planes[i] = Planef(normals[i], Point3f(0, 0, 0));
00041     }
00042 
00043     planes[Near] = Planef(Vec3f(0, 0, -1), -n);
00044     planes[Far] = Planef(Vec3f(0, 0, 1), f);
00045 }
00046 
00047 
00048 Frustum::Aspect Frustum::test(const Point3f& p) const
00049 {
00050     return testSphere(p, 0);
00051 }
00052 
00053 
00054 Frustum::Aspect Frustum::testSphere(const Point3f& center, float radius) const
00055 {
00056     int nPlanes = infinite ? 5 : 6;
00057     int intersections = 0;
00058 
00059     for (int i = 0; i < nPlanes; i++)
00060     {
00061         float distanceToPlane = planes[i].distanceTo(center);
00062         if (distanceToPlane < -radius)
00063             return Outside;
00064         else if (distanceToPlane <= radius)
00065             intersections |= (1 << i);
00066     }
00067 
00068     return (intersections == 0) ? Inside : Intersect;
00069 }
00070 
00071 
00072 Frustum::Aspect Frustum::testSphere(const Point3d& center, double radius) const
00073 {
00074     int nPlanes = infinite ? 5 : 6;
00075     int intersections = 0;
00076 
00077     for (int i = 0; i < nPlanes; i++)
00078     {
00079         //TODO: Celestia should incorporate some casting operators overloading to accomodate all this kind of stuff:
00080         Vec3f plNormal       = planes[i].normal;
00081         Vec3d plNormalDbl(plNormal.x, plNormal.y, plNormal.z); 
00082          
00083         double distanceToPlane = plNormalDbl.x * center.x + plNormalDbl.y * center.y + plNormalDbl.z * center.z + planes[i].d;        
00084         if (distanceToPlane < -radius)
00085             return Outside;
00086         else if (distanceToPlane <= radius)
00087             intersections |= (1 << i);
00088     }
00089 
00090     return (intersections == 0) ? Inside : Intersect;
00091 }
00092 
00093 #if 0
00094 // See if the half space defined by the plane intersects the frustum.  For the
00095 // plane equation p(x, y, z) = ax + by + cz + d = 0, the halfspace is
00096 // contains all points p(x, y, z) < 0.
00097 Frustum::Aspect Frustum::testHalfSpace(const Planef& plane)
00098 {
00099     return Intersect;
00100 }
00101 #endif
00102 
00103 
00104 void Frustum::transform(const Mat3f&)
00105 {
00106 }
00107 
00108 
00109 void Frustum::transform(const Mat4f& m)
00110 {
00111     int nPlanes = infinite ? 5 : 6;
00112     Mat4f invTranspose = m.inverse().transpose();
00113 
00114     for (int i = 0; i < nPlanes; i++)
00115     {
00116         planes[i] = planes[i] * invTranspose;
00117         float s = 1.0f / planes[i].normal.length();
00118         planes[i].normal = planes[i].normal * s;
00119         planes[i].d *= s;
00120     }
00121 }

Generated on Sat Jan 14 22:30:32 2006 for Celestia by  doxygen 1.4.1