1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas 4 // Digital Ltd. LLC 5 // 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions are 10 // met: 11 // * Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // * Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following disclaimer 15 // in the documentation and/or other materials provided with the 16 // distribution. 17 // * Neither the name of Industrial Light & Magic nor the names of 18 // its contributors may be used to endorse or promote products derived 19 // from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 // 33 /////////////////////////////////////////////////////////////////////////// 34 35 36 37 #ifndef INCLUDED_IMATHPLANE_H 38 #define INCLUDED_IMATHPLANE_H 39 40 //---------------------------------------------------------------------- 41 // 42 // template class Plane3 43 // 44 // The Imath::Plane3<> class represents a half space, so the 45 // normal may point either towards or away from origin. The 46 // plane P can be represented by Imath::Plane3 as either p or -p 47 // corresponding to the two half-spaces on either side of the 48 // plane. Any function which computes a distance will return 49 // either negative or positive values for the distance indicating 50 // which half-space the point is in. Note that reflection, and 51 // intersection functions will operate as expected. 52 // 53 //---------------------------------------------------------------------- 54 55 #include "ImathVec.h" 56 #include "ImathLine.h" 57 58 namespace Imath { 59 60 61 template <class T> 62 class Plane3 63 { 64 public: 65 66 Vec3<T> normal; 67 T distance; 68 69 Plane3() {} 70 Plane3(const Vec3<T> &normal, T distance); 71 Plane3(const Vec3<T> &point, const Vec3<T> &normal); 72 Plane3(const Vec3<T> &point1, 73 const Vec3<T> &point2, 74 const Vec3<T> &point3); 75 76 //---------------------- 77 // Various set methods 78 //---------------------- 79 80 void set(const Vec3<T> &normal, 81 T distance); 82 83 void set(const Vec3<T> &point, 84 const Vec3<T> &normal); 85 86 void set(const Vec3<T> &point1, 87 const Vec3<T> &point2, 88 const Vec3<T> &point3 ); 89 90 //---------------------- 91 // Utilities 92 //---------------------- 93 94 bool intersect(const Line3<T> &line, 95 Vec3<T> &intersection) const; 96 97 bool intersectT(const Line3<T> &line, 98 T ¶meter) const; 99 100 T distanceTo(const Vec3<T> &) const; 101 102 Vec3<T> reflectPoint(const Vec3<T> &) const; 103 Vec3<T> reflectVector(const Vec3<T> &) const; 104 }; 105 106 107 //-------------------- 108 // Convenient typedefs 109 //-------------------- 110 111 typedef Plane3<float> Plane3f; 112 typedef Plane3<double> Plane3d; 113 114 115 //--------------- 116 // Implementation 117 //--------------- 118 119 template <class T> 120 inline Plane3<T>::Plane3(const Vec3<T> &p0, 121 const Vec3<T> &p1, 122 const Vec3<T> &p2) 123 { 124 set(p0,p1,p2); 125 } 126 127 template <class T> 128 inline Plane3<T>::Plane3(const Vec3<T> &n, T d) 129 { 130 set(n, d); 131 } 132 133 template <class T> 134 inline Plane3<T>::Plane3(const Vec3<T> &p, const Vec3<T> &n) 135 { 136 set(p, n); 137 } 138 139 template <class T> 140 inline void Plane3<T>::set(const Vec3<T>& point1, 141 const Vec3<T>& point2, 142 const Vec3<T>& point3) 143 { 144 normal = (point2 - point1) % (point3 - point1); 145 normal.normalize(); 146 distance = normal ^ point1; 147 } 148 149 template <class T> 150 inline void Plane3<T>::set(const Vec3<T>& point, const Vec3<T>& n) 151 { 152 normal = n; 153 normal.normalize(); 154 distance = normal ^ point; 155 } 156 157 template <class T> 158 inline void Plane3<T>::set(const Vec3<T>& n, T d) 159 { 160 normal = n; 161 normal.normalize(); 162 distance = d; 163 } 164 165 template <class T> 166 inline T Plane3<T>::distanceTo(const Vec3<T> &point) const 167 { 168 return (point ^ normal) - distance; 169 } 170 171 template <class T> 172 inline Vec3<T> Plane3<T>::reflectPoint(const Vec3<T> &point) const 173 { 174 return normal * distanceTo(point) * -2.0 + point; 175 } 176 177 178 template <class T> 179 inline Vec3<T> Plane3<T>::reflectVector(const Vec3<T> &v) const 180 { 181 return normal * (normal ^ v) * 2.0 - v; 182 } 183 184 185 template <class T> 186 inline bool Plane3<T>::intersect(const Line3<T>& line, Vec3<T>& point) const 187 { 188 T d = normal ^ line.dir; 189 if ( d == 0.0 ) return false; 190 T t = - ((normal ^ line.pos) - distance) / d; 191 point = line(t); 192 return true; 193 } 194 195 template <class T> 196 inline bool Plane3<T>::intersectT(const Line3<T>& line, T &t) const 197 { 198 T d = normal ^ line.dir; 199 if ( d == 0.0 ) return false; 200 t = - ((normal ^ line.pos) - distance) / d; 201 return true; 202 } 203 204 template<class T> 205 std::ostream &operator<< (std::ostream &o, const Plane3<T> &plane) 206 { 207 return o << "(" << plane.normal << ", " << plane.distance 208 << ")"; 209 } 210 211 template<class T> 212 Plane3<T> operator* (const Plane3<T> &plane, const Matrix44<T> &M) 213 { 214 // T 215 // -1 216 // Could also compute M but that would suck. 217 // 218 219 Vec3<T> dir1 = Vec3<T> (1, 0, 0) % plane.normal; 220 T dir1Len = dir1 ^ dir1; 221 222 Vec3<T> tmp = Vec3<T> (0, 1, 0) % plane.normal; 223 T tmpLen = tmp ^ tmp; 224 225 if (tmpLen > dir1Len) 226 { 227 dir1 = tmp; 228 dir1Len = tmpLen; 229 } 230 231 tmp = Vec3<T> (0, 0, 1) % plane.normal; 232 tmpLen = tmp ^ tmp; 233 234 if (tmpLen > dir1Len) 235 { 236 dir1 = tmp; 237 } 238 239 Vec3<T> dir2 = dir1 % plane.normal; 240 Vec3<T> point = plane.distance * plane.normal; 241 242 return Plane3<T> ( point * M, 243 (point + dir2) * M, 244 (point + dir1) * M ); 245 } 246 247 template<class T> 248 Plane3<T> operator- (const Plane3<T> &plane) 249 { 250 return Plane3<T>(-plane.normal,-plane.distance); 251 } 252 253 254 } // namespace Imath 255 256 #endif 257