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 58namespace Imath { 59 60 61template <class T> 62class 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 111typedef Plane3<float> Plane3f; 112typedef Plane3<double> Plane3d; 113 114 115//--------------- 116// Implementation 117//--------------- 118 119template <class T> 120inline 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 127template <class T> 128inline Plane3<T>::Plane3(const Vec3<T> &n, T d) 129{ 130 set(n, d); 131} 132 133template <class T> 134inline Plane3<T>::Plane3(const Vec3<T> &p, const Vec3<T> &n) 135{ 136 set(p, n); 137} 138 139template <class T> 140inline 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 149template <class T> 150inline 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 157template <class T> 158inline void Plane3<T>::set(const Vec3<T>& n, T d) 159{ 160 normal = n; 161 normal.normalize(); 162 distance = d; 163} 164 165template <class T> 166inline T Plane3<T>::distanceTo(const Vec3<T> &point) const 167{ 168 return (point ^ normal) - distance; 169} 170 171template <class T> 172inline Vec3<T> Plane3<T>::reflectPoint(const Vec3<T> &point) const 173{ 174 return normal * distanceTo(point) * -2.0 + point; 175} 176 177 178template <class T> 179inline Vec3<T> Plane3<T>::reflectVector(const Vec3<T> &v) const 180{ 181 return normal * (normal ^ v) * 2.0 - v; 182} 183 184 185template <class T> 186inline 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 195template <class T> 196inline 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 204template<class T> 205std::ostream &operator<< (std::ostream &o, const Plane3<T> &plane) 206{ 207 return o << "(" << plane.normal << ", " << plane.distance 208 << ")"; 209} 210 211template<class T> 212Plane3<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 247template<class T> 248Plane3<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