PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/ImathPlane.h
00001 
00002 //
00003 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
00004 // Digital Ltd. LLC
00005 // 
00006 // All rights reserved.
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are
00010 // met:
00011 // *       Redistributions of source code must retain the above copyright
00012 // notice, this list of conditions and the following disclaimer.
00013 // *       Redistributions in binary form must reproduce the above
00014 // copyright notice, this list of conditions and the following disclaimer
00015 // in the documentation and/or other materials provided with the
00016 // distribution.
00017 // *       Neither the name of Industrial Light & Magic nor the names of
00018 // its contributors may be used to endorse or promote products derived
00019 // from this software without specific prior written permission. 
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00034 
00035 
00036 
00037 #ifndef INCLUDED_IMATHPLANE_H
00038 #define INCLUDED_IMATHPLANE_H
00039 
00040 //----------------------------------------------------------------------
00041 //
00042 //      template class Plane3
00043 //
00044 //      The Imath::Plane3<> class represents a half space, so the
00045 //      normal may point either towards or away from origin.  The
00046 //      plane P can be represented by Imath::Plane3 as either p or -p
00047 //      corresponding to the two half-spaces on either side of the
00048 //      plane. Any function which computes a distance will return
00049 //      either negative or positive values for the distance indicating
00050 //      which half-space the point is in. Note that reflection, and
00051 //      intersection functions will operate as expected.
00052 //
00053 //----------------------------------------------------------------------
00054 
00055 #include "ImathVec.h"
00056 #include "ImathLine.h"
00057 
00058 namespace Imath {
00059 
00060 
00061 template <class T>
00062 class Plane3
00063 {
00064   public:
00065 
00066     Vec3<T>                     normal;
00067     T                           distance;
00068 
00069     Plane3() {}
00070     Plane3(const Vec3<T> &normal, T distance);
00071     Plane3(const Vec3<T> &point, const Vec3<T> &normal);
00072     Plane3(const Vec3<T> &point1,
00073            const Vec3<T> &point2,
00074            const Vec3<T> &point3);
00075 
00076     //----------------------
00077     //  Various set methods
00078     //----------------------
00079 
00080     void                        set(const Vec3<T> &normal,
00081                                     T distance);
00082 
00083     void                        set(const Vec3<T> &point,
00084                                     const Vec3<T> &normal);
00085 
00086     void                        set(const Vec3<T> &point1,
00087                                     const Vec3<T> &point2,
00088                                     const Vec3<T> &point3 );
00089 
00090     //----------------------
00091     //  Utilities
00092     //----------------------
00093 
00094     bool                        intersect(const Line3<T> &line,
00095                                           Vec3<T> &intersection) const;
00096 
00097     bool                        intersectT(const Line3<T> &line,
00098                                            T &parameter) const;
00099 
00100     T                           distanceTo(const Vec3<T> &) const;
00101 
00102     Vec3<T>                     reflectPoint(const Vec3<T> &) const;
00103     Vec3<T>                     reflectVector(const Vec3<T> &) const;
00104 };
00105 
00106 
00107 //--------------------
00108 // Convenient typedefs
00109 //--------------------
00110 
00111 typedef Plane3<float> Plane3f;
00112 typedef Plane3<double> Plane3d;
00113 
00114 
00115 //---------------
00116 // Implementation
00117 //---------------
00118 
00119 template <class T>
00120 inline Plane3<T>::Plane3(const Vec3<T> &p0,
00121                          const Vec3<T> &p1,
00122                          const Vec3<T> &p2)
00123 {
00124     set(p0,p1,p2);
00125 }
00126 
00127 template <class T>
00128 inline Plane3<T>::Plane3(const Vec3<T> &n, T d)
00129 {
00130     set(n, d);
00131 }
00132 
00133 template <class T>
00134 inline Plane3<T>::Plane3(const Vec3<T> &p, const Vec3<T> &n)
00135 {
00136     set(p, n);
00137 }
00138 
00139 template <class T>
00140 inline void Plane3<T>::set(const Vec3<T>& point1,
00141                            const Vec3<T>& point2,
00142                            const Vec3<T>& point3)
00143 {
00144     normal = (point2 - point1) % (point3 - point1);
00145     normal.normalize();
00146     distance = normal ^ point1;
00147 }
00148 
00149 template <class T>
00150 inline void Plane3<T>::set(const Vec3<T>& point, const Vec3<T>& n)
00151 {
00152     normal = n;
00153     normal.normalize();
00154     distance = normal ^ point;
00155 }
00156 
00157 template <class T>
00158 inline void Plane3<T>::set(const Vec3<T>& n, T d)
00159 {
00160     normal = n;
00161     normal.normalize();
00162     distance = d;
00163 }
00164 
00165 template <class T>
00166 inline T Plane3<T>::distanceTo(const Vec3<T> &point) const
00167 {
00168     return (point ^ normal) - distance;
00169 }
00170 
00171 template <class T>
00172 inline Vec3<T> Plane3<T>::reflectPoint(const Vec3<T> &point) const
00173 {
00174     return normal * distanceTo(point) * -2.0 + point;
00175 }
00176 
00177 
00178 template <class T>
00179 inline Vec3<T> Plane3<T>::reflectVector(const Vec3<T> &v) const
00180 {
00181     return normal * (normal ^ v)  * 2.0 - v;
00182 }
00183 
00184 
00185 template <class T>
00186 inline bool Plane3<T>::intersect(const Line3<T>& line, Vec3<T>& point) const
00187 {
00188     T d = normal ^ line.dir;
00189     if ( d == 0.0 ) return false;
00190     T t = - ((normal ^ line.pos) - distance) /  d;
00191     point = line(t);
00192     return true;
00193 }
00194 
00195 template <class T>
00196 inline bool Plane3<T>::intersectT(const Line3<T>& line, T &t) const
00197 {
00198     T d = normal ^ line.dir;
00199     if ( d == 0.0 ) return false;
00200     t = - ((normal ^ line.pos) - distance) /  d;
00201     return true;
00202 }
00203 
00204 template<class T>
00205 std::ostream &operator<< (std::ostream &o, const Plane3<T> &plane)
00206 {
00207     return o << "(" << plane.normal << ", " << plane.distance
00208              << ")";
00209 }
00210 
00211 template<class T>
00212 Plane3<T> operator* (const Plane3<T> &plane, const Matrix44<T> &M)
00213 {
00214     //                        T
00215     //                      -1
00216     //  Could also compute M    but that would suck.
00217     //
00218 
00219     Vec3<T> dir1   = Vec3<T> (1, 0, 0) % plane.normal;
00220     T dir1Len      = dir1 ^ dir1;
00221 
00222     Vec3<T> tmp    = Vec3<T> (0, 1, 0) % plane.normal;
00223     T tmpLen       = tmp ^ tmp;
00224 
00225     if (tmpLen > dir1Len)
00226     {
00227         dir1      = tmp;
00228         dir1Len   = tmpLen;
00229     }
00230 
00231     tmp            = Vec3<T> (0, 0, 1) % plane.normal;
00232     tmpLen         = tmp ^ tmp;
00233 
00234     if (tmpLen > dir1Len)
00235     {
00236         dir1      = tmp;
00237     }
00238 
00239     Vec3<T> dir2   = dir1 % plane.normal;
00240     Vec3<T> point  = plane.distance * plane.normal;
00241 
00242     return Plane3<T> ( point         * M,
00243                       (point + dir2) * M,
00244                       (point + dir1) * M );
00245 }
00246 
00247 template<class T>
00248 Plane3<T> operator- (const Plane3<T> &plane)
00249 {
00250     return Plane3<T>(-plane.normal,-plane.distance);
00251 }
00252 
00253 
00254 } // namespace Imath
00255 
00256 #endif