Path: blob/master/3rdparty/openexr/Imath/ImathFrame.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_IMATHFRAME_H37#define INCLUDED_IMATHFRAME_H3839namespace Imath {4041template<class T> class Vec3;42template<class T> class Matrix44;4344//45// These methods compute a set of reference frames, defined by their46// transformation matrix, along a curve. It is designed so that the47// array of points and the array of matrices used to fetch these routines48// don't need to be ordered as the curve.49//50// A typical usage would be :51//52// m[0] = Imath::firstFrame( p[0], p[1], p[2] );53// for( int i = 1; i < n - 1; i++ )54// {55// m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );56// }57// m[n-1] = Imath::lastFrame( m[n-2], p[n-2], p[n-1] );58//59// See Graphics Gems I for the underlying algorithm.60//6162template<class T> Matrix44<T> firstFrame( const Vec3<T>&, // First point63const Vec3<T>&, // Second point64const Vec3<T>& ); // Third point6566template<class T> Matrix44<T> nextFrame( const Matrix44<T>&, // Previous matrix67const Vec3<T>&, // Previous point68const Vec3<T>&, // Current point69Vec3<T>&, // Previous tangent70Vec3<T>& ); // Current tangent7172template<class T> Matrix44<T> lastFrame( const Matrix44<T>&, // Previous matrix73const Vec3<T>&, // Previous point74const Vec3<T>& ); // Last point7576//77// firstFrame - Compute the first reference frame along a curve.78//79// This function returns the transformation matrix to the reference frame80// defined by the three points 'pi', 'pj' and 'pk'. Note that if the two81// vectors <pi,pj> and <pi,pk> are colinears, an arbitrary twist value will82// be choosen.83//84// Throw 'NullVecExc' if 'pi' and 'pj' are equals.85//8687template<class T> Matrix44<T> firstFrame88(89const Vec3<T>& pi, // First point90const Vec3<T>& pj, // Second point91const Vec3<T>& pk ) // Third point92{93Vec3<T> t = pj - pi; t.normalizeExc();9495Vec3<T> n = t.cross( pk - pi ); n.normalize();96if( n.length() == 0.0f )97{98int i = fabs( t[0] ) < fabs( t[1] ) ? 0 : 1;99if( fabs( t[2] ) < fabs( t[i] )) i = 2;100101Vec3<T> v( 0.0, 0.0, 0.0 ); v[i] = 1.0;102n = t.cross( v ); n.normalize();103}104105Vec3<T> b = t.cross( n );106107Matrix44<T> M;108109M[0][0] = t[0]; M[0][1] = t[1]; M[0][2] = t[2]; M[0][3] = 0.0,110M[1][0] = n[0]; M[1][1] = n[1]; M[1][2] = n[2]; M[1][3] = 0.0,111M[2][0] = b[0]; M[2][1] = b[1]; M[2][2] = b[2]; M[2][3] = 0.0,112M[3][0] = pi[0]; M[3][1] = pi[1]; M[3][2] = pi[2]; M[3][3] = 1.0;113114return M;115}116117//118// nextFrame - Compute the next reference frame along a curve.119//120// This function returns the transformation matrix to the next reference121// frame defined by the previously computed transformation matrix and the122// new point and tangent vector along the curve.123//124125template<class T> Matrix44<T> nextFrame126(127const Matrix44<T>& Mi, // Previous matrix128const Vec3<T>& pi, // Previous point129const Vec3<T>& pj, // Current point130Vec3<T>& ti, // Previous tangent vector131Vec3<T>& tj ) // Current tangent vector132{133Vec3<T> a(0.0, 0.0, 0.0); // Rotation axis.134T r = 0.0; // Rotation angle.135136if( ti.length() != 0.0 && tj.length() != 0.0 )137{138ti.normalize(); tj.normalize();139T dot = ti.dot( tj );140141//142// This is *really* necessary :143//144145if( dot > 1.0 ) dot = 1.0;146else if( dot < -1.0 ) dot = -1.0;147148r = acosf( dot );149a = ti.cross( tj );150}151152if( a.length() != 0.0 && r != 0.0 )153{154Matrix44<T> R; R.setAxisAngle( a, r );155Matrix44<T> Tj; Tj.translate( pj );156Matrix44<T> Ti; Ti.translate( -pi );157158return Mi * Ti * R * Tj;159}160else161{162Matrix44<T> Tr; Tr.translate( pj - pi );163164return Mi * Tr;165}166}167168//169// lastFrame - Compute the last reference frame along a curve.170//171// This function returns the transformation matrix to the last reference172// frame defined by the previously computed transformation matrix and the173// last point along the curve.174//175176template<class T> Matrix44<T> lastFrame177(178const Matrix44<T>& Mi, // Previous matrix179const Vec3<T>& pi, // Previous point180const Vec3<T>& pj ) // Last point181{182Matrix44<T> Tr; Tr.translate( pj - pi );183184return Mi * Tr;185}186187} // namespace Imath188189#endif190191192