Path: blob/master/3rdparty/openexr/Imath/ImathPlane.h
16337 views
///////////////////////////////////////////////////////////////////////////1//2// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas3// Digital Ltd. LLC4//5// All rights reserved.6//7// Redistribution and use in source and binary forms, with or without8// modification, are permitted provided that the following conditions are9// met:10// * Redistributions of source code must retain the above copyright11// notice, this list of conditions and the following disclaimer.12// * Redistributions in binary form must reproduce the above13// copyright notice, this list of conditions and the following disclaimer14// in the documentation and/or other materials provided with the15// distribution.16// * Neither the name of Industrial Light & Magic nor the names of17// its contributors may be used to endorse or promote products derived18// from this software without specific prior written permission.19//20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31//32///////////////////////////////////////////////////////////////////////////33343536#ifndef INCLUDED_IMATHPLANE_H37#define INCLUDED_IMATHPLANE_H3839//----------------------------------------------------------------------40//41// template class Plane342//43// The Imath::Plane3<> class represents a half space, so the44// normal may point either towards or away from origin. The45// plane P can be represented by Imath::Plane3 as either p or -p46// corresponding to the two half-spaces on either side of the47// plane. Any function which computes a distance will return48// either negative or positive values for the distance indicating49// which half-space the point is in. Note that reflection, and50// intersection functions will operate as expected.51//52//----------------------------------------------------------------------5354#include "ImathVec.h"55#include "ImathLine.h"5657namespace Imath {585960template <class T>61class Plane362{63public:6465Vec3<T> normal;66T distance;6768Plane3() {}69Plane3(const Vec3<T> &normal, T distance);70Plane3(const Vec3<T> &point, const Vec3<T> &normal);71Plane3(const Vec3<T> &point1,72const Vec3<T> &point2,73const Vec3<T> &point3);7475//----------------------76// Various set methods77//----------------------7879void set(const Vec3<T> &normal,80T distance);8182void set(const Vec3<T> &point,83const Vec3<T> &normal);8485void set(const Vec3<T> &point1,86const Vec3<T> &point2,87const Vec3<T> &point3 );8889//----------------------90// Utilities91//----------------------9293bool intersect(const Line3<T> &line,94Vec3<T> &intersection) const;9596bool intersectT(const Line3<T> &line,97T ¶meter) const;9899T distanceTo(const Vec3<T> &) const;100101Vec3<T> reflectPoint(const Vec3<T> &) const;102Vec3<T> reflectVector(const Vec3<T> &) const;103};104105106//--------------------107// Convenient typedefs108//--------------------109110typedef Plane3<float> Plane3f;111typedef Plane3<double> Plane3d;112113114//---------------115// Implementation116//---------------117118template <class T>119inline Plane3<T>::Plane3(const Vec3<T> &p0,120const Vec3<T> &p1,121const Vec3<T> &p2)122{123set(p0,p1,p2);124}125126template <class T>127inline Plane3<T>::Plane3(const Vec3<T> &n, T d)128{129set(n, d);130}131132template <class T>133inline Plane3<T>::Plane3(const Vec3<T> &p, const Vec3<T> &n)134{135set(p, n);136}137138template <class T>139inline void Plane3<T>::set(const Vec3<T>& point1,140const Vec3<T>& point2,141const Vec3<T>& point3)142{143normal = (point2 - point1) % (point3 - point1);144normal.normalize();145distance = normal ^ point1;146}147148template <class T>149inline void Plane3<T>::set(const Vec3<T>& point, const Vec3<T>& n)150{151normal = n;152normal.normalize();153distance = normal ^ point;154}155156template <class T>157inline void Plane3<T>::set(const Vec3<T>& n, T d)158{159normal = n;160normal.normalize();161distance = d;162}163164template <class T>165inline T Plane3<T>::distanceTo(const Vec3<T> &point) const166{167return (point ^ normal) - distance;168}169170template <class T>171inline Vec3<T> Plane3<T>::reflectPoint(const Vec3<T> &point) const172{173return normal * distanceTo(point) * -2.0 + point;174}175176177template <class T>178inline Vec3<T> Plane3<T>::reflectVector(const Vec3<T> &v) const179{180return normal * (normal ^ v) * 2.0 - v;181}182183184template <class T>185inline bool Plane3<T>::intersect(const Line3<T>& line, Vec3<T>& point) const186{187T d = normal ^ line.dir;188if ( d == 0.0 ) return false;189T t = - ((normal ^ line.pos) - distance) / d;190point = line(t);191return true;192}193194template <class T>195inline bool Plane3<T>::intersectT(const Line3<T>& line, T &t) const196{197T d = normal ^ line.dir;198if ( d == 0.0 ) return false;199t = - ((normal ^ line.pos) - distance) / d;200return true;201}202203template<class T>204std::ostream &operator<< (std::ostream &o, const Plane3<T> &plane)205{206return o << "(" << plane.normal << ", " << plane.distance207<< ")";208}209210template<class T>211Plane3<T> operator* (const Plane3<T> &plane, const Matrix44<T> &M)212{213// T214// -1215// Could also compute M but that would suck.216//217218Vec3<T> dir1 = Vec3<T> (1, 0, 0) % plane.normal;219T dir1Len = dir1 ^ dir1;220221Vec3<T> tmp = Vec3<T> (0, 1, 0) % plane.normal;222T tmpLen = tmp ^ tmp;223224if (tmpLen > dir1Len)225{226dir1 = tmp;227dir1Len = tmpLen;228}229230tmp = Vec3<T> (0, 0, 1) % plane.normal;231tmpLen = tmp ^ tmp;232233if (tmpLen > dir1Len)234{235dir1 = tmp;236}237238Vec3<T> dir2 = dir1 % plane.normal;239Vec3<T> point = plane.distance * plane.normal;240241return Plane3<T> ( point * M,242(point + dir2) * M,243(point + dir1) * M );244}245246template<class T>247Plane3<T> operator- (const Plane3<T> &plane)248{249return Plane3<T>(-plane.normal,-plane.distance);250}251252253} // namespace Imath254255#endif256257258