| /////////////////////////////////////////////////////////////////////////// |
| // |
| // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas |
| // Digital Ltd. LLC |
| // |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Industrial Light & Magic nor the names of |
| // its contributors may be used to endorse or promote products derived |
| // from this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| |
| #ifndef INCLUDED_IMATHPLANE_H |
| #define INCLUDED_IMATHPLANE_H |
| |
| //---------------------------------------------------------------------- |
| // |
| // template class Plane3 |
| // |
| // The Imath::Plane3<> class represents a half space, so the |
| // normal may point either towards or away from origin. The |
| // plane P can be represented by Imath::Plane3 as either p or -p |
| // corresponding to the two half-spaces on either side of the |
| // plane. Any function which computes a distance will return |
| // either negative or positive values for the distance indicating |
| // which half-space the point is in. Note that reflection, and |
| // intersection functions will operate as expected. |
| // |
| //---------------------------------------------------------------------- |
| |
| #include "ImathVec.h" |
| #include "ImathLine.h" |
| |
| namespace Imath { |
| |
| |
| template <class T> |
| class Plane3 |
| { |
| public: |
| |
| Vec3<T> normal; |
| T distance; |
| |
| Plane3() {} |
| Plane3(const Vec3<T> &normal, T distance); |
| Plane3(const Vec3<T> &point, const Vec3<T> &normal); |
| Plane3(const Vec3<T> &point1, |
| const Vec3<T> &point2, |
| const Vec3<T> &point3); |
| |
| //---------------------- |
| // Various set methods |
| //---------------------- |
| |
| void set(const Vec3<T> &normal, |
| T distance); |
| |
| void set(const Vec3<T> &point, |
| const Vec3<T> &normal); |
| |
| void set(const Vec3<T> &point1, |
| const Vec3<T> &point2, |
| const Vec3<T> &point3 ); |
| |
| //---------------------- |
| // Utilities |
| //---------------------- |
| |
| bool intersect(const Line3<T> &line, |
| Vec3<T> &intersection) const; |
| |
| bool intersectT(const Line3<T> &line, |
| T ¶meter) const; |
| |
| T distanceTo(const Vec3<T> &) const; |
| |
| Vec3<T> reflectPoint(const Vec3<T> &) const; |
| Vec3<T> reflectVector(const Vec3<T> &) const; |
| }; |
| |
| |
| //-------------------- |
| // Convenient typedefs |
| //-------------------- |
| |
| typedef Plane3<float> Plane3f; |
| typedef Plane3<double> Plane3d; |
| |
| |
| //--------------- |
| // Implementation |
| //--------------- |
| |
| template <class T> |
| inline Plane3<T>::Plane3(const Vec3<T> &p0, |
| const Vec3<T> &p1, |
| const Vec3<T> &p2) |
| { |
| set(p0,p1,p2); |
| } |
| |
| template <class T> |
| inline Plane3<T>::Plane3(const Vec3<T> &n, T d) |
| { |
| set(n, d); |
| } |
| |
| template <class T> |
| inline Plane3<T>::Plane3(const Vec3<T> &p, const Vec3<T> &n) |
| { |
| set(p, n); |
| } |
| |
| template <class T> |
| inline void Plane3<T>::set(const Vec3<T>& point1, |
| const Vec3<T>& point2, |
| const Vec3<T>& point3) |
| { |
| normal = (point2 - point1) % (point3 - point1); |
| normal.normalize(); |
| distance = normal ^ point1; |
| } |
| |
| template <class T> |
| inline void Plane3<T>::set(const Vec3<T>& point, const Vec3<T>& n) |
| { |
| normal = n; |
| normal.normalize(); |
| distance = normal ^ point; |
| } |
| |
| template <class T> |
| inline void Plane3<T>::set(const Vec3<T>& n, T d) |
| { |
| normal = n; |
| normal.normalize(); |
| distance = d; |
| } |
| |
| template <class T> |
| inline T Plane3<T>::distanceTo(const Vec3<T> &point) const |
| { |
| return (point ^ normal) - distance; |
| } |
| |
| template <class T> |
| inline Vec3<T> Plane3<T>::reflectPoint(const Vec3<T> &point) const |
| { |
| return normal * distanceTo(point) * -2.0 + point; |
| } |
| |
| |
| template <class T> |
| inline Vec3<T> Plane3<T>::reflectVector(const Vec3<T> &v) const |
| { |
| return normal * (normal ^ v) * 2.0 - v; |
| } |
| |
| |
| template <class T> |
| inline bool Plane3<T>::intersect(const Line3<T>& line, Vec3<T>& point) const |
| { |
| T d = normal ^ line.dir; |
| if ( d == 0.0 ) return false; |
| T t = - ((normal ^ line.pos) - distance) / d; |
| point = line(t); |
| return true; |
| } |
| |
| template <class T> |
| inline bool Plane3<T>::intersectT(const Line3<T>& line, T &t) const |
| { |
| T d = normal ^ line.dir; |
| if ( d == 0.0 ) return false; |
| t = - ((normal ^ line.pos) - distance) / d; |
| return true; |
| } |
| |
| template<class T> |
| std::ostream &operator<< (std::ostream &o, const Plane3<T> &plane) |
| { |
| return o << "(" << plane.normal << ", " << plane.distance |
| << ")"; |
| } |
| |
| template<class T> |
| Plane3<T> operator* (const Plane3<T> &plane, const Matrix44<T> &M) |
| { |
| // T |
| // -1 |
| // Could also compute M but that would suck. |
| // |
| |
| Vec3<T> dir1 = Vec3<T> (1, 0, 0) % plane.normal; |
| T dir1Len = dir1 ^ dir1; |
| |
| Vec3<T> tmp = Vec3<T> (0, 1, 0) % plane.normal; |
| T tmpLen = tmp ^ tmp; |
| |
| if (tmpLen > dir1Len) |
| { |
| dir1 = tmp; |
| dir1Len = tmpLen; |
| } |
| |
| tmp = Vec3<T> (0, 0, 1) % plane.normal; |
| tmpLen = tmp ^ tmp; |
| |
| if (tmpLen > dir1Len) |
| { |
| dir1 = tmp; |
| } |
| |
| Vec3<T> dir2 = dir1 % plane.normal; |
| Vec3<T> point = plane.distance * plane.normal; |
| |
| return Plane3<T> ( point * M, |
| (point + dir2) * M, |
| (point + dir1) * M ); |
| } |
| |
| template<class T> |
| Plane3<T> operator- (const Plane3<T> &plane) |
| { |
| return Plane3<T>(-plane.normal,-plane.distance); |
| } |
| |
| |
| } // namespace Imath |
| |
| #endif |