PBRT
|
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 ¶meter) 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