Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

View File

@@ -0,0 +1,16 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps

View File

@@ -0,0 +1,61 @@
# yue.nicholas@gmail.com
IF(ILMBASE_BUILD_SHARED_LIBS)
ADD_DEFINITIONS(-DIMATH_EXPORTS)
ENDIF()
ADD_LIBRARY ( Imath ${LIB_TYPE}
ImathBox.cpp
ImathRandom.cpp
ImathColorAlgo.cpp
ImathShear.cpp
ImathFun.cpp
ImathVec.cpp
ImathMatrixAlgo.cpp
)
TARGET_LINK_LIBRARIES(Imath Iex)
INSTALL ( TARGETS
Imath
DESTINATION
${OPENEXR_INSTALL_LIB_DEST}
)
INSTALL ( FILES
ImathBoxAlgo.h
ImathBox.h
ImathColorAlgo.h
ImathColor.h
ImathEuler.h
ImathExc.h
ImathExport.h
ImathForward.h
ImathFrame.h
ImathFrustum.h
ImathFrustumTest.h
ImathFun.h
ImathGL.h
ImathGLU.h
ImathHalfLimits.h
ImathInt64.h
ImathInterval.h
ImathLimits.h
ImathLineAlgo.h
ImathLine.h
ImathMath.h
ImathMatrixAlgo.h
ImathMatrix.h
ImathNamespace.h
ImathPlane.h
ImathPlatform.h
ImathQuat.h
ImathRandom.h
ImathRoots.h
ImathShear.h
ImathSphere.h
ImathVecAlgo.h
ImathVec.h
DESTINATION
${OPENEXR_INSTALL_HEADER_DEST}
)

View File

@@ -0,0 +1,37 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004, 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.
//
///////////////////////////////////////////////////////////////////////////
#include "ImathBox.h"
// this file is necessary for template instantiation on windows

View File

@@ -0,0 +1,849 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2012, 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_IMATHBOX_H
#define INCLUDED_IMATHBOX_H
//-------------------------------------------------------------------
//
// class Imath::Box<class T>
// --------------------------------
//
// This class imposes the following requirements on its
// parameter class:
//
// 1) The class T must implement these operators:
// + - < > <= >= =
// with the signature (T,T) and the expected
// return values for a numeric type.
//
// 2) The class T must implement operator=
// with the signature (T,float and/or double)
//
// 3) The class T must have a constructor which takes
// a float (and/or double) for use in initializing the box.
//
// 4) The class T must have a function T::dimensions()
// which returns the number of dimensions in the class
// (since its assumed its a vector) -- preferably, this
// returns a constant expression.
//
//-------------------------------------------------------------------
#include "ImathVec.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Box
{
public:
//-------------------------
// Data Members are public
//-------------------------
T min;
T max;
//-----------------------------------------------------
// Constructors - an "empty" box is created by default
//-----------------------------------------------------
Box ();
Box (const T &point);
Box (const T &minT, const T &maxT);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Box<T> &src) const;
bool operator != (const Box<T> &src) const;
//------------------
// Box manipulation
//------------------
void makeEmpty ();
void extendBy (const T &point);
void extendBy (const Box<T> &box);
void makeInfinite ();
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
T size () const;
T center () const;
bool intersects (const T &point) const;
bool intersects (const Box<T> &box) const;
unsigned int majorAxis () const;
//----------------
// Classification
//----------------
bool isEmpty () const;
bool hasVolume () const;
bool isInfinite () const;
};
//--------------------
// Convenient typedefs
//--------------------
typedef Box <V2s> Box2s;
typedef Box <V2i> Box2i;
typedef Box <V2f> Box2f;
typedef Box <V2d> Box2d;
typedef Box <V3s> Box3s;
typedef Box <V3i> Box3i;
typedef Box <V3f> Box3f;
typedef Box <V3d> Box3d;
//----------------
// Implementation
template <class T>
inline Box<T>::Box()
{
makeEmpty();
}
template <class T>
inline Box<T>::Box (const T &point)
{
min = point;
max = point;
}
template <class T>
inline Box<T>::Box (const T &minT, const T &maxT)
{
min = minT;
max = maxT;
}
template <class T>
inline bool
Box<T>::operator == (const Box<T> &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline bool
Box<T>::operator != (const Box<T> &src) const
{
return (min != src.min || max != src.max);
}
template <class T>
inline void Box<T>::makeEmpty()
{
min = T(T::baseTypeMax());
max = T(T::baseTypeMin());
}
template <class T>
inline void Box<T>::makeInfinite()
{
min = T(T::baseTypeMin());
max = T(T::baseTypeMax());
}
template <class T>
inline void
Box<T>::extendBy(const T &point)
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (point[i] < min[i])
min[i] = point[i];
if (point[i] > max[i])
max[i] = point[i];
}
}
template <class T>
inline void
Box<T>::extendBy(const Box<T> &box)
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (box.min[i] < min[i])
min[i] = box.min[i];
if (box.max[i] > max[i])
max[i] = box.max[i];
}
}
template <class T>
inline bool
Box<T>::intersects(const T &point) const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (point[i] < min[i] || point[i] > max[i])
return false;
}
return true;
}
template <class T>
inline bool
Box<T>::intersects(const Box<T> &box) const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (box.max[i] < min[i] || box.min[i] > max[i])
return false;
}
return true;
}
template <class T>
inline T
Box<T>::size() const
{
if (isEmpty())
return T (0);
return max - min;
}
template <class T>
inline T
Box<T>::center() const
{
return (max + min) / 2;
}
template <class T>
inline bool
Box<T>::isEmpty() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (max[i] < min[i])
return true;
}
return false;
}
template <class T>
inline bool
Box<T>::isInfinite() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax())
return false;
}
return true;
}
template <class T>
inline bool
Box<T>::hasVolume() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (max[i] <= min[i])
return false;
}
return true;
}
template<class T>
inline unsigned int
Box<T>::majorAxis() const
{
unsigned int major = 0;
T s = size();
for (unsigned int i = 1; i < min.dimensions(); i++)
{
if (s[i] > s[major])
major = i;
}
return major;
}
//-------------------------------------------------------------------
//
// Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T>
//
//-------------------------------------------------------------------
template <typename T> class Box;
template <class T>
class Box<Vec2<T> >
{
public:
//-------------------------
// Data Members are public
//-------------------------
Vec2<T> min;
Vec2<T> max;
//-----------------------------------------------------
// Constructors - an "empty" box is created by default
//-----------------------------------------------------
Box();
Box (const Vec2<T> &point);
Box (const Vec2<T> &minT, const Vec2<T> &maxT);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Box<Vec2<T> > &src) const;
bool operator != (const Box<Vec2<T> > &src) const;
//------------------
// Box manipulation
//------------------
void makeEmpty();
void extendBy (const Vec2<T> &point);
void extendBy (const Box<Vec2<T> > &box);
void makeInfinite();
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
Vec2<T> size() const;
Vec2<T> center() const;
bool intersects (const Vec2<T> &point) const;
bool intersects (const Box<Vec2<T> > &box) const;
unsigned int majorAxis() const;
//----------------
// Classification
//----------------
bool isEmpty() const;
bool hasVolume() const;
bool isInfinite() const;
};
//----------------
// Implementation
template <class T>
inline Box<Vec2<T> >::Box()
{
makeEmpty();
}
template <class T>
inline Box<Vec2<T> >::Box (const Vec2<T> &point)
{
min = point;
max = point;
}
template <class T>
inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT)
{
min = minT;
max = maxT;
}
template <class T>
inline bool
Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline bool
Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const
{
return (min != src.min || max != src.max);
}
template <class T>
inline void Box<Vec2<T> >::makeEmpty()
{
min = Vec2<T>(Vec2<T>::baseTypeMax());
max = Vec2<T>(Vec2<T>::baseTypeMin());
}
template <class T>
inline void Box<Vec2<T> >::makeInfinite()
{
min = Vec2<T>(Vec2<T>::baseTypeMin());
max = Vec2<T>(Vec2<T>::baseTypeMax());
}
template <class T>
inline void
Box<Vec2<T> >::extendBy (const Vec2<T> &point)
{
if (point[0] < min[0])
min[0] = point[0];
if (point[0] > max[0])
max[0] = point[0];
if (point[1] < min[1])
min[1] = point[1];
if (point[1] > max[1])
max[1] = point[1];
}
template <class T>
inline void
Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box)
{
if (box.min[0] < min[0])
min[0] = box.min[0];
if (box.max[0] > max[0])
max[0] = box.max[0];
if (box.min[1] < min[1])
min[1] = box.min[1];
if (box.max[1] > max[1])
max[1] = box.max[1];
}
template <class T>
inline bool
Box<Vec2<T> >::intersects (const Vec2<T> &point) const
{
if (point[0] < min[0] || point[0] > max[0] ||
point[1] < min[1] || point[1] > max[1])
return false;
return true;
}
template <class T>
inline bool
Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const
{
if (box.max[0] < min[0] || box.min[0] > max[0] ||
box.max[1] < min[1] || box.min[1] > max[1])
return false;
return true;
}
template <class T>
inline Vec2<T>
Box<Vec2<T> >::size() const
{
if (isEmpty())
return Vec2<T> (0);
return max - min;
}
template <class T>
inline Vec2<T>
Box<Vec2<T> >::center() const
{
return (max + min) / 2;
}
template <class T>
inline bool
Box<Vec2<T> >::isEmpty() const
{
if (max[0] < min[0] ||
max[1] < min[1])
return true;
return false;
}
template <class T>
inline bool
Box<Vec2<T> > ::isInfinite() const
{
if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
min[1] != limits<T>::min() || max[1] != limits<T>::max())
return false;
return true;
}
template <class T>
inline bool
Box<Vec2<T> >::hasVolume() const
{
if (max[0] <= min[0] ||
max[1] <= min[1])
return false;
return true;
}
template <class T>
inline unsigned int
Box<Vec2<T> >::majorAxis() const
{
unsigned int major = 0;
Vec2<T> s = size();
if (s[1] > s[major])
major = 1;
return major;
}
template <class T>
class Box<Vec3<T> >
{
public:
//-------------------------
// Data Members are public
//-------------------------
Vec3<T> min;
Vec3<T> max;
//-----------------------------------------------------
// Constructors - an "empty" box is created by default
//-----------------------------------------------------
Box();
Box (const Vec3<T> &point);
Box (const Vec3<T> &minT, const Vec3<T> &maxT);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Box<Vec3<T> > &src) const;
bool operator != (const Box<Vec3<T> > &src) const;
//------------------
// Box manipulation
//------------------
void makeEmpty();
void extendBy (const Vec3<T> &point);
void extendBy (const Box<Vec3<T> > &box);
void makeInfinite ();
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
Vec3<T> size() const;
Vec3<T> center() const;
bool intersects (const Vec3<T> &point) const;
bool intersects (const Box<Vec3<T> > &box) const;
unsigned int majorAxis() const;
//----------------
// Classification
//----------------
bool isEmpty() const;
bool hasVolume() const;
bool isInfinite() const;
};
//----------------
// Implementation
template <class T>
inline Box<Vec3<T> >::Box()
{
makeEmpty();
}
template <class T>
inline Box<Vec3<T> >::Box (const Vec3<T> &point)
{
min = point;
max = point;
}
template <class T>
inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT)
{
min = minT;
max = maxT;
}
template <class T>
inline bool
Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline bool
Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const
{
return (min != src.min || max != src.max);
}
template <class T>
inline void Box<Vec3<T> >::makeEmpty()
{
min = Vec3<T>(Vec3<T>::baseTypeMax());
max = Vec3<T>(Vec3<T>::baseTypeMin());
}
template <class T>
inline void Box<Vec3<T> >::makeInfinite()
{
min = Vec3<T>(Vec3<T>::baseTypeMin());
max = Vec3<T>(Vec3<T>::baseTypeMax());
}
template <class T>
inline void
Box<Vec3<T> >::extendBy (const Vec3<T> &point)
{
if (point[0] < min[0])
min[0] = point[0];
if (point[0] > max[0])
max[0] = point[0];
if (point[1] < min[1])
min[1] = point[1];
if (point[1] > max[1])
max[1] = point[1];
if (point[2] < min[2])
min[2] = point[2];
if (point[2] > max[2])
max[2] = point[2];
}
template <class T>
inline void
Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box)
{
if (box.min[0] < min[0])
min[0] = box.min[0];
if (box.max[0] > max[0])
max[0] = box.max[0];
if (box.min[1] < min[1])
min[1] = box.min[1];
if (box.max[1] > max[1])
max[1] = box.max[1];
if (box.min[2] < min[2])
min[2] = box.min[2];
if (box.max[2] > max[2])
max[2] = box.max[2];
}
template <class T>
inline bool
Box<Vec3<T> >::intersects (const Vec3<T> &point) const
{
if (point[0] < min[0] || point[0] > max[0] ||
point[1] < min[1] || point[1] > max[1] ||
point[2] < min[2] || point[2] > max[2])
return false;
return true;
}
template <class T>
inline bool
Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const
{
if (box.max[0] < min[0] || box.min[0] > max[0] ||
box.max[1] < min[1] || box.min[1] > max[1] ||
box.max[2] < min[2] || box.min[2] > max[2])
return false;
return true;
}
template <class T>
inline Vec3<T>
Box<Vec3<T> >::size() const
{
if (isEmpty())
return Vec3<T> (0);
return max - min;
}
template <class T>
inline Vec3<T>
Box<Vec3<T> >::center() const
{
return (max + min) / 2;
}
template <class T>
inline bool
Box<Vec3<T> >::isEmpty() const
{
if (max[0] < min[0] ||
max[1] < min[1] ||
max[2] < min[2])
return true;
return false;
}
template <class T>
inline bool
Box<Vec3<T> >::isInfinite() const
{
if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
min[1] != limits<T>::min() || max[1] != limits<T>::max() ||
min[2] != limits<T>::min() || max[2] != limits<T>::max())
return false;
return true;
}
template <class T>
inline bool
Box<Vec3<T> >::hasVolume() const
{
if (max[0] <= min[0] ||
max[1] <= min[1] ||
max[2] <= min[2])
return false;
return true;
}
template <class T>
inline unsigned int
Box<Vec3<T> >::majorAxis() const
{
unsigned int major = 0;
Vec3<T> s = size();
if (s[1] > s[major])
major = 1;
if (s[2] > s[major])
major = 2;
return major;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHBOX_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,736 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2012, 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_IMATHCOLOR_H
#define INCLUDED_IMATHCOLOR_H
//----------------------------------------------------
//
// A three and four component color class template.
//
//----------------------------------------------------
#include "ImathVec.h"
#include "ImathNamespace.h"
#include "half.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Color3: public Vec3 <T>
{
public:
//-------------
// Constructors
//-------------
Color3 (); // no initialization
explicit Color3 (T a); // (a a a)
Color3 (T a, T b, T c); // (a b c)
//---------------------------------
// Copy constructors and assignment
//---------------------------------
Color3 (const Color3 &c);
template <class S> Color3 (const Vec3<S> &v);
const Color3 & operator = (const Color3 &c);
//------------------------
// Component-wise addition
//------------------------
const Color3 & operator += (const Color3 &c);
Color3 operator + (const Color3 &c) const;
//---------------------------
// Component-wise subtraction
//---------------------------
const Color3 & operator -= (const Color3 &c);
Color3 operator - (const Color3 &c) const;
//------------------------------------
// Component-wise multiplication by -1
//------------------------------------
Color3 operator - () const;
const Color3 & negate ();
//------------------------------
// Component-wise multiplication
//------------------------------
const Color3 & operator *= (const Color3 &c);
const Color3 & operator *= (T a);
Color3 operator * (const Color3 &c) const;
Color3 operator * (T a) const;
//------------------------
// Component-wise division
//------------------------
const Color3 & operator /= (const Color3 &c);
const Color3 & operator /= (T a);
Color3 operator / (const Color3 &c) const;
Color3 operator / (T a) const;
};
template <class T> class Color4
{
public:
//-------------------
// Access to elements
//-------------------
T r, g, b, a;
T & operator [] (int i);
const T & operator [] (int i) const;
//-------------
// Constructors
//-------------
Color4 (); // no initialization
explicit Color4 (T a); // (a a a a)
Color4 (T a, T b, T c, T d); // (a b c d)
//---------------------------------
// Copy constructors and assignment
//---------------------------------
Color4 (const Color4 &v);
template <class S> Color4 (const Color4<S> &v);
const Color4 & operator = (const Color4 &v);
//----------------------
// Compatibility with Sb
//----------------------
template <class S>
void setValue (S a, S b, S c, S d);
template <class S>
void setValue (const Color4<S> &v);
template <class S>
void getValue (S &a, S &b, S &c, S &d) const;
template <class S>
void getValue (Color4<S> &v) const;
T * getValue();
const T * getValue() const;
//---------
// Equality
//---------
template <class S>
bool operator == (const Color4<S> &v) const;
template <class S>
bool operator != (const Color4<S> &v) const;
//------------------------
// Component-wise addition
//------------------------
const Color4 & operator += (const Color4 &v);
Color4 operator + (const Color4 &v) const;
//---------------------------
// Component-wise subtraction
//---------------------------
const Color4 & operator -= (const Color4 &v);
Color4 operator - (const Color4 &v) const;
//------------------------------------
// Component-wise multiplication by -1
//------------------------------------
Color4 operator - () const;
const Color4 & negate ();
//------------------------------
// Component-wise multiplication
//------------------------------
const Color4 & operator *= (const Color4 &v);
const Color4 & operator *= (T a);
Color4 operator * (const Color4 &v) const;
Color4 operator * (T a) const;
//------------------------
// Component-wise division
//------------------------
const Color4 & operator /= (const Color4 &v);
const Color4 & operator /= (T a);
Color4 operator / (const Color4 &v) const;
Color4 operator / (T a) const;
//----------------------------------------------------------
// Number of dimensions, i.e. number of elements in a Color4
//----------------------------------------------------------
static unsigned int dimensions() {return 4;}
//-------------------------------------------------
// Limitations of type T (see also class limits<T>)
//-------------------------------------------------
static T baseTypeMin() {return limits<T>::min();}
static T baseTypeMax() {return limits<T>::max();}
static T baseTypeSmallest() {return limits<T>::smallest();}
static T baseTypeEpsilon() {return limits<T>::epsilon();}
//--------------------------------------------------------------
// Base type -- in templates, which accept a parameter, V, which
// could be a Color4<T>, you can refer to T as
// V::BaseType
//--------------------------------------------------------------
typedef T BaseType;
};
//--------------
// Stream output
//--------------
template <class T>
std::ostream & operator << (std::ostream &s, const Color4<T> &v);
//----------------------------------------------------
// Reverse multiplication: S * Color4<T>
//----------------------------------------------------
template <class S, class T> Color4<T> operator * (S a, const Color4<T> &v);
//-------------------------
// Typedefs for convenience
//-------------------------
typedef Color3<float> Color3f;
typedef Color3<half> Color3h;
typedef Color3<unsigned char> Color3c;
typedef Color3<half> C3h;
typedef Color3<float> C3f;
typedef Color3<unsigned char> C3c;
typedef Color4<float> Color4f;
typedef Color4<half> Color4h;
typedef Color4<unsigned char> Color4c;
typedef Color4<float> C4f;
typedef Color4<half> C4h;
typedef Color4<unsigned char> C4c;
typedef unsigned int PackedColor;
//-------------------------
// Implementation of Color3
//-------------------------
template <class T>
inline
Color3<T>::Color3 (): Vec3 <T> ()
{
// empty
}
template <class T>
inline
Color3<T>::Color3 (T a): Vec3 <T> (a)
{
// empty
}
template <class T>
inline
Color3<T>::Color3 (T a, T b, T c): Vec3 <T> (a, b, c)
{
// empty
}
template <class T>
inline
Color3<T>::Color3 (const Color3 &c): Vec3 <T> (c)
{
// empty
}
template <class T>
template <class S>
inline
Color3<T>::Color3 (const Vec3<S> &v): Vec3 <T> (v)
{
//empty
}
template <class T>
inline const Color3<T> &
Color3<T>::operator = (const Color3 &c)
{
*((Vec3<T> *) this) = c;
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator += (const Color3 &c)
{
*((Vec3<T> *) this) += c;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator + (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this + (const Vec3<T> &)c);
}
template <class T>
inline const Color3<T> &
Color3<T>::operator -= (const Color3 &c)
{
*((Vec3<T> *) this) -= c;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator - (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this - (const Vec3<T> &)c);
}
template <class T>
inline Color3<T>
Color3<T>::operator - () const
{
return Color3 (-(*(Vec3<T> *)this));
}
template <class T>
inline const Color3<T> &
Color3<T>::negate ()
{
((Vec3<T> *) this)->negate();
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator *= (const Color3 &c)
{
*((Vec3<T> *) this) *= c;
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator *= (T a)
{
*((Vec3<T> *) this) *= a;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator * (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this * (const Vec3<T> &)c);
}
template <class T>
inline Color3<T>
Color3<T>::operator * (T a) const
{
return Color3 (*(Vec3<T> *)this * a);
}
template <class T>
inline const Color3<T> &
Color3<T>::operator /= (const Color3 &c)
{
*((Vec3<T> *) this) /= c;
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator /= (T a)
{
*((Vec3<T> *) this) /= a;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator / (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this / (const Vec3<T> &)c);
}
template <class T>
inline Color3<T>
Color3<T>::operator / (T a) const
{
return Color3 (*(Vec3<T> *)this / a);
}
//-----------------------
// Implementation of Color4
//-----------------------
template <class T>
inline T &
Color4<T>::operator [] (int i)
{
return (&r)[i];
}
template <class T>
inline const T &
Color4<T>::operator [] (int i) const
{
return (&r)[i];
}
template <class T>
inline
Color4<T>::Color4 ()
{
// empty
}
template <class T>
inline
Color4<T>::Color4 (T x)
{
r = g = b = a = x;
}
template <class T>
inline
Color4<T>::Color4 (T x, T y, T z, T w)
{
r = x;
g = y;
b = z;
a = w;
}
template <class T>
inline
Color4<T>::Color4 (const Color4 &v)
{
r = v.r;
g = v.g;
b = v.b;
a = v.a;
}
template <class T>
template <class S>
inline
Color4<T>::Color4 (const Color4<S> &v)
{
r = T (v.r);
g = T (v.g);
b = T (v.b);
a = T (v.a);
}
template <class T>
inline const Color4<T> &
Color4<T>::operator = (const Color4 &v)
{
r = v.r;
g = v.g;
b = v.b;
a = v.a;
return *this;
}
template <class T>
template <class S>
inline void
Color4<T>::setValue (S x, S y, S z, S w)
{
r = T (x);
g = T (y);
b = T (z);
a = T (w);
}
template <class T>
template <class S>
inline void
Color4<T>::setValue (const Color4<S> &v)
{
r = T (v.r);
g = T (v.g);
b = T (v.b);
a = T (v.a);
}
template <class T>
template <class S>
inline void
Color4<T>::getValue (S &x, S &y, S &z, S &w) const
{
x = S (r);
y = S (g);
z = S (b);
w = S (a);
}
template <class T>
template <class S>
inline void
Color4<T>::getValue (Color4<S> &v) const
{
v.r = S (r);
v.g = S (g);
v.b = S (b);
v.a = S (a);
}
template <class T>
inline T *
Color4<T>::getValue()
{
return (T *) &r;
}
template <class T>
inline const T *
Color4<T>::getValue() const
{
return (const T *) &r;
}
template <class T>
template <class S>
inline bool
Color4<T>::operator == (const Color4<S> &v) const
{
return r == v.r && g == v.g && b == v.b && a == v.a;
}
template <class T>
template <class S>
inline bool
Color4<T>::operator != (const Color4<S> &v) const
{
return r != v.r || g != v.g || b != v.b || a != v.a;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator += (const Color4 &v)
{
r += v.r;
g += v.g;
b += v.b;
a += v.a;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator + (const Color4 &v) const
{
return Color4 (r + v.r, g + v.g, b + v.b, a + v.a);
}
template <class T>
inline const Color4<T> &
Color4<T>::operator -= (const Color4 &v)
{
r -= v.r;
g -= v.g;
b -= v.b;
a -= v.a;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator - (const Color4 &v) const
{
return Color4 (r - v.r, g - v.g, b - v.b, a - v.a);
}
template <class T>
inline Color4<T>
Color4<T>::operator - () const
{
return Color4 (-r, -g, -b, -a);
}
template <class T>
inline const Color4<T> &
Color4<T>::negate ()
{
r = -r;
g = -g;
b = -b;
a = -a;
return *this;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator *= (const Color4 &v)
{
r *= v.r;
g *= v.g;
b *= v.b;
a *= v.a;
return *this;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator *= (T x)
{
r *= x;
g *= x;
b *= x;
a *= x;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator * (const Color4 &v) const
{
return Color4 (r * v.r, g * v.g, b * v.b, a * v.a);
}
template <class T>
inline Color4<T>
Color4<T>::operator * (T x) const
{
return Color4 (r * x, g * x, b * x, a * x);
}
template <class T>
inline const Color4<T> &
Color4<T>::operator /= (const Color4 &v)
{
r /= v.r;
g /= v.g;
b /= v.b;
a /= v.a;
return *this;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator /= (T x)
{
r /= x;
g /= x;
b /= x;
a /= x;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator / (const Color4 &v) const
{
return Color4 (r / v.r, g / v.g, b / v.b, a / v.a);
}
template <class T>
inline Color4<T>
Color4<T>::operator / (T x) const
{
return Color4 (r / x, g / x, b / x, a / x);
}
template <class T>
std::ostream &
operator << (std::ostream &s, const Color4<T> &v)
{
return s << '(' << v.r << ' ' << v.g << ' ' << v.b << ' ' << v.a << ')';
}
//-----------------------------------------
// Implementation of reverse multiplication
//-----------------------------------------
template <class S, class T>
inline Color4<T>
operator * (S x, const Color4<T> &v)
{
return Color4<T> (x * v.r, x * v.g, x * v.b, x * v.a);
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHCOLOR_H

View File

@@ -0,0 +1,178 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Implementation of non-template items declared in ImathColorAlgo.h
//
//----------------------------------------------------------------------------
#include "ImathColorAlgo.h"
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
Vec3<double>
hsv2rgb_d(const Vec3<double> &hsv)
{
double hue = hsv.x;
double sat = hsv.y;
double val = hsv.z;
double x = 0.0, y = 0.0, z = 0.0;
if (hue == 1) hue = 0;
else hue *= 6;
int i = int(Math<double>::floor(hue));
double f = hue-i;
double p = val*(1-sat);
double q = val*(1-(sat*f));
double t = val*(1-(sat*(1-f)));
switch (i)
{
case 0: x = val; y = t; z = p; break;
case 1: x = q; y = val; z = p; break;
case 2: x = p; y = val; z = t; break;
case 3: x = p; y = q; z = val; break;
case 4: x = t; y = p; z = val; break;
case 5: x = val; y = p; z = q; break;
}
return Vec3<double>(x,y,z);
}
Color4<double>
hsv2rgb_d(const Color4<double> &hsv)
{
double hue = hsv.r;
double sat = hsv.g;
double val = hsv.b;
double r = 0.0, g = 0.0, b = 0.0;
if (hue == 1) hue = 0;
else hue *= 6;
int i = int(Math<double>::floor(hue));
double f = hue-i;
double p = val*(1-sat);
double q = val*(1-(sat*f));
double t = val*(1-(sat*(1-f)));
switch (i)
{
case 0: r = val; g = t; b = p; break;
case 1: r = q; g = val; b = p; break;
case 2: r = p; g = val; b = t; break;
case 3: r = p; g = q; b = val; break;
case 4: r = t; g = p; b = val; break;
case 5: r = val; g = p; b = q; break;
}
return Color4<double>(r,g,b,hsv.a);
}
Vec3<double>
rgb2hsv_d(const Vec3<double> &c)
{
const double &x = c.x;
const double &y = c.y;
const double &z = c.z;
double max = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
double min = (x < y) ? ((x < z) ? x : z) : ((y < z) ? y : z);
double range = max - min;
double val = max;
double sat = 0;
double hue = 0;
if (max != 0) sat = range/max;
if (sat != 0)
{
double h;
if (x == max) h = (y - z) / range;
else if (y == max) h = 2 + (z - x) / range;
else h = 4 + (x - y) / range;
hue = h/6.;
if (hue < 0.)
hue += 1.0;
}
return Vec3<double>(hue,sat,val);
}
Color4<double>
rgb2hsv_d(const Color4<double> &c)
{
const double &r = c.r;
const double &g = c.g;
const double &b = c.b;
double max = (r > g) ? ((r > b) ? r : b) : ((g > b) ? g : b);
double min = (r < g) ? ((r < b) ? r : b) : ((g < b) ? g : b);
double range = max - min;
double val = max;
double sat = 0;
double hue = 0;
if (max != 0) sat = range/max;
if (sat != 0)
{
double h;
if (r == max) h = (g - b) / range;
else if (g == max) h = 2 + (b - r) / range;
else h = 4 + (r - g) / range;
hue = h/6.;
if (hue < 0.)
hue += 1.0;
}
return Color4<double>(hue,sat,val,c.a);
}
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

View File

@@ -0,0 +1,257 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHCOLORALGO_H
#define INCLUDED_IMATHCOLORALGO_H
#include "ImathColor.h"
#include "ImathExport.h"
#include "ImathMath.h"
#include "ImathLimits.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Non-templated helper routines for color conversion.
// These routines eliminate type warnings under g++.
//
IMATH_EXPORT Vec3<double> hsv2rgb_d(const Vec3<double> &hsv);
IMATH_EXPORT Color4<double> hsv2rgb_d(const Color4<double> &hsv);
IMATH_EXPORT Vec3<double> rgb2hsv_d(const Vec3<double> &rgb);
IMATH_EXPORT Color4<double> rgb2hsv_d(const Color4<double> &rgb);
//
// Color conversion functions and general color algorithms
//
// hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb()
// see each funtion definition for details.
//
template<class T>
Vec3<T>
hsv2rgb(const Vec3<T> &hsv)
{
if ( limits<T>::isIntegral() )
{
Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),
hsv.y / double(limits<T>::max()),
hsv.z / double(limits<T>::max()));
Vec3<double> c = hsv2rgb_d(v);
return Vec3<T>((T) (c.x * limits<T>::max()),
(T) (c.y * limits<T>::max()),
(T) (c.z * limits<T>::max()));
}
else
{
Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);
Vec3<double> c = hsv2rgb_d(v);
return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
}
}
template<class T>
Color4<T>
hsv2rgb(const Color4<T> &hsv)
{
if ( limits<T>::isIntegral() )
{
Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),
hsv.g / float(limits<T>::max()),
hsv.b / float(limits<T>::max()),
hsv.a / float(limits<T>::max()));
Color4<double> c = hsv2rgb_d(v);
return Color4<T>((T) (c.r * limits<T>::max()),
(T) (c.g * limits<T>::max()),
(T) (c.b * limits<T>::max()),
(T) (c.a * limits<T>::max()));
}
else
{
Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.b, hsv.a);
Color4<double> c = hsv2rgb_d(v);
return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
}
}
template<class T>
Vec3<T>
rgb2hsv(const Vec3<T> &rgb)
{
if ( limits<T>::isIntegral() )
{
Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),
rgb.y / double(limits<T>::max()),
rgb.z / double(limits<T>::max()));
Vec3<double> c = rgb2hsv_d(v);
return Vec3<T>((T) (c.x * limits<T>::max()),
(T) (c.y * limits<T>::max()),
(T) (c.z * limits<T>::max()));
}
else
{
Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);
Vec3<double> c = rgb2hsv_d(v);
return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
}
}
template<class T>
Color4<T>
rgb2hsv(const Color4<T> &rgb)
{
if ( limits<T>::isIntegral() )
{
Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),
rgb.g / float(limits<T>::max()),
rgb.b / float(limits<T>::max()),
rgb.a / float(limits<T>::max()));
Color4<double> c = rgb2hsv_d(v);
return Color4<T>((T) (c.r * limits<T>::max()),
(T) (c.g * limits<T>::max()),
(T) (c.b * limits<T>::max()),
(T) (c.a * limits<T>::max()));
}
else
{
Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.b, rgb.a);
Color4<double> c = rgb2hsv_d(v);
return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
}
}
template <class T>
PackedColor
rgb2packed(const Vec3<T> &c)
{
if ( limits<T>::isIntegral() )
{
float x = c.x / float(limits<T>::max());
float y = c.y / float(limits<T>::max());
float z = c.z / float(limits<T>::max());
return rgb2packed( V3f(x,y,z) );
}
else
{
return ( (PackedColor) (c.x * 255) |
(((PackedColor) (c.y * 255)) << 8) |
(((PackedColor) (c.z * 255)) << 16) | 0xFF000000 );
}
}
template <class T>
PackedColor
rgb2packed(const Color4<T> &c)
{
if ( limits<T>::isIntegral() )
{
float r = c.r / float(limits<T>::max());
float g = c.g / float(limits<T>::max());
float b = c.b / float(limits<T>::max());
float a = c.a / float(limits<T>::max());
return rgb2packed( C4f(r,g,b,a) );
}
else
{
return ( (PackedColor) (c.r * 255) |
(((PackedColor) (c.g * 255)) << 8) |
(((PackedColor) (c.b * 255)) << 16) |
(((PackedColor) (c.a * 255)) << 24));
}
}
//
// This guy can't return the result because the template
// parameter would not be in the function signiture. So instead,
// its passed in as an argument.
//
template <class T>
void
packed2rgb(PackedColor packed, Vec3<T> &out)
{
if ( limits<T>::isIntegral() )
{
T f = limits<T>::max() / ((PackedColor)0xFF);
out.x = (packed & 0xFF) * f;
out.y = ((packed & 0xFF00) >> 8) * f;
out.z = ((packed & 0xFF0000) >> 16) * f;
}
else
{
T f = T(1) / T(255);
out.x = (packed & 0xFF) * f;
out.y = ((packed & 0xFF00) >> 8) * f;
out.z = ((packed & 0xFF0000) >> 16) * f;
}
}
template <class T>
void
packed2rgb(PackedColor packed, Color4<T> &out)
{
if ( limits<T>::isIntegral() )
{
T f = limits<T>::max() / ((PackedColor)0xFF);
out.r = (packed & 0xFF) * f;
out.g = ((packed & 0xFF00) >> 8) * f;
out.b = ((packed & 0xFF0000) >> 16) * f;
out.a = ((packed & 0xFF000000) >> 24) * f;
}
else
{
T f = T(1) / T(255);
out.r = (packed & 0xFF) * f;
out.g = ((packed & 0xFF00) >> 8) * f;
out.b = ((packed & 0xFF0000) >> 16) * f;
out.a = ((packed & 0xFF000000) >> 24) * f;
}
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHCOLORALGO_H

View File

@@ -0,0 +1,926 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHEULER_H
#define INCLUDED_IMATHEULER_H
//----------------------------------------------------------------------
//
// template class Euler<T>
//
// This class represents euler angle orientations. The class
// inherits from Vec3 to it can be freely cast. The additional
// information is the euler priorities rep. This class is
// essentially a rip off of Ken Shoemake's GemsIV code. It has
// been modified minimally to make it more understandable, but
// hardly enough to make it easy to grok completely.
//
// There are 24 possible combonations of Euler angle
// representations of which 12 are common in CG and you will
// probably only use 6 of these which in this scheme are the
// non-relative-non-repeating types.
//
// The representations can be partitioned according to two
// criteria:
//
// 1) Are the angles measured relative to a set of fixed axis
// or relative to each other (the latter being what happens
// when rotation matrices are multiplied together and is
// almost ubiquitous in the cg community)
//
// 2) Is one of the rotations repeated (ala XYX rotation)
//
// When you construct a given representation from scratch you
// must order the angles according to their priorities. So, the
// easiest is a softimage or aerospace (yaw/pitch/roll) ordering
// of ZYX.
//
// float x_rot = 1;
// float y_rot = 2;
// float z_rot = 3;
//
// Eulerf angles(z_rot, y_rot, x_rot, Eulerf::ZYX);
// -or-
// Eulerf angles( V3f(z_rot,y_rot,z_rot), Eulerf::ZYX );
//
// If instead, the order was YXZ for instance you would have to
// do this:
//
// float x_rot = 1;
// float y_rot = 2;
// float z_rot = 3;
//
// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ);
// -or-
// Eulerf angles( V3f(y_rot,x_rot,z_rot), Eulerf::YXZ );
//
// Notice how the order you put the angles into the three slots
// should correspond to the enum (YXZ) ordering. The input angle
// vector is called the "ijk" vector -- not an "xyz" vector. The
// ijk vector order is the same as the enum. If you treat the
// Euler<> as a Vec<> (which it inherts from) you will find the
// angles are ordered in the same way, i.e.:
//
// V3f v = angles;
// // v.x == y_rot, v.y == x_rot, v.z == z_rot
//
// If you just want the x, y, and z angles stored in a vector in
// that order, you can do this:
//
// V3f v = angles.toXYZVector()
// // v.x == x_rot, v.y == y_rot, v.z == z_rot
//
// If you want to set the Euler with an XYZVector use the
// optional layout argument:
//
// Eulerf angles(x_rot, y_rot, z_rot,
// Eulerf::YXZ,
// Eulerf::XYZLayout);
//
// This is the same as:
//
// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ);
//
// Note that this won't do anything intelligent if you have a
// repeated axis in the euler angles (e.g. XYX)
//
// If you need to use the "relative" versions of these, you will
// need to use the "r" enums.
//
// The units of the rotation angles are assumed to be radians.
//
//----------------------------------------------------------------------
#include "ImathMath.h"
#include "ImathVec.h"
#include "ImathQuat.h"
#include "ImathMatrix.h"
#include "ImathLimits.h"
#include "ImathNamespace.h"
#include <iostream>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
// Disable MS VC++ warnings about conversion from double to float
#pragma warning(disable:4244)
#endif
template <class T>
class Euler : public Vec3<T>
{
public:
using Vec3<T>::x;
using Vec3<T>::y;
using Vec3<T>::z;
enum Order
{
//
// All 24 possible orderings
//
XYZ = 0x0101, // "usual" orderings
XZY = 0x0001,
YZX = 0x1101,
YXZ = 0x1001,
ZXY = 0x2101,
ZYX = 0x2001,
XZX = 0x0011, // first axis repeated
XYX = 0x0111,
YXY = 0x1011,
YZY = 0x1111,
ZYZ = 0x2011,
ZXZ = 0x2111,
XYZr = 0x2000, // relative orderings -- not common
XZYr = 0x2100,
YZXr = 0x1000,
YXZr = 0x1100,
ZXYr = 0x0000,
ZYXr = 0x0100,
XZXr = 0x2110, // relative first axis repeated
XYXr = 0x2010,
YXYr = 0x1110,
YZYr = 0x1010,
ZYZr = 0x0110,
ZXZr = 0x0010,
// ||||
// VVVV
// Legend: ABCD
// A -> Initial Axis (0==x, 1==y, 2==z)
// B -> Parity Even (1==true)
// C -> Initial Repeated (1==true)
// D -> Frame Static (1==true)
//
Legal = XYZ | XZY | YZX | YXZ | ZXY | ZYX |
XZX | XYX | YXY | YZY | ZYZ | ZXZ |
XYZr| XZYr| YZXr| YXZr| ZXYr| ZYXr|
XZXr| XYXr| YXYr| YZYr| ZYZr| ZXZr,
Min = 0x0000,
Max = 0x2111,
Default = XYZ
};
enum Axis { X = 0, Y = 1, Z = 2 };
enum InputLayout { XYZLayout, IJKLayout };
//--------------------------------------------------------------------
// Constructors -- all default to ZYX non-relative ala softimage
// (where there is no argument to specify it)
//
// The Euler-from-matrix constructors assume that the matrix does
// not include shear or non-uniform scaling, but the constructors
// do not examine the matrix to verify this assumption. If necessary,
// you can adjust the matrix by calling the removeScalingAndShear()
// function, defined in ImathMatrixAlgo.h.
//--------------------------------------------------------------------
Euler();
Euler(const Euler&);
Euler(Order p);
Euler(const Vec3<T> &v, Order o = Default, InputLayout l = IJKLayout);
Euler(T i, T j, T k, Order o = Default, InputLayout l = IJKLayout);
Euler(const Euler<T> &euler, Order newp);
Euler(const Matrix33<T> &, Order o = Default);
Euler(const Matrix44<T> &, Order o = Default);
//---------------------------------
// Algebraic functions/ Operators
//---------------------------------
const Euler<T>& operator= (const Euler<T>&);
const Euler<T>& operator= (const Vec3<T>&);
//--------------------------------------------------------
// Set the euler value
// This does NOT convert the angles, but setXYZVector()
// does reorder the input vector.
//--------------------------------------------------------
static bool legal(Order);
void setXYZVector(const Vec3<T> &);
Order order() const;
void setOrder(Order);
void set(Axis initial,
bool relative,
bool parityEven,
bool firstRepeats);
//------------------------------------------------------------
// Conversions, toXYZVector() reorders the angles so that
// the X rotation comes first, followed by the Y and Z
// in cases like XYX ordering, the repeated angle will be
// in the "z" component
//
// The Euler-from-matrix extract() functions assume that the
// matrix does not include shear or non-uniform scaling, but
// the extract() functions do not examine the matrix to verify
// this assumption. If necessary, you can adjust the matrix
// by calling the removeScalingAndShear() function, defined
// in ImathMatrixAlgo.h.
//------------------------------------------------------------
void extract(const Matrix33<T>&);
void extract(const Matrix44<T>&);
void extract(const Quat<T>&);
Matrix33<T> toMatrix33() const;
Matrix44<T> toMatrix44() const;
Quat<T> toQuat() const;
Vec3<T> toXYZVector() const;
//---------------------------------------------------
// Use this function to unpack angles from ijk form
//---------------------------------------------------
void angleOrder(int &i, int &j, int &k) const;
//---------------------------------------------------
// Use this function to determine mapping from xyz to ijk
// - reshuffles the xyz to match the order
//---------------------------------------------------
void angleMapping(int &i, int &j, int &k) const;
//----------------------------------------------------------------------
//
// Utility methods for getting continuous rotations. None of these
// methods change the orientation given by its inputs (or at least
// that is the intent).
//
// angleMod() converts an angle to its equivalent in [-PI, PI]
//
// simpleXYZRotation() adjusts xyzRot so that its components differ
// from targetXyzRot by no more than +-PI
//
// nearestRotation() adjusts xyzRot so that its components differ
// from targetXyzRot by as little as possible.
// Note that xyz here really means ijk, because
// the order must be provided.
//
// makeNear() adjusts "this" Euler so that its components differ
// from target by as little as possible. This method
// might not make sense for Eulers with different order
// and it probably doesn't work for repeated axis and
// relative orderings (TODO).
//
//-----------------------------------------------------------------------
static float angleMod (T angle);
static void simpleXYZRotation (Vec3<T> &xyzRot,
const Vec3<T> &targetXyzRot);
static void nearestRotation (Vec3<T> &xyzRot,
const Vec3<T> &targetXyzRot,
Order order = XYZ);
void makeNear (const Euler<T> &target);
bool frameStatic() const { return _frameStatic; }
bool initialRepeated() const { return _initialRepeated; }
bool parityEven() const { return _parityEven; }
Axis initialAxis() const { return _initialAxis; }
protected:
bool _frameStatic : 1; // relative or static rotations
bool _initialRepeated : 1; // init axis repeated as last
bool _parityEven : 1; // "parity of axis permutation"
#if defined _WIN32 || defined _WIN64
Axis _initialAxis ; // First axis of rotation
#else
Axis _initialAxis : 2; // First axis of rotation
#endif
};
//--------------------
// Convenient typedefs
//--------------------
typedef Euler<float> Eulerf;
typedef Euler<double> Eulerd;
//---------------
// Implementation
//---------------
template<class T>
inline void
Euler<T>::angleOrder(int &i, int &j, int &k) const
{
i = _initialAxis;
j = _parityEven ? (i+1)%3 : (i > 0 ? i-1 : 2);
k = _parityEven ? (i > 0 ? i-1 : 2) : (i+1)%3;
}
template<class T>
inline void
Euler<T>::angleMapping(int &i, int &j, int &k) const
{
int m[3];
m[_initialAxis] = 0;
m[(_initialAxis+1) % 3] = _parityEven ? 1 : 2;
m[(_initialAxis+2) % 3] = _parityEven ? 2 : 1;
i = m[0];
j = m[1];
k = m[2];
}
template<class T>
inline void
Euler<T>::setXYZVector(const Vec3<T> &v)
{
int i,j,k;
angleMapping(i,j,k);
(*this)[i] = v.x;
(*this)[j] = v.y;
(*this)[k] = v.z;
}
template<class T>
inline Vec3<T>
Euler<T>::toXYZVector() const
{
int i,j,k;
angleMapping(i,j,k);
return Vec3<T>((*this)[i],(*this)[j],(*this)[k]);
}
template<class T>
Euler<T>::Euler() :
Vec3<T>(0,0,0),
_frameStatic(true),
_initialRepeated(false),
_parityEven(true),
_initialAxis(X)
{}
template<class T>
Euler<T>::Euler(typename Euler<T>::Order p) :
Vec3<T>(0,0,0),
_frameStatic(true),
_initialRepeated(false),
_parityEven(true),
_initialAxis(X)
{
setOrder(p);
}
template<class T>
inline Euler<T>::Euler( const Vec3<T> &v,
typename Euler<T>::Order p,
typename Euler<T>::InputLayout l )
{
setOrder(p);
if ( l == XYZLayout ) setXYZVector(v);
else { x = v.x; y = v.y; z = v.z; }
}
template<class T>
inline Euler<T>::Euler(const Euler<T> &euler)
{
operator=(euler);
}
template<class T>
inline Euler<T>::Euler(const Euler<T> &euler,Order p)
{
setOrder(p);
Matrix33<T> M = euler.toMatrix33();
extract(M);
}
template<class T>
inline Euler<T>::Euler( T xi, T yi, T zi,
typename Euler<T>::Order p,
typename Euler<T>::InputLayout l)
{
setOrder(p);
if ( l == XYZLayout ) setXYZVector(Vec3<T>(xi,yi,zi));
else { x = xi; y = yi; z = zi; }
}
template<class T>
inline Euler<T>::Euler( const Matrix33<T> &M, typename Euler::Order p )
{
setOrder(p);
extract(M);
}
template<class T>
inline Euler<T>::Euler( const Matrix44<T> &M, typename Euler::Order p )
{
setOrder(p);
extract(M);
}
template<class T>
inline void Euler<T>::extract(const Quat<T> &q)
{
extract(q.toMatrix33());
}
template<class T>
void Euler<T>::extract(const Matrix33<T> &M)
{
int i,j,k;
angleOrder(i,j,k);
if (_initialRepeated)
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][i], M[k][i]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
M[1][0], M[1][1], M[1][2], 0,
M[2][0], M[2][1], M[2][2], 0,
0, 0, 0, 1);
//
// Extract the other two angles, y and z, from N.
//
T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
y = Math<T>::atan2 (sy, N[i][i]);
z = Math<T>::atan2 (N[j][k], N[j][j]);
}
else
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][k], M[k][k]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
M[1][0], M[1][1], M[1][2], 0,
M[2][0], M[2][1], M[2][2], 0,
0, 0, 0, 1);
//
// Extract the other two angles, y and z, from N.
//
T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
y = Math<T>::atan2 (-N[i][k], cy);
z = Math<T>::atan2 (-N[j][i], N[j][j]);
}
if (!_parityEven)
*this *= -1;
if (!_frameStatic)
{
T t = x;
x = z;
z = t;
}
}
template<class T>
void Euler<T>::extract(const Matrix44<T> &M)
{
int i,j,k;
angleOrder(i,j,k);
if (_initialRepeated)
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][i], M[k][i]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * M;
//
// Extract the other two angles, y and z, from N.
//
T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
y = Math<T>::atan2 (sy, N[i][i]);
z = Math<T>::atan2 (N[j][k], N[j][j]);
}
else
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][k], M[k][k]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * M;
//
// Extract the other two angles, y and z, from N.
//
T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
y = Math<T>::atan2 (-N[i][k], cy);
z = Math<T>::atan2 (-N[j][i], N[j][j]);
}
if (!_parityEven)
*this *= -1;
if (!_frameStatic)
{
T t = x;
x = z;
z = t;
}
}
template<class T>
Matrix33<T> Euler<T>::toMatrix33() const
{
int i,j,k;
angleOrder(i,j,k);
Vec3<T> angles;
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles *= -1.0;
T ci = Math<T>::cos(angles.x);
T cj = Math<T>::cos(angles.y);
T ch = Math<T>::cos(angles.z);
T si = Math<T>::sin(angles.x);
T sj = Math<T>::sin(angles.y);
T sh = Math<T>::sin(angles.z);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
Matrix33<T> M;
if ( _initialRepeated )
{
M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci;
M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss;
}
else
{
M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci;
}
return M;
}
template<class T>
Matrix44<T> Euler<T>::toMatrix44() const
{
int i,j,k;
angleOrder(i,j,k);
Vec3<T> angles;
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles *= -1.0;
T ci = Math<T>::cos(angles.x);
T cj = Math<T>::cos(angles.y);
T ch = Math<T>::cos(angles.z);
T si = Math<T>::sin(angles.x);
T sj = Math<T>::sin(angles.y);
T sh = Math<T>::sin(angles.z);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
Matrix44<T> M;
if ( _initialRepeated )
{
M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci;
M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss;
}
else
{
M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci;
}
return M;
}
template<class T>
Quat<T> Euler<T>::toQuat() const
{
Vec3<T> angles;
int i,j,k;
angleOrder(i,j,k);
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles.y = -angles.y;
T ti = angles.x*0.5;
T tj = angles.y*0.5;
T th = angles.z*0.5;
T ci = Math<T>::cos(ti);
T cj = Math<T>::cos(tj);
T ch = Math<T>::cos(th);
T si = Math<T>::sin(ti);
T sj = Math<T>::sin(tj);
T sh = Math<T>::sin(th);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
T parity = _parityEven ? 1.0 : -1.0;
Quat<T> q;
Vec3<T> a;
if ( _initialRepeated )
{
a[i] = cj*(cs + sc);
a[j] = sj*(cc + ss) * parity,
a[k] = sj*(cs - sc);
q.r = cj*(cc - ss);
}
else
{
a[i] = cj*sc - sj*cs,
a[j] = (cj*ss + sj*cc) * parity,
a[k] = cj*cs - sj*sc;
q.r = cj*cc + sj*ss;
}
q.v = a;
return q;
}
template<class T>
inline bool
Euler<T>::legal(typename Euler<T>::Order order)
{
return (order & ~Legal) ? false : true;
}
template<class T>
typename Euler<T>::Order
Euler<T>::order() const
{
int foo = (_initialAxis == Z ? 0x2000 : (_initialAxis == Y ? 0x1000 : 0));
if (_parityEven) foo |= 0x0100;
if (_initialRepeated) foo |= 0x0010;
if (_frameStatic) foo++;
return (Order)foo;
}
template<class T>
inline void Euler<T>::setOrder(typename Euler<T>::Order p)
{
set( p & 0x2000 ? Z : (p & 0x1000 ? Y : X), // initial axis
!(p & 0x1), // static?
!!(p & 0x100), // permutation even?
!!(p & 0x10)); // initial repeats?
}
template<class T>
void Euler<T>::set(typename Euler<T>::Axis axis,
bool relative,
bool parityEven,
bool firstRepeats)
{
_initialAxis = axis;
_frameStatic = !relative;
_parityEven = parityEven;
_initialRepeated = firstRepeats;
}
template<class T>
const Euler<T>& Euler<T>::operator= (const Euler<T> &euler)
{
x = euler.x;
y = euler.y;
z = euler.z;
_initialAxis = euler._initialAxis;
_frameStatic = euler._frameStatic;
_parityEven = euler._parityEven;
_initialRepeated = euler._initialRepeated;
return *this;
}
template<class T>
const Euler<T>& Euler<T>::operator= (const Vec3<T> &v)
{
x = v.x;
y = v.y;
z = v.z;
return *this;
}
template<class T>
std::ostream& operator << (std::ostream &o, const Euler<T> &euler)
{
char a[3] = { 'X', 'Y', 'Z' };
const char* r = euler.frameStatic() ? "" : "r";
int i,j,k;
euler.angleOrder(i,j,k);
if ( euler.initialRepeated() ) k = i;
return o << "("
<< euler.x << " "
<< euler.y << " "
<< euler.z << " "
<< a[i] << a[j] << a[k] << r << ")";
}
template <class T>
float
Euler<T>::angleMod (T angle)
{
angle = fmod(T (angle), T (2 * M_PI));
if (angle < -M_PI) angle += 2 * M_PI;
if (angle > +M_PI) angle -= 2 * M_PI;
return angle;
}
template <class T>
void
Euler<T>::simpleXYZRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot)
{
Vec3<T> d = xyzRot - targetXyzRot;
xyzRot[0] = targetXyzRot[0] + angleMod(d[0]);
xyzRot[1] = targetXyzRot[1] + angleMod(d[1]);
xyzRot[2] = targetXyzRot[2] + angleMod(d[2]);
}
template <class T>
void
Euler<T>::nearestRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot,
Order order)
{
int i,j,k;
Euler<T> e (0,0,0, order);
e.angleOrder(i,j,k);
simpleXYZRotation(xyzRot, targetXyzRot);
Vec3<T> otherXyzRot;
otherXyzRot[i] = M_PI+xyzRot[i];
otherXyzRot[j] = M_PI-xyzRot[j];
otherXyzRot[k] = M_PI+xyzRot[k];
simpleXYZRotation(otherXyzRot, targetXyzRot);
Vec3<T> d = xyzRot - targetXyzRot;
Vec3<T> od = otherXyzRot - targetXyzRot;
T dMag = d.dot(d);
T odMag = od.dot(od);
if (odMag < dMag)
{
xyzRot = otherXyzRot;
}
}
template <class T>
void
Euler<T>::makeNear (const Euler<T> &target)
{
Vec3<T> xyzRot = toXYZVector();
Vec3<T> targetXyz;
if (order() != target.order())
{
Euler<T> targetSameOrder = Euler<T>(target, order());
targetXyz = targetSameOrder.toXYZVector();
}
else
{
targetXyz = target.toXYZVector();
}
nearestRotation(xyzRot, targetXyz, order());
setXYZVector(xyzRot);
}
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#pragma warning(default:4244)
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHEULER_H

View File

@@ -0,0 +1,73 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHEXC_H
#define INCLUDED_IMATHEXC_H
//-----------------------------------------------
//
// Imath library-specific exceptions
//
//-----------------------------------------------
#include "ImathNamespace.h"
#include "IexBaseExc.h"
#include "ImathExport.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
// Attempt to normalize null vector
DEFINE_EXC_EXP (IMATH_EXPORT, NullVecExc, ::IEX_NAMESPACE::MathExc)
// Attempt to normalize a point at infinity
DEFINE_EXC_EXP (IMATH_EXPORT, InfPointExc, ::IEX_NAMESPACE::MathExc)
// Attempt to normalize null quaternion
DEFINE_EXC_EXP (IMATH_EXPORT, NullQuatExc, ::IEX_NAMESPACE::MathExc)
// Attempt to invert singular matrix
DEFINE_EXC_EXP (IMATH_EXPORT, SingMatrixExc, ::IEX_NAMESPACE::MathExc)
// Attempt to remove zero scaling from matrix
DEFINE_EXC_EXP (IMATH_EXPORT, ZeroScaleExc, ::IEX_NAMESPACE::MathExc)
// Attempt to normalize a vector of whose elementsare an integer type
DEFINE_EXC_EXP (IMATH_EXPORT, IntVecNormalizeExc, ::IEX_NAMESPACE::MathExc)
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHEXC_H

View File

@@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, 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.
//
///////////////////////////////////////////////////////////////////////////
#if defined(OPENEXR_DLL)
#if defined(IMATH_EXPORTS)
#define IMATH_EXPORT __declspec(dllexport)
#define IMATH_EXPORT_CONST extern __declspec(dllexport)
#else
#define IMATH_EXPORT __declspec(dllimport)
#define IMATH_EXPORT_CONST extern __declspec(dllimport)
#endif
#else
#define IMATH_EXPORT
#define IMATH_EXPORT_CONST extern const
#endif

View File

@@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, 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_IMATHFORWARD_H
#define INCLUDED_IMATHFORWARD_H
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Basic template type declarations.
//
template <class T> class Box;
template <class T> class Color3;
template <class T> class Color4;
template <class T> class Euler;
template <class T> class Frustum;
template <class T> class FrustumTest;
template <class T> class Interval;
template <class T> class Line3;
template <class T> class Matrix33;
template <class T> class Matrix44;
template <class T> class Plane3;
template <class T> class Quat;
template <class T> class Shear6;
template <class T> class Sphere3;
template <class T> class TMatrix;
template <class T> class TMatrixBase;
template <class T> class TMatrixData;
template <class T> class Vec2;
template <class T> class Vec3;
template <class T> class Vec4;
class Rand32;
class Rand48;
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFORWARD_H

View File

@@ -0,0 +1,192 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHFRAME_H
#define INCLUDED_IMATHFRAME_H
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template<class T> class Vec3;
template<class T> class Matrix44;
//
// These methods compute a set of reference frames, defined by their
// transformation matrix, along a curve. It is designed so that the
// array of points and the array of matrices used to fetch these routines
// don't need to be ordered as the curve.
//
// A typical usage would be :
//
// m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] );
// for( int i = 1; i < n - 1; i++ )
// {
// m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
// }
// m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] );
//
// See Graphics Gems I for the underlying algorithm.
//
template<class T> Matrix44<T> firstFrame( const Vec3<T>&, // First point
const Vec3<T>&, // Second point
const Vec3<T>& ); // Third point
template<class T> Matrix44<T> nextFrame( const Matrix44<T>&, // Previous matrix
const Vec3<T>&, // Previous point
const Vec3<T>&, // Current point
Vec3<T>&, // Previous tangent
Vec3<T>& ); // Current tangent
template<class T> Matrix44<T> lastFrame( const Matrix44<T>&, // Previous matrix
const Vec3<T>&, // Previous point
const Vec3<T>& ); // Last point
//
// firstFrame - Compute the first reference frame along a curve.
//
// This function returns the transformation matrix to the reference frame
// defined by the three points 'pi', 'pj' and 'pk'. Note that if the two
// vectors <pi,pj> and <pi,pk> are colinears, an arbitrary twist value will
// be choosen.
//
// Throw 'NullVecExc' if 'pi' and 'pj' are equals.
//
template<class T> Matrix44<T> firstFrame
(
const Vec3<T>& pi, // First point
const Vec3<T>& pj, // Second point
const Vec3<T>& pk ) // Third point
{
Vec3<T> t = pj - pi; t.normalizeExc();
Vec3<T> n = t.cross( pk - pi ); n.normalize();
if( n.length() == 0.0f )
{
int i = fabs( t[0] ) < fabs( t[1] ) ? 0 : 1;
if( fabs( t[2] ) < fabs( t[i] )) i = 2;
Vec3<T> v( 0.0, 0.0, 0.0 ); v[i] = 1.0;
n = t.cross( v ); n.normalize();
}
Vec3<T> b = t.cross( n );
Matrix44<T> M;
M[0][0] = t[0]; M[0][1] = t[1]; M[0][2] = t[2]; M[0][3] = 0.0,
M[1][0] = n[0]; M[1][1] = n[1]; M[1][2] = n[2]; M[1][3] = 0.0,
M[2][0] = b[0]; M[2][1] = b[1]; M[2][2] = b[2]; M[2][3] = 0.0,
M[3][0] = pi[0]; M[3][1] = pi[1]; M[3][2] = pi[2]; M[3][3] = 1.0;
return M;
}
//
// nextFrame - Compute the next reference frame along a curve.
//
// This function returns the transformation matrix to the next reference
// frame defined by the previously computed transformation matrix and the
// new point and tangent vector along the curve.
//
template<class T> Matrix44<T> nextFrame
(
const Matrix44<T>& Mi, // Previous matrix
const Vec3<T>& pi, // Previous point
const Vec3<T>& pj, // Current point
Vec3<T>& ti, // Previous tangent vector
Vec3<T>& tj ) // Current tangent vector
{
Vec3<T> a(0.0, 0.0, 0.0); // Rotation axis.
T r = 0.0; // Rotation angle.
if( ti.length() != 0.0 && tj.length() != 0.0 )
{
ti.normalize(); tj.normalize();
T dot = ti.dot( tj );
//
// This is *really* necessary :
//
if( dot > 1.0 ) dot = 1.0;
else if( dot < -1.0 ) dot = -1.0;
r = acosf( dot );
a = ti.cross( tj );
}
if( a.length() != 0.0 && r != 0.0 )
{
Matrix44<T> R; R.setAxisAngle( a, r );
Matrix44<T> Tj; Tj.translate( pj );
Matrix44<T> Ti; Ti.translate( -pi );
return Mi * Ti * R * Tj;
}
else
{
Matrix44<T> Tr; Tr.translate( pj - pi );
return Mi * Tr;
}
}
//
// lastFrame - Compute the last reference frame along a curve.
//
// This function returns the transformation matrix to the last reference
// frame defined by the previously computed transformation matrix and the
// last point along the curve.
//
template<class T> Matrix44<T> lastFrame
(
const Matrix44<T>& Mi, // Previous matrix
const Vec3<T>& pi, // Previous point
const Vec3<T>& pj ) // Last point
{
Matrix44<T> Tr; Tr.translate( pj - pi );
return Mi * Tr;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFRAME_H

View File

@@ -0,0 +1,741 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHFRUSTUM_H
#define INCLUDED_IMATHFRUSTUM_H
#include "ImathVec.h"
#include "ImathPlane.h"
#include "ImathLine.h"
#include "ImathMatrix.h"
#include "ImathLimits.h"
#include "ImathFun.h"
#include "ImathNamespace.h"
#include "IexMathExc.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// template class Frustum<T>
//
// The frustum is always located with the eye point at the
// origin facing down -Z. This makes the Frustum class
// compatable with OpenGL (or anything that assumes a camera
// looks down -Z, hence with a right-handed coordinate system)
// but not with RenderMan which assumes the camera looks down
// +Z. Additional functions are provided for conversion from
// and from various camera coordinate spaces.
//
// nearPlane/farPlane: near/far are keywords used by Microsoft's
// compiler, so we use nearPlane/farPlane instead to avoid
// issues.
template<class T>
class Frustum
{
public:
Frustum();
Frustum(const Frustum &);
Frustum(T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho=false);
Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
virtual ~Frustum();
//--------------------
// Assignment operator
//--------------------
const Frustum & operator = (const Frustum &);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Frustum<T> &src) const;
bool operator != (const Frustum<T> &src) const;
//--------------------------------------------------------
// Set functions change the entire state of the Frustum
//--------------------------------------------------------
void set(T nearPlane, T farPlane,
T left, T right,
T top, T bottom,
bool ortho=false);
void set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
//------------------------------------------------------
// These functions modify an already valid frustum state
//------------------------------------------------------
void modifyNearAndFar(T nearPlane, T farPlane);
void setOrthographic(bool);
//--------------
// Access
//--------------
bool orthographic() const { return _orthographic; }
T nearPlane() const { return _nearPlane; }
T hither() const { return _nearPlane; }
T farPlane() const { return _farPlane; }
T yon() const { return _farPlane; }
T left() const { return _left; }
T right() const { return _right; }
T bottom() const { return _bottom; }
T top() const { return _top; }
//-----------------------------------------------------------------------
// Sets the planes in p to be the six bounding planes of the frustum, in
// the following order: top, right, bottom, left, near, far.
// Note that the planes have normals that point out of the frustum.
// The version of this routine that takes a matrix applies that matrix
// to transform the frustum before setting the planes.
//-----------------------------------------------------------------------
void planes(Plane3<T> p[6]) const;
void planes(Plane3<T> p[6], const Matrix44<T> &M) const;
//----------------------
// Derived Quantities
//----------------------
T fovx() const;
T fovy() const;
T aspect() const;
Matrix44<T> projectionMatrix() const;
bool degenerate() const;
//-----------------------------------------------------------------------
// Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1
// and -1 <= bottom <= top <= 1) of this Frustum, and returns a new
// Frustum whose near clipping-plane window is that rectangle in local
// space.
//-----------------------------------------------------------------------
Frustum<T> window(T left, T right, T top, T bottom) const;
//----------------------------------------------------------
// Projection is in screen space / Conversion from Z-Buffer
//----------------------------------------------------------
Line3<T> projectScreenToRay( const Vec2<T> & ) const;
Vec2<T> projectPointToScreen( const Vec3<T> & ) const;
T ZToDepth(long zval, long min, long max) const;
T normalizedZToDepth(T zval) const;
long DepthToZ(T depth, long zmin, long zmax) const;
T worldRadius(const Vec3<T> &p, T radius) const;
T screenRadius(const Vec3<T> &p, T radius) const;
protected:
Vec2<T> screenToLocal( const Vec2<T> & ) const;
Vec2<T> localToScreen( const Vec2<T> & ) const;
protected:
T _nearPlane;
T _farPlane;
T _left;
T _right;
T _top;
T _bottom;
bool _orthographic;
};
template<class T>
inline Frustum<T>::Frustum()
{
set(T (0.1),
T (1000.0),
T (-1.0),
T (1.0),
T (1.0),
T (-1.0),
false);
}
template<class T>
inline Frustum<T>::Frustum(const Frustum &f)
{
*this = f;
}
template<class T>
inline Frustum<T>::Frustum(T n, T f, T l, T r, T t, T b, bool o)
{
set(n,f,l,r,t,b,o);
}
template<class T>
inline Frustum<T>::Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
{
set(nearPlane,farPlane,fovx,fovy,aspect);
}
template<class T>
Frustum<T>::~Frustum()
{
}
template<class T>
const Frustum<T> &
Frustum<T>::operator = (const Frustum &f)
{
_nearPlane = f._nearPlane;
_farPlane = f._farPlane;
_left = f._left;
_right = f._right;
_top = f._top;
_bottom = f._bottom;
_orthographic = f._orthographic;
return *this;
}
template <class T>
bool
Frustum<T>::operator == (const Frustum<T> &src) const
{
return
_nearPlane == src._nearPlane &&
_farPlane == src._farPlane &&
_left == src._left &&
_right == src._right &&
_top == src._top &&
_bottom == src._bottom &&
_orthographic == src._orthographic;
}
template <class T>
inline bool
Frustum<T>::operator != (const Frustum<T> &src) const
{
return !operator== (src);
}
template<class T>
void Frustum<T>::set(T n, T f, T l, T r, T t, T b, bool o)
{
_nearPlane = n;
_farPlane = f;
_left = l;
_right = r;
_bottom = b;
_top = t;
_orthographic = o;
}
template<class T>
void Frustum<T>::modifyNearAndFar(T n, T f)
{
if ( _orthographic )
{
_nearPlane = n;
}
else
{
Line3<T> lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
Vec3<T> ll,ur;
nearPlane.intersect(lowerLeft,ll);
nearPlane.intersect(upperRight,ur);
_left = ll.x;
_right = ur.x;
_top = ur.y;
_bottom = ll.y;
_nearPlane = n;
_farPlane = f;
}
_farPlane = f;
}
template<class T>
void Frustum<T>::setOrthographic(bool ortho)
{
_orthographic = ortho;
}
template<class T>
void Frustum<T>::set(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
{
if (fovx != 0 && fovy != 0)
throw IEX_NAMESPACE::ArgExc ("fovx and fovy cannot both be non-zero.");
const T two = static_cast<T>(2);
if (fovx != 0)
{
_right = nearPlane * Math<T>::tan(fovx / two);
_left = -_right;
_top = ((_right - _left) / aspect) / two;
_bottom = -_top;
}
else
{
_top = nearPlane * Math<T>::tan(fovy / two);
_bottom = -_top;
_right = (_top - _bottom) * aspect / two;
_left = -_right;
}
_nearPlane = nearPlane;
_farPlane = farPlane;
_orthographic = false;
}
template<class T>
T Frustum<T>::fovx() const
{
return Math<T>::atan2(_right,_nearPlane) - Math<T>::atan2(_left,_nearPlane);
}
template<class T>
T Frustum<T>::fovy() const
{
return Math<T>::atan2(_top,_nearPlane) - Math<T>::atan2(_bottom,_nearPlane);
}
template<class T>
T Frustum<T>::aspect() const
{
T rightMinusLeft = _right-_left;
T topMinusBottom = _top-_bottom;
if (abs(topMinusBottom) < 1 &&
abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"aspect ratio cannot be computed.");
}
return rightMinusLeft / topMinusBottom;
}
template<class T>
Matrix44<T> Frustum<T>::projectionMatrix() const
{
T rightPlusLeft = _right+_left;
T rightMinusLeft = _right-_left;
T topPlusBottom = _top+_bottom;
T topMinusBottom = _top-_bottom;
T farPlusNear = _farPlane+_nearPlane;
T farMinusNear = _farPlane-_nearPlane;
if ((abs(rightMinusLeft) < 1 &&
abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
(abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
if ( _orthographic )
{
T tx = -rightPlusLeft / rightMinusLeft;
T ty = -topPlusBottom / topMinusBottom;
T tz = -farPlusNear / farMinusNear;
if ((abs(rightMinusLeft) < 1 &&
2 > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
2 > limits<T>::max() * abs(topMinusBottom)) ||
(abs(farMinusNear) < 1 &&
2 > limits<T>::max() * abs(farMinusNear)))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T A = 2 / rightMinusLeft;
T B = 2 / topMinusBottom;
T C = -2 / farMinusNear;
return Matrix44<T>( A, 0, 0, 0,
0, B, 0, 0,
0, 0, C, 0,
tx, ty, tz, 1.f );
}
else
{
T A = rightPlusLeft / rightMinusLeft;
T B = topPlusBottom / topMinusBottom;
T C = -farPlusNear / farMinusNear;
T farTimesNear = -2 * _farPlane * _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T D = farTimesNear / farMinusNear;
T twoTimesNear = 2 * _nearPlane;
if ((abs(rightMinusLeft) < 1 &&
abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T E = twoTimesNear / rightMinusLeft;
T F = twoTimesNear / topMinusBottom;
return Matrix44<T>( E, 0, 0, 0,
0, F, 0, 0,
A, B, C, -1,
0, 0, D, 0 );
}
}
template<class T>
bool Frustum<T>::degenerate() const
{
return (_nearPlane == _farPlane) ||
(_left == _right) ||
(_top == _bottom);
}
template<class T>
Frustum<T> Frustum<T>::window(T l, T r, T t, T b) const
{
// move it to 0->1 space
Vec2<T> bl = screenToLocal( Vec2<T>(l,b) );
Vec2<T> tr = screenToLocal( Vec2<T>(r,t) );
return Frustum<T>(_nearPlane, _farPlane, bl.x, tr.x, tr.y, bl.y, _orthographic);
}
template<class T>
Vec2<T> Frustum<T>::screenToLocal(const Vec2<T> &s) const
{
return Vec2<T>( _left + (_right-_left) * (1.f+s.x) / 2.f,
_bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
}
template<class T>
Vec2<T> Frustum<T>::localToScreen(const Vec2<T> &p) const
{
T leftPlusRight = _left - T (2) * p.x + _right;
T leftMinusRight = _left-_right;
T bottomPlusTop = _bottom - T (2) * p.y + _top;
T bottomMinusTop = _bottom-_top;
if ((abs(leftMinusRight) < T (1) &&
abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
(abs(bottomMinusTop) < T (1) &&
abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: "
"local-to-screen transformation cannot be computed");
}
return Vec2<T>( leftPlusRight / leftMinusRight,
bottomPlusTop / bottomMinusTop );
}
template<class T>
Line3<T> Frustum<T>::projectScreenToRay(const Vec2<T> &p) const
{
Vec2<T> point = screenToLocal(p);
if (orthographic())
return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
Vec3<T>(point.x,point.y,-1.0));
else
return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
}
template<class T>
Vec2<T> Frustum<T>::projectPointToScreen(const Vec3<T> &point) const
{
if (orthographic() || point.z == T (0))
return localToScreen( Vec2<T>( point.x, point.y ) );
else
return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z,
point.y * _nearPlane / -point.z ) );
}
template<class T>
T Frustum<T>::ZToDepth(long zval,long zmin,long zmax) const
{
int zdiff = zmax - zmin;
if (zdiff == 0)
{
throw IEX_NAMESPACE::DivzeroExc
("Bad call to Frustum::ZToDepth: zmax == zmin");
}
if ( zval > zmax+1 ) zval -= zdiff;
T fzval = (T(zval) - T(zmin)) / T(zdiff);
return normalizedZToDepth(fzval);
}
template<class T>
T Frustum<T>::normalizedZToDepth(T zval) const
{
T Zp = zval * 2.0 - 1;
if ( _orthographic )
{
return -(Zp*(_farPlane-_nearPlane) + (_farPlane+_nearPlane))/2;
}
else
{
T farTimesNear = 2 * _farPlane * _nearPlane;
T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc
("Frustum::normalizedZToDepth cannot be computed. The "
"near and far clipping planes of the viewing frustum "
"may be too close to each other");
}
return farTimesNear / farMinusNear;
}
}
template<class T>
long Frustum<T>::DepthToZ(T depth,long zmin,long zmax) const
{
long zdiff = zmax - zmin;
T farMinusNear = _farPlane-_nearPlane;
if ( _orthographic )
{
T farPlusNear = 2*depth + _farPlane + _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: near and far clipping planes "
"are too close to each other");
}
T Zp = -farPlusNear/farMinusNear;
return long(0.5*(Zp+1)*zdiff) + zmin;
}
else
{
// Perspective
T farTimesNear = 2*_farPlane*_nearPlane;
if (abs(depth) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(depth))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad call to DepthToZ function: value of `depth' "
"is too small");
}
T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: near and far clipping planes "
"are too close to each other");
}
T Zp = farPlusNear/farMinusNear;
return long(0.5*(Zp+1)*zdiff) + zmin;
}
}
template<class T>
T Frustum<T>::screenRadius(const Vec3<T> &p, T radius) const
{
// Derivation:
// Consider X-Z plane.
// X coord of projection of p = xp = p.x * (-_nearPlane / p.z)
// Let q be p + (radius, 0, 0).
// X coord of projection of q = xq = (p.x - radius) * (-_nearPlane / p.z)
// X coord of projection of segment from p to q = r = xp - xq
// = radius * (-_nearPlane / p.z)
// A similar analysis holds in the Y-Z plane.
// So r is the quantity we want to return.
if (abs(p.z) > 1 || abs(-_nearPlane) < limits<T>::max() * abs(p.z))
{
return radius * (-_nearPlane / p.z);
}
else
{
throw IEX_NAMESPACE::DivzeroExc
("Bad call to Frustum::screenRadius: the magnitude of `p' "
"is too small");
}
return radius * (-_nearPlane / p.z);
}
template<class T>
T Frustum<T>::worldRadius(const Vec3<T> &p, T radius) const
{
if (abs(-_nearPlane) > 1 || abs(p.z) < limits<T>::max() * abs(-_nearPlane))
{
return radius * (p.z / -_nearPlane);
}
else
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: the near clipping plane is too "
"close to zero");
}
}
template<class T>
void Frustum<T>::planes(Plane3<T> p[6]) const
{
//
// Plane order: Top, Right, Bottom, Left, Near, Far.
// Normals point outwards.
//
if (! _orthographic)
{
Vec3<T> a( _left, _bottom, -_nearPlane);
Vec3<T> b( _left, _top, -_nearPlane);
Vec3<T> c( _right, _top, -_nearPlane);
Vec3<T> d( _right, _bottom, -_nearPlane);
Vec3<T> o(0,0,0);
p[0].set( o, c, b );
p[1].set( o, d, c );
p[2].set( o, a, d );
p[3].set( o, b, a );
}
else
{
p[0].set( Vec3<T>( 0, 1, 0), _top );
p[1].set( Vec3<T>( 1, 0, 0), _right );
p[2].set( Vec3<T>( 0,-1, 0),-_bottom );
p[3].set( Vec3<T>(-1, 0, 0),-_left );
}
p[4].set( Vec3<T>(0, 0, 1), -_nearPlane );
p[5].set( Vec3<T>(0, 0,-1), _farPlane );
}
template<class T>
void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M) const
{
//
// Plane order: Top, Right, Bottom, Left, Near, Far.
// Normals point outwards.
//
Vec3<T> a = Vec3<T>( _left, _bottom, -_nearPlane) * M;
Vec3<T> b = Vec3<T>( _left, _top, -_nearPlane) * M;
Vec3<T> c = Vec3<T>( _right, _top, -_nearPlane) * M;
Vec3<T> d = Vec3<T>( _right, _bottom, -_nearPlane) * M;
if (! _orthographic)
{
double s = _farPlane / double(_nearPlane);
T farLeft = (T) (s * _left);
T farRight = (T) (s * _right);
T farTop = (T) (s * _top);
T farBottom = (T) (s * _bottom);
Vec3<T> e = Vec3<T>( farLeft, farBottom, -_farPlane) * M;
Vec3<T> f = Vec3<T>( farLeft, farTop, -_farPlane) * M;
Vec3<T> g = Vec3<T>( farRight, farTop, -_farPlane) * M;
Vec3<T> o = Vec3<T>(0,0,0) * M;
p[0].set( o, c, b );
p[1].set( o, d, c );
p[2].set( o, a, d );
p[3].set( o, b, a );
p[4].set( a, d, c );
p[5].set( e, f, g );
}
else
{
Vec3<T> e = Vec3<T>( _left, _bottom, -_farPlane) * M;
Vec3<T> f = Vec3<T>( _left, _top, -_farPlane) * M;
Vec3<T> g = Vec3<T>( _right, _top, -_farPlane) * M;
Vec3<T> h = Vec3<T>( _right, _bottom, -_farPlane) * M;
p[0].set( c, g, f );
p[1].set( d, h, g );
p[2].set( a, e, h );
p[3].set( b, f, e );
p[4].set( a, d, c );
p[5].set( e, f, g );
}
}
typedef Frustum<float> Frustumf;
typedef Frustum<double> Frustumd;
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#if defined _WIN32 || defined _WIN64
#ifdef _redef_near
#define near
#endif
#ifdef _redef_far
#define far
#endif
#endif
#endif // INCLUDED_IMATHFRUSTUM_H

View File

@@ -0,0 +1,417 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2011-2012, 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_IMATHFRUSTUMTEST_H
#define INCLUDED_IMATHFRUSTUMTEST_H
//-------------------------------------------------------------------------
//
// This file contains algorithms applied to or in conjunction with
// Frustum visibility testing (Imath::Frustum).
//
// Methods for frustum-based rejection of primitives are contained here.
//
//-------------------------------------------------------------------------
#include "ImathFrustum.h"
#include "ImathBox.h"
#include "ImathSphere.h"
#include "ImathMatrix.h"
#include "ImathVec.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
/////////////////////////////////////////////////////////////////
// FrustumTest
//
// template class FrustumTest<T>
//
// This is a helper class, designed to accelerate the case
// where many tests are made against the same frustum.
// That's a really common case.
//
// The acceleration is achieved by pre-computing the planes of
// the frustum, along with the ablsolute values of the plane normals.
//
//////////////////////////////////////////////////////////////////
// How to use this
//
// Given that you already have:
// Imath::Frustum myFrustum
// Imath::Matrix44 myCameraWorldMatrix
//
// First, make a frustum test object:
// FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix)
//
// Whenever the camera or frustum changes, call:
// myFrustumTest.setFrustum(myFrustum, myCameraWorldMatrix)
//
// For each object you want to test for visibility, call:
// myFrustumTest.isVisible(myBox)
// myFrustumTest.isVisible(mySphere)
// myFrustumTest.isVisible(myVec3)
// myFrustumTest.completelyContains(myBox)
// myFrustumTest.completelyContains(mySphere)
//
//////////////////////////////////////////////////////////////////
// Explanation of how it works
//
//
// We store six world-space Frustum planes (nx, ny, nz, offset)
//
// Points: To test a Vec3 for visibility, test it against each plane
// using the normal (v dot n - offset) method. (the result is exact)
//
// BBoxes: To test an axis-aligned bbox, test the center against each plane
// using the normal (v dot n - offset) method, but offset by the
// box extents dot the abs of the plane normal. (the result is NOT
// exact, but will not return false-negatives.)
//
// Spheres: To test a sphere, test the center against each plane
// using the normal (v dot n - offset) method, but offset by the
// sphere's radius. (the result is NOT exact, but will not return
// false-negatives.)
//
//
// SPECIAL NOTE: "Where are the dot products?"
// Actual dot products are currently slow for most SIMD architectures.
// In order to keep this code optimization-ready, the dot products
// are all performed using vector adds and multipies.
//
// In order to do this, the plane equations are stored in "transpose"
// form, with the X components grouped into an X vector, etc.
//
template <class T>
class FrustumTest
{
public:
FrustumTest()
{
Frustum<T> frust;
Matrix44<T> cameraMat;
cameraMat.makeIdentity();
setFrustum(frust, cameraMat);
}
FrustumTest(const Frustum<T> &frustum, const Matrix44<T> &cameraMat)
{
setFrustum(frustum, cameraMat);
}
////////////////////////////////////////////////////////////////////
// setFrustum()
// This updates the frustum test with a new frustum and matrix.
// This should usually be called just once per frame.
void setFrustum(const Frustum<T> &frustum, const Matrix44<T> &cameraMat);
////////////////////////////////////////////////////////////////////
// isVisible()
// Check to see if shapes are visible.
bool isVisible(const Sphere3<T> &sphere) const;
bool isVisible(const Box<Vec3<T> > &box) const;
bool isVisible(const Vec3<T> &vec) const;
////////////////////////////////////////////////////////////////////
// completelyContains()
// Check to see if shapes are entirely contained.
bool completelyContains(const Sphere3<T> &sphere) const;
bool completelyContains(const Box<Vec3<T> > &box) const;
// These next items are kept primarily for debugging tools.
// It's useful for drawing the culling environment, and also
// for getting an "outside view" of the culling frustum.
IMATH_INTERNAL_NAMESPACE::Matrix44<T> cameraMat() const {return cameraMatrix;}
IMATH_INTERNAL_NAMESPACE::Frustum<T> currentFrustum() const {return currFrustum;}
protected:
// To understand why the planes are stored this way, see
// the SPECIAL NOTE above.
Vec3<T> planeNormX[2]; // The X compunents from 6 plane equations
Vec3<T> planeNormY[2]; // The Y compunents from 6 plane equations
Vec3<T> planeNormZ[2]; // The Z compunents from 6 plane equations
Vec3<T> planeOffsetVec[2]; // The distance offsets from 6 plane equations
// The absolute values are stored to assist with bounding box tests.
Vec3<T> planeNormAbsX[2]; // The abs(X) compunents from 6 plane equations
Vec3<T> planeNormAbsY[2]; // The abs(X) compunents from 6 plane equations
Vec3<T> planeNormAbsZ[2]; // The abs(X) compunents from 6 plane equations
// These are kept primarily for debugging tools.
Frustum<T> currFrustum;
Matrix44<T> cameraMatrix;
};
////////////////////////////////////////////////////////////////////
// setFrustum()
// This should usually only be called once per frame, or however
// often the camera moves.
template<class T>
void FrustumTest<T>::setFrustum(const Frustum<T> &frustum,
const Matrix44<T> &cameraMat)
{
Plane3<T> frustumPlanes[6];
frustum.planes(frustumPlanes, cameraMat);
// Here's where we effectively transpose the plane equations.
// We stuff all six X's into the two planeNormX vectors, etc.
for (int i = 0; i < 2; ++i)
{
int index = i * 3;
planeNormX[i] = Vec3<T>(frustumPlanes[index + 0].normal.x,
frustumPlanes[index + 1].normal.x,
frustumPlanes[index + 2].normal.x);
planeNormY[i] = Vec3<T>(frustumPlanes[index + 0].normal.y,
frustumPlanes[index + 1].normal.y,
frustumPlanes[index + 2].normal.y);
planeNormZ[i] = Vec3<T>(frustumPlanes[index + 0].normal.z,
frustumPlanes[index + 1].normal.z,
frustumPlanes[index + 2].normal.z);
planeNormAbsX[i] = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].x),
IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].y),
IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].z));
planeNormAbsY[i] = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].x),
IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].y),
IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].z));
planeNormAbsZ[i] = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].x),
IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].y),
IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].z));
planeOffsetVec[i] = Vec3<T>(frustumPlanes[index + 0].distance,
frustumPlanes[index + 1].distance,
frustumPlanes[index + 2].distance);
}
currFrustum = frustum;
cameraMatrix = cameraMat;
}
////////////////////////////////////////////////////////////////////
// isVisible(Sphere)
// Returns true if any part of the sphere is inside
// the frustum.
// The result MAY return close false-positives, but not false-negatives.
//
template<typename T>
bool FrustumTest<T>::isVisible(const Sphere3<T> &sphere) const
{
Vec3<T> center = sphere.center;
Vec3<T> radiusVec = Vec3<T>(sphere.radius, sphere.radius, sphere.radius);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
- radiusVec
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
- radiusVec
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// completelyContains(Sphere)
// Returns true if every part of the sphere is inside
// the frustum.
// The result MAY return close false-negatives, but not false-positives.
//
template<typename T>
bool FrustumTest<T>::completelyContains(const Sphere3<T> &sphere) const
{
Vec3<T> center = sphere.center;
Vec3<T> radiusVec = Vec3<T>(sphere.radius, sphere.radius, sphere.radius);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
+ radiusVec
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
+ radiusVec
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// isVisible(Box)
// Returns true if any part of the axis-aligned box
// is inside the frustum.
// The result MAY return close false-positives, but not false-negatives.
//
template<typename T>
bool FrustumTest<T>::isVisible(const Box<Vec3<T> > &box) const
{
if (box.isEmpty())
return false;
Vec3<T> center = (box.min + box.max) / 2;
Vec3<T> extent = (box.max - center);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
- planeNormAbsX[0] * extent.x
- planeNormAbsY[0] * extent.y
- planeNormAbsZ[0] * extent.z
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
- planeNormAbsX[1] * extent.x
- planeNormAbsY[1] * extent.y
- planeNormAbsZ[1] * extent.z
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// completelyContains(Box)
// Returns true if every part of the axis-aligned box
// is inside the frustum.
// The result MAY return close false-negatives, but not false-positives.
//
template<typename T>
bool FrustumTest<T>::completelyContains(const Box<Vec3<T> > &box) const
{
if (box.isEmpty())
return false;
Vec3<T> center = (box.min + box.max) / 2;
Vec3<T> extent = (box.max - center);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
+ planeNormAbsX[0] * extent.x
+ planeNormAbsY[0] * extent.y
+ planeNormAbsZ[0] * extent.z
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
+ planeNormAbsX[1] * extent.x
+ planeNormAbsY[1] * extent.y
+ planeNormAbsZ[1] * extent.z
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// isVisible(Vec3)
// Returns true if the point is inside the frustum.
//
template<typename T>
bool FrustumTest<T>::isVisible(const Vec3<T> &vec) const
{
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = (planeNormX[0] * vec.x)
+ (planeNormY[0] * vec.y)
+ (planeNormZ[0] * vec.z)
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = (planeNormX[1] * vec.x)
+ (planeNormY[1] * vec.y)
+ (planeNormZ[1] * vec.z)
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
typedef FrustumTest<float> FrustumTestf;
typedef FrustumTest<double> FrustumTestd;
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFRUSTUMTEST_H

View File

@@ -0,0 +1,181 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
#include "ImathFun.h"
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
float
succf (float f)
{
union {float f; int i;} u;
u.f = f;
if ((u.i & 0x7f800000) == 0x7f800000)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x00000000 || u.i == 0x80000000)
{
// Plus or minus zero.
u.i = 0x00000001;
}
else if (u.i > 0)
{
// Positive float, normalized or denormalized.
// Incrementing the largest positive float
// produces +infinity.
++u.i;
}
else
{
// Negative normalized or denormalized float.
--u.i;
}
return u.f;
}
float
predf (float f)
{
union {float f; int i;} u;
u.f = f;
if ((u.i & 0x7f800000) == 0x7f800000)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x00000000 || u.i == 0x80000000)
{
// Plus or minus zero.
u.i = 0x80000001;
}
else if (u.i > 0)
{
// Positive float, normalized or denormalized.
--u.i;
}
else
{
// Negative normalized or denormalized float.
// Decrementing the largest negative float
// produces -infinity.
++u.i;
}
return u.f;
}
double
succd (double d)
{
union {double d; Int64 i;} u;
u.d = d;
if ((u.i & 0x7ff0000000000000LL) == 0x7ff0000000000000LL)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x0000000000000000LL || u.i == 0x8000000000000000LL)
{
// Plus or minus zero.
u.i = 0x0000000000000001LL;
}
else if (u.d > 0)
{
// Positive double, normalized or denormalized.
// Incrementing the largest positive double
// produces +infinity.
++u.i;
}
else
{
// Negative normalized or denormalized double.
--u.i;
}
return u.d;
}
double
predd (double d)
{
union {double d; Int64 i;} u;
u.d = d;
if ((u.i & 0x7ff0000000000000LL) == 0x7ff0000000000000LL)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x0000000000000000LL || u.i == 0x8000000000000000LL)
{
// Plus or minus zero.
u.i = 0x8000000000000001LL;
}
else if (u.d > 0)
{
// Positive double, normalized or denormalized.
--u.i;
}
else
{
// Negative normalized or denormalized double.
// Decrementing the largest negative double
// produces -infinity.
++u.i;
}
return u.d;
}
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

View File

@@ -0,0 +1,269 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHFUN_H
#define INCLUDED_IMATHFUN_H
//-----------------------------------------------------------------------------
//
// Miscellaneous utility functions
//
//-----------------------------------------------------------------------------
#include "ImathExport.h"
#include "ImathLimits.h"
#include "ImathInt64.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
inline T
abs (T a)
{
return (a > T(0)) ? a : -a;
}
template <class T>
inline int
sign (T a)
{
return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0);
}
template <class T, class Q>
inline T
lerp (T a, T b, Q t)
{
return (T) (a * (1 - t) + b * t);
}
template <class T, class Q>
inline T
ulerp (T a, T b, Q t)
{
return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t));
}
template <class T>
inline T
lerpfactor(T m, T a, T b)
{
//
// Return how far m is between a and b, that is return t such that
// if:
// t = lerpfactor(m, a, b);
// then:
// m = lerp(a, b, t);
//
// If a==b, return 0.
//
T d = b - a;
T n = m - a;
if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))
return n / d;
return T(0);
}
template <class T>
inline T
clamp (T a, T l, T h)
{
return (a < l)? l : ((a > h)? h : a);
}
template <class T>
inline int
cmp (T a, T b)
{
return IMATH_INTERNAL_NAMESPACE::sign (a - b);
}
template <class T>
inline int
cmpt (T a, T b, T t)
{
return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t)? 0 : cmp (a, b);
}
template <class T>
inline bool
iszero (T a, T t)
{
return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0;
}
template <class T1, class T2, class T3>
inline bool
equal (T1 a, T2 b, T3 t)
{
return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t;
}
template <class T>
inline int
floor (T x)
{
return (x >= 0)? int (x): -(int (-x) + (-x > int (-x)));
}
template <class T>
inline int
ceil (T x)
{
return -floor (-x);
}
template <class T>
inline int
trunc (T x)
{
return (x >= 0) ? int(x) : -int(-x);
}
//
// Integer division and remainder where the
// remainder of x/y has the same sign as x:
//
// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))
// mods(x,y) == x - y * divs(x,y)
//
inline int
divs (int x, int y)
{
return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
((y >= 0)? -(-x / y): (-x / -y));
}
inline int
mods (int x, int y)
{
return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)):
((y >= 0)? -(-x % y): -(-x % -y));
}
//
// Integer division and remainder where the
// remainder of x/y is always positive:
//
// divp(x,y) == floor (double(x) / double (y))
// modp(x,y) == x - y * divp(x,y)
//
inline int
divp (int x, int y)
{
return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y));
}
inline int
modp (int x, int y)
{
return x - y * divp (x, y);
}
//----------------------------------------------------------
// Successor and predecessor for floating-point numbers:
//
// succf(f) returns float(f+e), where e is the smallest
// positive number such that float(f+e) != f.
//
// predf(f) returns float(f-e), where e is the smallest
// positive number such that float(f-e) != f.
//
// succd(d) returns double(d+e), where e is the smallest
// positive number such that double(d+e) != d.
//
// predd(d) returns double(d-e), where e is the smallest
// positive number such that double(d-e) != d.
//
// Exceptions: If the input value is an infinity or a nan,
// succf(), predf(), succd(), and predd() all
// return the input value without changing it.
//
//----------------------------------------------------------
IMATH_EXPORT float succf (float f);
IMATH_EXPORT float predf (float f);
IMATH_EXPORT double succd (double d);
IMATH_EXPORT double predd (double d);
//
// Return true if the number is not a NaN or Infinity.
//
inline bool
finitef (float f)
{
union {float f; int i;} u;
u.f = f;
return (u.i & 0x7f800000) != 0x7f800000;
}
inline bool
finited (double d)
{
union {double d; Int64 i;} u;
u.d = d;
return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFUN_H

View File

@@ -0,0 +1,166 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHGL_H
#define INCLUDED_IMATHGL_H
#include <GL/gl.h>
#include "ImathVec.h"
#include "ImathMatrix.h"
#include "IexMathExc.h"
#include "ImathFun.h"
#include "ImathNamespace.h"
inline void glVertex ( const IMATH_INTERNAL_NAMESPACE::V3f &v ) { glVertex3f(v.x,v.y,v.z); }
inline void glVertex ( const IMATH_INTERNAL_NAMESPACE::V2f &v ) { glVertex2f(v.x,v.y); }
inline void glNormal ( const IMATH_INTERNAL_NAMESPACE::V3f &n ) { glNormal3f(n.x,n.y,n.z); }
inline void glColor ( const IMATH_INTERNAL_NAMESPACE::V3f &c ) { glColor3f(c.x,c.y,c.z); }
inline void glTranslate ( const IMATH_INTERNAL_NAMESPACE::V3f &t ) { glTranslatef(t.x,t.y,t.z); }
inline void glTexCoord( const IMATH_INTERNAL_NAMESPACE::V2f &t )
{
glTexCoord2f(t.x,t.y);
}
inline void glDisableTexture()
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
}
namespace {
const float GL_FLOAT_MAX = 1.8e+19; // sqrt (FLT_MAX)
inline bool
badFloat (float f)
{
return !IMATH_INTERNAL_NAMESPACE::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX;
}
} // namespace
inline void
throwBadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m)
{
if (badFloat (m[0][0]) ||
badFloat (m[0][1]) ||
badFloat (m[0][2]) ||
badFloat (m[0][3]) ||
badFloat (m[1][0]) ||
badFloat (m[1][1]) ||
badFloat (m[1][2]) ||
badFloat (m[1][3]) ||
badFloat (m[2][0]) ||
badFloat (m[2][1]) ||
badFloat (m[2][2]) ||
badFloat (m[2][3]) ||
badFloat (m[3][0]) ||
badFloat (m[3][1]) ||
badFloat (m[3][2]) ||
badFloat (m[3][3]))
throw IEX_NAMESPACE::OverflowExc ("GL matrix overflow");
}
inline void
glMultMatrix( const IMATH_INTERNAL_NAMESPACE::M44f& m )
{
throwBadMatrix (m);
glMultMatrixf( (GLfloat*)m[0] );
}
inline void
glMultMatrix( const IMATH_INTERNAL_NAMESPACE::M44f* m )
{
throwBadMatrix (*m);
glMultMatrixf( (GLfloat*)(*m)[0] );
}
inline void
glLoadMatrix( const IMATH_INTERNAL_NAMESPACE::M44f& m )
{
throwBadMatrix (m);
glLoadMatrixf( (GLfloat*)m[0] );
}
inline void
glLoadMatrix( const IMATH_INTERNAL_NAMESPACE::M44f* m )
{
throwBadMatrix (*m);
glLoadMatrixf( (GLfloat*)(*m)[0] );
}
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Class objects that push/pop the GL state. These objects assist with
// proper cleanup of the state when exceptions are thrown.
//
class GLPushMatrix {
public:
GLPushMatrix () { glPushMatrix(); }
~GLPushMatrix() { glPopMatrix(); }
};
class GLPushAttrib {
public:
GLPushAttrib (GLbitfield mask) { glPushAttrib (mask); }
~GLPushAttrib() { glPopAttrib(); }
};
class GLBegin {
public:
GLBegin (GLenum mode) { glBegin (mode); }
~GLBegin() { glEnd(); }
};
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif

View File

@@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHGLU_H
#define INCLUDED_IMATHGLU_H
#include <GL/gl.h>
#include <GL/glu.h>
#include "ImathVec.h"
inline
void
gluLookAt(const IMATH_INTERNAL_NAMESPACE::V3f &pos, const IMATH_INTERNAL_NAMESPACE::V3f &interest, const IMATH_INTERNAL_NAMESPACE::V3f &up)
{
gluLookAt(pos.x, pos.y, pos.z,
interest.x, interest.y, interest.z,
up.x, up.y, up.z);
}
#endif

View File

@@ -0,0 +1,68 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHHALFLIMITS_H
#define INCLUDED_IMATHHALFLIMITS_H
//--------------------------------------------------
//
// Imath-style limits for class half.
//
//--------------------------------------------------
#include "ImathLimits.h"
#include "ImathNamespace.h"
#include "half.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <>
struct limits <half>
{
static float min() {return -HALF_MAX;}
static float max() {return HALF_MAX;}
static float smallest() {return HALF_MIN;}
static float epsilon() {return HALF_EPSILON;}
static bool isIntegral() {return false;}
static bool isSigned() {return true;}
};
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHHALFLIMITS_H

View File

@@ -0,0 +1,62 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2012, 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_IMATH_INT64_H
#define INCLUDED_IMATH_INT64_H
//----------------------------------------------------------------------------
//
// Int64 -- unsigned 64-bit integers
//
//----------------------------------------------------------------------------
#include "ImathNamespace.h"
#include <limits.h>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
#if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300
typedef unsigned __int64 Int64;
#elif ULONG_MAX == 18446744073709551615LU
typedef long unsigned int Int64;
#else
typedef long long unsigned int Int64;
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATH_INT64_H

View File

@@ -0,0 +1,226 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHINTERVAL_H
#define INCLUDED_IMATHINTERVAL_H
//-------------------------------------------------------------------
//
// class Imath::Interval<class T>
// --------------------------------
//
// An Interval has a min and a max and some miscellaneous
// functions. It is basically a Box<T> that allows T to be
// a scalar.
//
//-------------------------------------------------------------------
#include "ImathVec.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Interval
{
public:
//-------------------------
// Data Members are public
//-------------------------
T min;
T max;
//-----------------------------------------------------
// Constructors - an "empty" Interval is created by default
//-----------------------------------------------------
Interval();
Interval(const T& point);
Interval(const T& minT, const T& maxT);
//--------------------------------
// Operators: we get != from STL
//--------------------------------
bool operator == (const Interval<T> &src) const;
//------------------
// Interval manipulation
//------------------
void makeEmpty();
void extendBy(const T& point);
void extendBy(const Interval<T>& interval);
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
T size() const;
T center() const;
bool intersects(const T &point) const;
bool intersects(const Interval<T> &interval) const;
//----------------
// Classification
//----------------
bool hasVolume() const;
bool isEmpty() const;
};
//--------------------
// Convenient typedefs
//--------------------
typedef Interval <float> Intervalf;
typedef Interval <double> Intervald;
typedef Interval <short> Intervals;
typedef Interval <int> Intervali;
//----------------
// Implementation
//----------------
template <class T>
inline Interval<T>::Interval()
{
makeEmpty();
}
template <class T>
inline Interval<T>::Interval(const T& point)
{
min = point;
max = point;
}
template <class T>
inline Interval<T>::Interval(const T& minV, const T& maxV)
{
min = minV;
max = maxV;
}
template <class T>
inline bool
Interval<T>::operator == (const Interval<T> &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline void
Interval<T>::makeEmpty()
{
min = limits<T>::max();
max = limits<T>::min();
}
template <class T>
inline void
Interval<T>::extendBy(const T& point)
{
if ( point < min )
min = point;
if ( point > max )
max = point;
}
template <class T>
inline void
Interval<T>::extendBy(const Interval<T>& interval)
{
if ( interval.min < min )
min = interval.min;
if ( interval.max > max )
max = interval.max;
}
template <class T>
inline bool
Interval<T>::intersects(const T& point) const
{
return point >= min && point <= max;
}
template <class T>
inline bool
Interval<T>::intersects(const Interval<T>& interval) const
{
return interval.max >= min && interval.min <= max;
}
template <class T>
inline T
Interval<T>::size() const
{
return max-min;
}
template <class T>
inline T
Interval<T>::center() const
{
return (max+min)/2;
}
template <class T>
inline bool
Interval<T>::isEmpty() const
{
return max < min;
}
template <class T>
inline bool Interval<T>::hasVolume() const
{
return max > min;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHINTERVAL_H

View File

@@ -0,0 +1,268 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHLIMITS_H
#define INCLUDED_IMATHLIMITS_H
//----------------------------------------------------------------
//
// Limitations of the basic C++ numerical data types
//
//----------------------------------------------------------------
#include "ImathNamespace.h"
#include <float.h>
#include <limits.h>
//------------------------------------------
// In Windows, min and max are macros. Yay.
//------------------------------------------
#if defined _WIN32 || defined _WIN64
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//-----------------------------------------------------------------
//
// Template class limits<T> returns information about the limits
// of numerical data type T:
//
// min() largest possible negative value of type T
//
// max() largest possible positive value of type T
//
// smallest() smallest possible positive value of type T
// (for float and double: smallest normalized
// positive value)
//
// epsilon() smallest possible e of type T, for which
// 1 + e != 1
//
// isIntegral() returns true if T is an integral type
//
// isSigned() returns true if T is signed
//
// Class limits<T> is useful to implement template classes or
// functions which depend on the limits of a numerical type
// which is not known in advance; for example:
//
// template <class T> max (T x[], int n)
// {
// T m = limits<T>::min();
//
// for (int i = 0; i < n; i++)
// if (m < x[i])
// m = x[i];
//
// return m;
// }
//
// Class limits<T> has been implemented for the following types:
//
// char, signed char, unsigned char
// short, unsigned short
// int, unsigned int
// long, unsigned long
// float
// double
// long double
//
// Class limits<T> has only static member functions, all of which
// are implemented as inlines. No objects of type limits<T> are
// ever created.
//
//-----------------------------------------------------------------
template <class T> struct limits
{
static T min();
static T max();
static T smallest();
static T epsilon();
static bool isIntegral();
static bool isSigned();
};
//---------------
// Implementation
//---------------
template <>
struct limits <char>
{
static char min() {return CHAR_MIN;}
static char max() {return CHAR_MAX;}
static char smallest() {return 1;}
static char epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return (char) ~0 < 0;}
};
template <>
struct limits <signed char>
{
static signed char min() {return SCHAR_MIN;}
static signed char max() {return SCHAR_MAX;}
static signed char smallest() {return 1;}
static signed char epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return true;}
};
template <>
struct limits <unsigned char>
{
static unsigned char min() {return 0;}
static unsigned char max() {return UCHAR_MAX;}
static unsigned char smallest() {return 1;}
static unsigned char epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return false;}
};
template <>
struct limits <short>
{
static short min() {return SHRT_MIN;}
static short max() {return SHRT_MAX;}
static short smallest() {return 1;}
static short epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return true;}
};
template <>
struct limits <unsigned short>
{
static unsigned short min() {return 0;}
static unsigned short max() {return USHRT_MAX;}
static unsigned short smallest() {return 1;}
static unsigned short epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return false;}
};
template <>
struct limits <int>
{
static int min() {return INT_MIN;}
static int max() {return INT_MAX;}
static int smallest() {return 1;}
static int epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return true;}
};
template <>
struct limits <unsigned int>
{
static unsigned int min() {return 0;}
static unsigned int max() {return UINT_MAX;}
static unsigned int smallest() {return 1;}
static unsigned int epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return false;}
};
template <>
struct limits <long>
{
static long min() {return LONG_MIN;}
static long max() {return LONG_MAX;}
static long smallest() {return 1;}
static long epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return true;}
};
template <>
struct limits <unsigned long>
{
static unsigned long min() {return 0;}
static unsigned long max() {return ULONG_MAX;}
static unsigned long smallest() {return 1;}
static unsigned long epsilon() {return 1;}
static bool isIntegral() {return true;}
static bool isSigned() {return false;}
};
template <>
struct limits <float>
{
static float min() {return -FLT_MAX;}
static float max() {return FLT_MAX;}
static float smallest() {return FLT_MIN;}
static float epsilon() {return FLT_EPSILON;}
static bool isIntegral() {return false;}
static bool isSigned() {return true;}
};
template <>
struct limits <double>
{
static double min() {return -DBL_MAX;}
static double max() {return DBL_MAX;}
static double smallest() {return DBL_MIN;}
static double epsilon() {return DBL_EPSILON;}
static bool isIntegral() {return false;}
static bool isSigned() {return true;}
};
template <>
struct limits <long double>
{
static long double min() {return -LDBL_MAX;}
static long double max() {return LDBL_MAX;}
static long double smallest() {return LDBL_MIN;}
static long double epsilon() {return LDBL_EPSILON;}
static bool isIntegral() {return false;}
static bool isSigned() {return true;}
};
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHLIMITS_H

View File

@@ -0,0 +1,185 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHLINE_H
#define INCLUDED_IMATHLINE_H
//-------------------------------------
//
// A 3D line class template
//
//-------------------------------------
#include "ImathVec.h"
#include "ImathLimits.h"
#include "ImathMatrix.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Line3
{
public:
Vec3<T> pos;
Vec3<T> dir;
//-------------------------------------------------------------
// Constructors - default is normalized units along direction
//-------------------------------------------------------------
Line3() {}
Line3(const Vec3<T>& point1, const Vec3<T>& point2);
//------------------
// State Query/Set
//------------------
void set(const Vec3<T>& point1,
const Vec3<T>& point2);
//-------
// F(t)
//-------
Vec3<T> operator() (T parameter) const;
//---------
// Query
//---------
T distanceTo(const Vec3<T>& point) const;
T distanceTo(const Line3<T>& line) const;
Vec3<T> closestPointTo(const Vec3<T>& point) const;
Vec3<T> closestPointTo(const Line3<T>& line) const;
};
//--------------------
// Convenient typedefs
//--------------------
typedef Line3<float> Line3f;
typedef Line3<double> Line3d;
//---------------
// Implementation
//---------------
template <class T>
inline Line3<T>::Line3(const Vec3<T> &p0, const Vec3<T> &p1)
{
set(p0,p1);
}
template <class T>
inline void Line3<T>::set(const Vec3<T> &p0, const Vec3<T> &p1)
{
pos = p0; dir = p1-p0;
dir.normalize();
}
template <class T>
inline Vec3<T> Line3<T>::operator()(T parameter) const
{
return pos + dir * parameter;
}
template <class T>
inline T Line3<T>::distanceTo(const Vec3<T>& point) const
{
return (closestPointTo(point)-point).length();
}
template <class T>
inline Vec3<T> Line3<T>::closestPointTo(const Vec3<T>& point) const
{
return ((point - pos) ^ dir) * dir + pos;
}
template <class T>
inline T Line3<T>::distanceTo(const Line3<T>& line) const
{
T d = (dir % line.dir) ^ (line.pos - pos);
return (d >= 0)? d: -d;
}
template <class T>
inline Vec3<T>
Line3<T>::closestPointTo(const Line3<T>& line) const
{
// Assumes the lines are normalized
Vec3<T> posLpos = pos - line.pos ;
T c = dir ^ posLpos;
T a = line.dir ^ dir;
T f = line.dir ^ posLpos ;
T num = c - a * f;
T denom = a*a - 1;
T absDenom = ((denom >= 0)? denom: -denom);
if (absDenom < 1)
{
T absNum = ((num >= 0)? num: -num);
if (absNum >= absDenom * limits<T>::max())
return pos;
}
return pos + dir * (num / denom);
}
template<class T>
std::ostream& operator<< (std::ostream &o, const Line3<T> &line)
{
return o << "(" << line.pos << ", " << line.dir << ")";
}
template<class S, class T>
inline Line3<S> operator * (const Line3<S> &line, const Matrix44<T> &M)
{
return Line3<S>( line.pos * M, (line.pos + line.dir) * M );
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHLINE_H

View File

@@ -0,0 +1,288 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHLINEALGO_H
#define INCLUDED_IMATHLINEALGO_H
//------------------------------------------------------------------
//
// This file contains algorithms applied to or in conjunction
// with lines (Imath::Line). These algorithms may require
// more headers to compile. The assumption made is that these
// functions are called much less often than the basic line
// functions or these functions require more support classes
//
// Contains:
//
// bool closestPoints(const Line<T>& line1,
// const Line<T>& line2,
// Vec3<T>& point1,
// Vec3<T>& point2)
//
// bool intersect( const Line3<T> &line,
// const Vec3<T> &v0,
// const Vec3<T> &v1,
// const Vec3<T> &v2,
// Vec3<T> &pt,
// Vec3<T> &barycentric,
// bool &front)
//
// V3f
// closestVertex(const Vec3<T> &v0,
// const Vec3<T> &v1,
// const Vec3<T> &v2,
// const Line3<T> &l)
//
// V3f
// rotatePoint(const Vec3<T> p, Line3<T> l, float angle)
//
//------------------------------------------------------------------
#include "ImathLine.h"
#include "ImathVecAlgo.h"
#include "ImathFun.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
bool
closestPoints
(const Line3<T>& line1,
const Line3<T>& line2,
Vec3<T>& point1,
Vec3<T>& point2)
{
//
// Compute point1 and point2 such that point1 is on line1, point2
// is on line2 and the distance between point1 and point2 is minimal.
// This function returns true if point1 and point2 can be computed,
// or false if line1 and line2 are parallel or nearly parallel.
// This function assumes that line1.dir and line2.dir are normalized.
//
Vec3<T> w = line1.pos - line2.pos;
T d1w = line1.dir ^ w;
T d2w = line2.dir ^ w;
T d1d2 = line1.dir ^ line2.dir;
T n1 = d1d2 * d2w - d1w;
T n2 = d2w - d1d2 * d1w;
T d = 1 - d1d2 * d1d2;
T absD = abs (d);
if ((absD > 1) ||
(abs (n1) < limits<T>::max() * absD &&
abs (n2) < limits<T>::max() * absD))
{
point1 = line1 (n1 / d);
point2 = line2 (n2 / d);
return true;
}
else
{
return false;
}
}
template <class T>
bool
intersect
(const Line3<T> &line,
const Vec3<T> &v0,
const Vec3<T> &v1,
const Vec3<T> &v2,
Vec3<T> &pt,
Vec3<T> &barycentric,
bool &front)
{
//
// Given a line and a triangle (v0, v1, v2), the intersect() function
// finds the intersection of the line and the plane that contains the
// triangle.
//
// If the intersection point cannot be computed, either because the
// line and the triangle's plane are nearly parallel or because the
// triangle's area is very small, intersect() returns false.
//
// If the intersection point is outside the triangle, intersect
// returns false.
//
// If the intersection point, pt, is inside the triangle, intersect()
// computes a front-facing flag and the barycentric coordinates of
// the intersection point, and returns true.
//
// The front-facing flag is true if the dot product of the triangle's
// normal, (v2-v1)%(v1-v0), and the line's direction is negative.
//
// The barycentric coordinates have the following property:
//
// pt = v0 * barycentric.x + v1 * barycentric.y + v2 * barycentric.z
//
Vec3<T> edge0 = v1 - v0;
Vec3<T> edge1 = v2 - v1;
Vec3<T> normal = edge1 % edge0;
T l = normal.length();
if (l != 0)
normal /= l;
else
return false; // zero-area triangle
//
// d is the distance of line.pos from the plane that contains the triangle.
// The intersection point is at line.pos + (d/nd) * line.dir.
//
T d = normal ^ (v0 - line.pos);
T nd = normal ^ line.dir;
if (abs (nd) > 1 || abs (d) < limits<T>::max() * abs (nd))
pt = line (d / nd);
else
return false; // line and plane are nearly parallel
//
// Compute the barycentric coordinates of the intersection point.
// The intersection is inside the triangle if all three barycentric
// coordinates are between zero and one.
//
{
Vec3<T> en = edge0.normalized();
Vec3<T> a = pt - v0;
Vec3<T> b = v2 - v0;
Vec3<T> c = (a - en * (en ^ a));
Vec3<T> d = (b - en * (en ^ b));
T e = c ^ d;
T f = d ^ d;
if (e >= 0 && e <= f)
barycentric.z = e / f;
else
return false; // outside
}
{
Vec3<T> en = edge1.normalized();
Vec3<T> a = pt - v1;
Vec3<T> b = v0 - v1;
Vec3<T> c = (a - en * (en ^ a));
Vec3<T> d = (b - en * (en ^ b));
T e = c ^ d;
T f = d ^ d;
if (e >= 0 && e <= f)
barycentric.x = e / f;
else
return false; // outside
}
barycentric.y = 1 - barycentric.x - barycentric.z;
if (barycentric.y < 0)
return false; // outside
front = ((line.dir ^ normal) < 0);
return true;
}
template <class T>
Vec3<T>
closestVertex
(const Vec3<T> &v0,
const Vec3<T> &v1,
const Vec3<T> &v2,
const Line3<T> &l)
{
Vec3<T> nearest = v0;
T neardot = (v0 - l.closestPointTo(v0)).length2();
T tmp = (v1 - l.closestPointTo(v1)).length2();
if (tmp < neardot)
{
neardot = tmp;
nearest = v1;
}
tmp = (v2 - l.closestPointTo(v2)).length2();
if (tmp < neardot)
{
neardot = tmp;
nearest = v2;
}
return nearest;
}
template <class T>
Vec3<T>
rotatePoint (const Vec3<T> p, Line3<T> l, T angle)
{
//
// Rotate the point p around the line l by the given angle.
//
//
// Form a coordinate frame with <x,y,a>. The rotation is the in xy
// plane.
//
Vec3<T> q = l.closestPointTo(p);
Vec3<T> x = p - q;
T radius = x.length();
x.normalize();
Vec3<T> y = (x % l.dir).normalize();
T cosangle = Math<T>::cos(angle);
T sinangle = Math<T>::sin(angle);
Vec3<T> r = q + x * radius * cosangle + y * radius * sinangle;
return r;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHLINEALGO_H

View File

@@ -0,0 +1,208 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHMATH_H
#define INCLUDED_IMATHMATH_H
//----------------------------------------------------------------------------
//
// ImathMath.h
//
// This file contains template functions which call the double-
// precision math functions defined in math.h (sin(), sqrt(),
// exp() etc.), with specializations that call the faster
// single-precision versions (sinf(), sqrtf(), expf() etc.)
// when appropriate.
//
// Example:
//
// double x = Math<double>::sqrt (3); // calls ::sqrt(double);
// float y = Math<float>::sqrt (3); // calls ::sqrtf(float);
//
// When would I want to use this?
//
// You may be writing a template which needs to call some function
// defined in math.h, for example to extract a square root, but you
// don't know whether to call the single- or the double-precision
// version of this function (sqrt() or sqrtf()):
//
// template <class T>
// T
// glorp (T x)
// {
// return sqrt (x + 1); // should call ::sqrtf(float)
// } // if x is a float, but we
// // don't know if it is
//
// Using the templates in this file, you can make sure that
// the appropriate version of the math function is called:
//
// template <class T>
// T
// glorp (T x, T y)
// {
// return Math<T>::sqrt (x + 1); // calls ::sqrtf(float) if x
// } // is a float, ::sqrt(double)
// // otherwise
//
//----------------------------------------------------------------------------
#include "ImathPlatform.h"
#include "ImathLimits.h"
#include "ImathNamespace.h"
#include <math.h>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
struct Math
{
static T acos (T x) {return ::acos (double(x));}
static T asin (T x) {return ::asin (double(x));}
static T atan (T x) {return ::atan (double(x));}
static T atan2 (T x, T y) {return ::atan2 (double(x), double(y));}
static T cos (T x) {return ::cos (double(x));}
static T sin (T x) {return ::sin (double(x));}
static T tan (T x) {return ::tan (double(x));}
static T cosh (T x) {return ::cosh (double(x));}
static T sinh (T x) {return ::sinh (double(x));}
static T tanh (T x) {return ::tanh (double(x));}
static T exp (T x) {return ::exp (double(x));}
static T log (T x) {return ::log (double(x));}
static T log10 (T x) {return ::log10 (double(x));}
static T modf (T x, T *iptr)
{
double ival;
T rval( ::modf (double(x),&ival));
*iptr = ival;
return rval;
}
static T pow (T x, T y) {return ::pow (double(x), double(y));}
static T sqrt (T x) {return ::sqrt (double(x));}
static T ceil (T x) {return ::ceil (double(x));}
static T fabs (T x) {return ::fabs (double(x));}
static T floor (T x) {return ::floor (double(x));}
static T fmod (T x, T y) {return ::fmod (double(x), double(y));}
static T hypot (T x, T y) {return ::hypot (double(x), double(y));}
};
template <>
struct Math<float>
{
static float acos (float x) {return ::acosf (x);}
static float asin (float x) {return ::asinf (x);}
static float atan (float x) {return ::atanf (x);}
static float atan2 (float x, float y) {return ::atan2f (x, y);}
static float cos (float x) {return ::cosf (x);}
static float sin (float x) {return ::sinf (x);}
static float tan (float x) {return ::tanf (x);}
static float cosh (float x) {return ::coshf (x);}
static float sinh (float x) {return ::sinhf (x);}
static float tanh (float x) {return ::tanhf (x);}
static float exp (float x) {return ::expf (x);}
static float log (float x) {return ::logf (x);}
static float log10 (float x) {return ::log10f (x);}
static float modf (float x, float *y) {return ::modff (x, y);}
static float pow (float x, float y) {return ::powf (x, y);}
static float sqrt (float x) {return ::sqrtf (x);}
static float ceil (float x) {return ::ceilf (x);}
static float fabs (float x) {return ::fabsf (x);}
static float floor (float x) {return ::floorf (x);}
static float fmod (float x, float y) {return ::fmodf (x, y);}
#if !defined(_MSC_VER)
static float hypot (float x, float y) {return ::hypotf (x, y);}
#else
static float hypot (float x, float y) {return ::sqrtf(x*x + y*y);}
#endif
};
//--------------------------------------------------------------------------
// Don Hatch's version of sin(x)/x, which is accurate for very small x.
// Returns 1 for x == 0.
//--------------------------------------------------------------------------
template <class T>
inline T
sinx_over_x (T x)
{
if (x * x < limits<T>::epsilon())
return T (1);
else
return Math<T>::sin (x) / x;
}
//--------------------------------------------------------------------------
// Compare two numbers and test if they are "approximately equal":
//
// equalWithAbsError (x1, x2, e)
//
// Returns true if x1 is the same as x2 with an absolute error of
// no more than e,
//
// abs (x1 - x2) <= e
//
// equalWithRelError (x1, x2, e)
//
// Returns true if x1 is the same as x2 with an relative error of
// no more than e,
//
// abs (x1 - x2) <= e * x1
//
//--------------------------------------------------------------------------
template <class T>
inline bool
equalWithAbsError (T x1, T x2, T e)
{
return ((x1 > x2)? x1 - x2: x2 - x1) <= e;
}
template <class T>
inline bool
equalWithRelError (T x1, T x2, T e)
{
return ((x1 > x2)? x1 - x2: x2 - x1) <= e * ((x1 > 0)? x1: -x1);
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHMATH_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, 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_IMATHNAMESPACE_H
#define INCLUDED_IMATHNAMESPACE_H
//
// The purpose of this file is to make it possible to specify an
// IMATH_INTERNAL_NAMESPACE as a preprocessor definition and have all of the
// Imath symbols defined within that namespace rather than the standard
// Imath namespace. Those symbols are made available to client code through
// the IMATH_NAMESPACE in addition to the IMATH_INTERNAL_NAMESPACE.
//
// To ensure source code compatibility, the IMATH_NAMESPACE defaults to Imath
// and then "using namespace IMATH_INTERNAL_NAMESPACE;" brings all of the
// declarations from the IMATH_INTERNAL_NAMESPACE into the IMATH_NAMESPACE.
// This means that client code can continue to use syntax like Imath::V3f,
// but at link time it will resolve to a mangled symbol based on the
// IMATH_INTERNAL_NAMESPACE.
//
// As an example, if one needed to build against a newer version of Imath and
// have it run alongside an older version in the same application, it is now
// possible to use an internal namespace to prevent collisions between the
// older versions of Imath symbols and the newer ones. To do this, the
// following could be defined at build time:
//
// IMATH_INTERNAL_NAMESPACE = Imath_v2
//
// This means that declarations inside Imath headers look like this (after
// the preprocessor has done its work):
//
// namespace Imath_v2 {
// ...
// class declarations
// ...
// }
//
// namespace Imath {
// using namespace Imath_v2;
// }
//
//
// Open Source version of this file pulls in the IlmBaseConfig.h file
// for the configure time options.
//
#include "IlmBaseConfig.h"
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4515) // warning C4515: 'Imf': namespace uses itself
#endif
#ifndef IMATH_NAMESPACE
#define IMATH_NAMESPACE Imath
#endif
#ifndef IMATH_INTERNAL_NAMESPACE
#define IMATH_INTERNAL_NAMESPACE IMATH_NAMESPACE
#endif
//
// We need to be sure that we import the internal namespace into the public one.
// To do this, we use the small bit of code below which initially defines
// IMATH_INTERNAL_NAMESPACE (so it can be referenced) and then defines
// IMATH_NAMESPACE and pulls the internal symbols into the public
// namespace.
//
namespace IMATH_INTERNAL_NAMESPACE {}
namespace IMATH_NAMESPACE {
using namespace IMATH_INTERNAL_NAMESPACE;
}
//
// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
// future extension to the namespace mechanism is possible without changing
// project source code.
//
#define IMATH_INTERNAL_NAMESPACE_HEADER_ENTER namespace IMATH_INTERNAL_NAMESPACE {
#define IMATH_INTERNAL_NAMESPACE_HEADER_EXIT }
#define IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER namespace IMATH_INTERNAL_NAMESPACE {
#define IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT }
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif /* INCLUDED_IMATHNAMESPACE_H */

View File

@@ -0,0 +1,257 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
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 &parameter) 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);
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHPLANE_H

View File

@@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHPLATFORM_H
#define INCLUDED_IMATHPLATFORM_H
//----------------------------------------------------------------------------
//
// ImathPlatform.h
//
// This file contains functions and constants which aren't
// provided by the system libraries, compilers, or includes on
// certain platforms.
//
//----------------------------------------------------------------------------
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923 // pi/2
#endif
//-----------------------------------------------------------------------------
//
// Some, but not all, C++ compilers support the C99 restrict
// keyword or some variant of it, for example, __restrict.
//
//-----------------------------------------------------------------------------
#if defined __GNUC__
//
// supports __restrict
//
#define IMATH_RESTRICT __restrict
#elif defined (__INTEL_COMPILER) || \
defined(__ICL) || \
defined(__ICC) || \
defined(__ECC)
//
// supports restrict
//
#define IMATH_RESTRICT restrict
#elif defined __sgi
//
// supports restrict
//
#define IMATH_RESTRICT restrict
#elif defined _MSC_VER
//
// supports __restrict
//
// #define IMATH_RESTRICT __restrict
#define IMATH_RESTRICT
#else
//
// restrict / __restrict not supported
//
#define IMATH_RESTRICT
#endif
#endif // INCLUDED_IMATHPLATFORM_H

View File

@@ -0,0 +1,964 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHQUAT_H
#define INCLUDED_IMATHQUAT_H
//----------------------------------------------------------------------
//
// template class Quat<T>
//
// "Quaternions came from Hamilton ... and have been an unmixed
// evil to those who have touched them in any way. Vector is a
// useless survival ... and has never been of the slightest use
// to any creature."
//
// - Lord Kelvin
//
// This class implements the quaternion numerical type -- you
// will probably want to use this class to represent orientations
// in R3 and to convert between various euler angle reps. You
// should probably use Imath::Euler<> for that.
//
//----------------------------------------------------------------------
#include "ImathExc.h"
#include "ImathMatrix.h"
#include "ImathNamespace.h"
#include <iostream>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
// Disable MS VC++ warnings about conversion from double to float
#pragma warning(disable:4244)
#endif
template <class T>
class Quat
{
public:
T r; // real part
Vec3<T> v; // imaginary vector
//-----------------------------------------------------
// Constructors - default constructor is identity quat
//-----------------------------------------------------
Quat ();
template <class S>
Quat (const Quat<S> &q);
Quat (T s, T i, T j, T k);
Quat (T s, Vec3<T> d);
static Quat<T> identity ();
//-------------------------------------------------
// Basic Algebra - Operators and Methods
// The operator return values are *NOT* normalized
//
// operator^ and euclideanInnnerProduct() both
// implement the 4D dot product
//
// operator/ uses the inverse() quaternion
//
// operator~ is conjugate -- if (S+V) is quat then
// the conjugate (S+V)* == (S-V)
//
// some operators (*,/,*=,/=) treat the quat as
// a 4D vector when one of the operands is scalar
//-------------------------------------------------
const Quat<T> & operator = (const Quat<T> &q);
const Quat<T> & operator *= (const Quat<T> &q);
const Quat<T> & operator *= (T t);
const Quat<T> & operator /= (const Quat<T> &q);
const Quat<T> & operator /= (T t);
const Quat<T> & operator += (const Quat<T> &q);
const Quat<T> & operator -= (const Quat<T> &q);
T & operator [] (int index); // as 4D vector
T operator [] (int index) const;
template <class S> bool operator == (const Quat<S> &q) const;
template <class S> bool operator != (const Quat<S> &q) const;
Quat<T> & invert (); // this -> 1 / this
Quat<T> inverse () const;
Quat<T> & normalize (); // returns this
Quat<T> normalized () const;
T length () const; // in R4
Vec3<T> rotateVector(const Vec3<T> &original) const;
T euclideanInnerProduct(const Quat<T> &q) const;
//-----------------------
// Rotation conversion
//-----------------------
Quat<T> & setAxisAngle (const Vec3<T> &axis, T radians);
Quat<T> & setRotation (const Vec3<T> &fromDirection,
const Vec3<T> &toDirection);
T angle () const;
Vec3<T> axis () const;
Matrix33<T> toMatrix33 () const;
Matrix44<T> toMatrix44 () const;
Quat<T> log () const;
Quat<T> exp () const;
private:
void setRotationInternal (const Vec3<T> &f0,
const Vec3<T> &t0,
Quat<T> &q);
};
template<class T>
Quat<T> slerp (const Quat<T> &q1, const Quat<T> &q2, T t);
template<class T>
Quat<T> slerpShortestArc
(const Quat<T> &q1, const Quat<T> &q2, T t);
template<class T>
Quat<T> squad (const Quat<T> &q1, const Quat<T> &q2,
const Quat<T> &qa, const Quat<T> &qb, T t);
template<class T>
void intermediate (const Quat<T> &q0, const Quat<T> &q1,
const Quat<T> &q2, const Quat<T> &q3,
Quat<T> &qa, Quat<T> &qb);
template<class T>
Matrix33<T> operator * (const Matrix33<T> &M, const Quat<T> &q);
template<class T>
Matrix33<T> operator * (const Quat<T> &q, const Matrix33<T> &M);
template<class T>
std::ostream & operator << (std::ostream &o, const Quat<T> &q);
template<class T>
Quat<T> operator * (const Quat<T> &q1, const Quat<T> &q2);
template<class T>
Quat<T> operator / (const Quat<T> &q1, const Quat<T> &q2);
template<class T>
Quat<T> operator / (const Quat<T> &q, T t);
template<class T>
Quat<T> operator * (const Quat<T> &q, T t);
template<class T>
Quat<T> operator * (T t, const Quat<T> &q);
template<class T>
Quat<T> operator + (const Quat<T> &q1, const Quat<T> &q2);
template<class T>
Quat<T> operator - (const Quat<T> &q1, const Quat<T> &q2);
template<class T>
Quat<T> operator ~ (const Quat<T> &q);
template<class T>
Quat<T> operator - (const Quat<T> &q);
template<class T>
Vec3<T> operator * (const Vec3<T> &v, const Quat<T> &q);
//--------------------
// Convenient typedefs
//--------------------
typedef Quat<float> Quatf;
typedef Quat<double> Quatd;
//---------------
// Implementation
//---------------
template<class T>
inline
Quat<T>::Quat (): r (1), v (0, 0, 0)
{
// empty
}
template<class T>
template <class S>
inline
Quat<T>::Quat (const Quat<S> &q): r (q.r), v (q.v)
{
// empty
}
template<class T>
inline
Quat<T>::Quat (T s, T i, T j, T k): r (s), v (i, j, k)
{
// empty
}
template<class T>
inline
Quat<T>::Quat (T s, Vec3<T> d): r (s), v (d)
{
// empty
}
template<class T>
inline Quat<T>
Quat<T>::identity ()
{
return Quat<T>();
}
template<class T>
inline const Quat<T> &
Quat<T>::operator = (const Quat<T> &q)
{
r = q.r;
v = q.v;
return *this;
}
template<class T>
inline const Quat<T> &
Quat<T>::operator *= (const Quat<T> &q)
{
T rtmp = r * q.r - (v ^ q.v);
v = r * q.v + v * q.r + v % q.v;
r = rtmp;
return *this;
}
template<class T>
inline const Quat<T> &
Quat<T>::operator *= (T t)
{
r *= t;
v *= t;
return *this;
}
template<class T>
inline const Quat<T> &
Quat<T>::operator /= (const Quat<T> &q)
{
*this = *this * q.inverse();
return *this;
}
template<class T>
inline const Quat<T> &
Quat<T>::operator /= (T t)
{
r /= t;
v /= t;
return *this;
}
template<class T>
inline const Quat<T> &
Quat<T>::operator += (const Quat<T> &q)
{
r += q.r;
v += q.v;
return *this;
}
template<class T>
inline const Quat<T> &
Quat<T>::operator -= (const Quat<T> &q)
{
r -= q.r;
v -= q.v;
return *this;
}
template<class T>
inline T &
Quat<T>::operator [] (int index)
{
return index ? v[index - 1] : r;
}
template<class T>
inline T
Quat<T>::operator [] (int index) const
{
return index ? v[index - 1] : r;
}
template <class T>
template <class S>
inline bool
Quat<T>::operator == (const Quat<S> &q) const
{
return r == q.r && v == q.v;
}
template <class T>
template <class S>
inline bool
Quat<T>::operator != (const Quat<S> &q) const
{
return r != q.r || v != q.v;
}
template<class T>
inline T
operator ^ (const Quat<T>& q1 ,const Quat<T>& q2)
{
return q1.r * q2.r + (q1.v ^ q2.v);
}
template <class T>
inline T
Quat<T>::length () const
{
return Math<T>::sqrt (r * r + (v ^ v));
}
template <class T>
inline Quat<T> &
Quat<T>::normalize ()
{
if (T l = length())
{
r /= l;
v /= l;
}
else
{
r = 1;
v = Vec3<T> (0);
}
return *this;
}
template <class T>
inline Quat<T>
Quat<T>::normalized () const
{
if (T l = length())
return Quat (r / l, v / l);
return Quat();
}
template<class T>
inline Quat<T>
Quat<T>::inverse () const
{
//
// 1 Q*
// - = ---- where Q* is conjugate (operator~)
// Q Q* Q and (Q* Q) == Q ^ Q (4D dot)
//
T qdot = *this ^ *this;
return Quat (r / qdot, -v / qdot);
}
template<class T>
inline Quat<T> &
Quat<T>::invert ()
{
T qdot = (*this) ^ (*this);
r /= qdot;
v = -v / qdot;
return *this;
}
template<class T>
inline Vec3<T>
Quat<T>::rotateVector(const Vec3<T>& original) const
{
//
// Given a vector p and a quaternion q (aka this),
// calculate p' = qpq*
//
// Assumes unit quaternions (because non-unit
// quaternions cannot be used to rotate vectors
// anyway).
//
Quat<T> vec (0, original); // temporarily promote grade of original
Quat<T> inv (*this);
inv.v *= -1; // unit multiplicative inverse
Quat<T> result = *this * vec * inv;
return result.v;
}
template<class T>
inline T
Quat<T>::euclideanInnerProduct (const Quat<T> &q) const
{
return r * q.r + v.x * q.v.x + v.y * q.v.y + v.z * q.v.z;
}
template<class T>
T
angle4D (const Quat<T> &q1, const Quat<T> &q2)
{
//
// Compute the angle between two quaternions,
// interpreting the quaternions as 4D vectors.
//
Quat<T> d = q1 - q2;
T lengthD = Math<T>::sqrt (d ^ d);
Quat<T> s = q1 + q2;
T lengthS = Math<T>::sqrt (s ^ s);
return 2 * Math<T>::atan2 (lengthD, lengthS);
}
template<class T>
Quat<T>
slerp (const Quat<T> &q1, const Quat<T> &q2, T t)
{
//
// Spherical linear interpolation.
// Assumes q1 and q2 are normalized and that q1 != -q2.
//
// This method does *not* interpolate along the shortest
// arc between q1 and q2. If you desire interpolation
// along the shortest arc, and q1^q2 is negative, then
// consider calling slerpShortestArc(), below, or flipping
// the second quaternion explicitly.
//
// The implementation of squad() depends on a slerp()
// that interpolates as is, without the automatic
// flipping.
//
// Don Hatch explains the method we use here on his
// web page, The Right Way to Calculate Stuff, at
// http://www.plunk.org/~hatch/rightway.php
//
T a = angle4D (q1, q2);
T s = 1 - t;
Quat<T> q = sinx_over_x (s * a) / sinx_over_x (a) * s * q1 +
sinx_over_x (t * a) / sinx_over_x (a) * t * q2;
return q.normalized();
}
template<class T>
Quat<T>
slerpShortestArc (const Quat<T> &q1, const Quat<T> &q2, T t)
{
//
// Spherical linear interpolation along the shortest
// arc from q1 to either q2 or -q2, whichever is closer.
// Assumes q1 and q2 are unit quaternions.
//
if ((q1 ^ q2) >= 0)
return slerp (q1, q2, t);
else
return slerp (q1, -q2, t);
}
template<class T>
Quat<T>
spline (const Quat<T> &q0, const Quat<T> &q1,
const Quat<T> &q2, const Quat<T> &q3,
T t)
{
//
// Spherical Cubic Spline Interpolation -
// from Advanced Animation and Rendering
// Techniques by Watt and Watt, Page 366:
// A spherical curve is constructed using three
// spherical linear interpolations of a quadrangle
// of unit quaternions: q1, qa, qb, q2.
// Given a set of quaternion keys: q0, q1, q2, q3,
// this routine does the interpolation between
// q1 and q2 by constructing two intermediate
// quaternions: qa and qb. The qa and qb are
// computed by the intermediate function to
// guarantee the continuity of tangents across
// adjacent cubic segments. The qa represents in-tangent
// for q1 and the qb represents the out-tangent for q2.
//
// The q1 q2 is the cubic segment being interpolated.
// The q0 is from the previous adjacent segment and q3 is
// from the next adjacent segment. The q0 and q3 are used
// in computing qa and qb.
//
Quat<T> qa = intermediate (q0, q1, q2);
Quat<T> qb = intermediate (q1, q2, q3);
Quat<T> result = squad (q1, qa, qb, q2, t);
return result;
}
template<class T>
Quat<T>
squad (const Quat<T> &q1, const Quat<T> &qa,
const Quat<T> &qb, const Quat<T> &q2,
T t)
{
//
// Spherical Quadrangle Interpolation -
// from Advanced Animation and Rendering
// Techniques by Watt and Watt, Page 366:
// It constructs a spherical cubic interpolation as
// a series of three spherical linear interpolations
// of a quadrangle of unit quaternions.
//
Quat<T> r1 = slerp (q1, q2, t);
Quat<T> r2 = slerp (qa, qb, t);
Quat<T> result = slerp (r1, r2, 2 * t * (1 - t));
return result;
}
template<class T>
Quat<T>
intermediate (const Quat<T> &q0, const Quat<T> &q1, const Quat<T> &q2)
{
//
// From advanced Animation and Rendering
// Techniques by Watt and Watt, Page 366:
// computing the inner quadrangle
// points (qa and qb) to guarantee tangent
// continuity.
//
Quat<T> q1inv = q1.inverse();
Quat<T> c1 = q1inv * q2;
Quat<T> c2 = q1inv * q0;
Quat<T> c3 = (T) (-0.25) * (c2.log() + c1.log());
Quat<T> qa = q1 * c3.exp();
qa.normalize();
return qa;
}
template <class T>
inline Quat<T>
Quat<T>::log () const
{
//
// For unit quaternion, from Advanced Animation and
// Rendering Techniques by Watt and Watt, Page 366:
//
T theta = Math<T>::acos (std::min (r, (T) 1.0));
if (theta == 0)
return Quat<T> (0, v);
T sintheta = Math<T>::sin (theta);
T k;
if (abs (sintheta) < 1 && abs (theta) >= limits<T>::max() * abs (sintheta))
k = 1;
else
k = theta / sintheta;
return Quat<T> ((T) 0, v.x * k, v.y * k, v.z * k);
}
template <class T>
inline Quat<T>
Quat<T>::exp () const
{
//
// For pure quaternion (zero scalar part):
// from Advanced Animation and Rendering
// Techniques by Watt and Watt, Page 366:
//
T theta = v.length();
T sintheta = Math<T>::sin (theta);
T k;
if (abs (theta) < 1 && abs (sintheta) >= limits<T>::max() * abs (theta))
k = 1;
else
k = sintheta / theta;
T costheta = Math<T>::cos (theta);
return Quat<T> (costheta, v.x * k, v.y * k, v.z * k);
}
template <class T>
inline T
Quat<T>::angle () const
{
return 2 * Math<T>::atan2 (v.length(), r);
}
template <class T>
inline Vec3<T>
Quat<T>::axis () const
{
return v.normalized();
}
template <class T>
inline Quat<T> &
Quat<T>::setAxisAngle (const Vec3<T> &axis, T radians)
{
r = Math<T>::cos (radians / 2);
v = axis.normalized() * Math<T>::sin (radians / 2);
return *this;
}
template <class T>
Quat<T> &
Quat<T>::setRotation (const Vec3<T> &from, const Vec3<T> &to)
{
//
// Create a quaternion that rotates vector from into vector to,
// such that the rotation is around an axis that is the cross
// product of from and to.
//
// This function calls function setRotationInternal(), which is
// numerically accurate only for rotation angles that are not much
// greater than pi/2. In order to achieve good accuracy for angles
// greater than pi/2, we split large angles in half, and rotate in
// two steps.
//
//
// Normalize from and to, yielding f0 and t0.
//
Vec3<T> f0 = from.normalized();
Vec3<T> t0 = to.normalized();
if ((f0 ^ t0) >= 0)
{
//
// The rotation angle is less than or equal to pi/2.
//
setRotationInternal (f0, t0, *this);
}
else
{
//
// The angle is greater than pi/2. After computing h0,
// which is halfway between f0 and t0, we rotate first
// from f0 to h0, then from h0 to t0.
//
Vec3<T> h0 = (f0 + t0).normalized();
if ((h0 ^ h0) != 0)
{
setRotationInternal (f0, h0, *this);
Quat<T> q;
setRotationInternal (h0, t0, q);
*this *= q;
}
else
{
//
// f0 and t0 point in exactly opposite directions.
// Pick an arbitrary axis that is orthogonal to f0,
// and rotate by pi.
//
r = T (0);
Vec3<T> f02 = f0 * f0;
if (f02.x <= f02.y && f02.x <= f02.z)
v = (f0 % Vec3<T> (1, 0, 0)).normalized();
else if (f02.y <= f02.z)
v = (f0 % Vec3<T> (0, 1, 0)).normalized();
else
v = (f0 % Vec3<T> (0, 0, 1)).normalized();
}
}
return *this;
}
template <class T>
void
Quat<T>::setRotationInternal (const Vec3<T> &f0, const Vec3<T> &t0, Quat<T> &q)
{
//
// The following is equivalent to setAxisAngle(n,2*phi),
// where the rotation axis, n, is orthogonal to the f0 and
// t0 vectors, and 2*phi is the angle between f0 and t0.
//
// This function is called by setRotation(), above; it assumes
// that f0 and t0 are normalized and that the angle between
// them is not much greater than pi/2. This function becomes
// numerically inaccurate if f0 and t0 point into nearly
// opposite directions.
//
//
// Find a normalized vector, h0, that is halfway between f0 and t0.
// The angle between f0 and h0 is phi.
//
Vec3<T> h0 = (f0 + t0).normalized();
//
// Store the rotation axis and rotation angle.
//
q.r = f0 ^ h0; // f0 ^ h0 == cos (phi)
q.v = f0 % h0; // (f0 % h0).length() == sin (phi)
}
template<class T>
Matrix33<T>
Quat<T>::toMatrix33() const
{
return Matrix33<T> (1 - 2 * (v.y * v.y + v.z * v.z),
2 * (v.x * v.y + v.z * r),
2 * (v.z * v.x - v.y * r),
2 * (v.x * v.y - v.z * r),
1 - 2 * (v.z * v.z + v.x * v.x),
2 * (v.y * v.z + v.x * r),
2 * (v.z * v.x + v.y * r),
2 * (v.y * v.z - v.x * r),
1 - 2 * (v.y * v.y + v.x * v.x));
}
template<class T>
Matrix44<T>
Quat<T>::toMatrix44() const
{
return Matrix44<T> (1 - 2 * (v.y * v.y + v.z * v.z),
2 * (v.x * v.y + v.z * r),
2 * (v.z * v.x - v.y * r),
0,
2 * (v.x * v.y - v.z * r),
1 - 2 * (v.z * v.z + v.x * v.x),
2 * (v.y * v.z + v.x * r),
0,
2 * (v.z * v.x + v.y * r),
2 * (v.y * v.z - v.x * r),
1 - 2 * (v.y * v.y + v.x * v.x),
0,
0,
0,
0,
1);
}
template<class T>
inline Matrix33<T>
operator * (const Matrix33<T> &M, const Quat<T> &q)
{
return M * q.toMatrix33();
}
template<class T>
inline Matrix33<T>
operator * (const Quat<T> &q, const Matrix33<T> &M)
{
return q.toMatrix33() * M;
}
template<class T>
std::ostream &
operator << (std::ostream &o, const Quat<T> &q)
{
return o << "(" << q.r
<< " " << q.v.x
<< " " << q.v.y
<< " " << q.v.z
<< ")";
}
template<class T>
inline Quat<T>
operator * (const Quat<T> &q1, const Quat<T> &q2)
{
return Quat<T> (q1.r * q2.r - (q1.v ^ q2.v),
q1.r * q2.v + q1.v * q2.r + q1.v % q2.v);
}
template<class T>
inline Quat<T>
operator / (const Quat<T> &q1, const Quat<T> &q2)
{
return q1 * q2.inverse();
}
template<class T>
inline Quat<T>
operator / (const Quat<T> &q, T t)
{
return Quat<T> (q.r / t, q.v / t);
}
template<class T>
inline Quat<T>
operator * (const Quat<T> &q, T t)
{
return Quat<T> (q.r * t, q.v * t);
}
template<class T>
inline Quat<T>
operator * (T t, const Quat<T> &q)
{
return Quat<T> (q.r * t, q.v * t);
}
template<class T>
inline Quat<T>
operator + (const Quat<T> &q1, const Quat<T> &q2)
{
return Quat<T> (q1.r + q2.r, q1.v + q2.v);
}
template<class T>
inline Quat<T>
operator - (const Quat<T> &q1, const Quat<T> &q2)
{
return Quat<T> (q1.r - q2.r, q1.v - q2.v);
}
template<class T>
inline Quat<T>
operator ~ (const Quat<T> &q)
{
return Quat<T> (q.r, -q.v);
}
template<class T>
inline Quat<T>
operator - (const Quat<T> &q)
{
return Quat<T> (-q.r, -q.v);
}
template<class T>
inline Vec3<T>
operator * (const Vec3<T> &v, const Quat<T> &q)
{
Vec3<T> a = q.v % v;
Vec3<T> b = q.v % a;
return v + T (2) * (q.r * a + b);
}
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#pragma warning(default:4244)
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHQUAT_H

View File

@@ -0,0 +1,194 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Routines that generate pseudo-random numbers compatible
// with the standard erand48(), nrand48(), etc. functions.
//
//-----------------------------------------------------------------------------
#include "ImathRandom.h"
#include "ImathInt64.h"
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
namespace {
//
// Static state used by Imath::drand48(), Imath::lrand48() and Imath::srand48()
//
unsigned short staticState[3] = {0, 0, 0};
void
rand48Next (unsigned short state[3])
{
//
// drand48() and friends are all based on a linear congruential
// sequence,
//
// x[n+1] = (a * x[n] + c) % m,
//
// where a and c are as specified below, and m == (1 << 48)
//
static const Int64 a = Int64 (0x5deece66dLL);
static const Int64 c = Int64 (0xbLL);
//
// Assemble the 48-bit value x[n] from the
// three 16-bit values stored in state.
//
Int64 x = (Int64 (state[2]) << 32) |
(Int64 (state[1]) << 16) |
Int64 (state[0]);
//
// Compute x[n+1], except for the "modulo m" part.
//
x = a * x + c;
//
// Disassemble the 48 least significant bits of x[n+1] into
// three 16-bit values. Discard the 16 most significant bits;
// this takes care of the "modulo m" operation.
//
// We assume that sizeof (unsigned short) == 2.
//
state[2] = (unsigned short)(x >> 32);
state[1] = (unsigned short)(x >> 16);
state[0] = (unsigned short)(x);
}
} // namespace
double
erand48 (unsigned short state[3])
{
//
// Generate double-precision floating-point values between 0.0 and 1.0:
//
// The exponent is set to 0x3ff, which indicates a value greater
// than or equal to 1.0, and less than 2.0. The 48 most significant
// bits of the significand (mantissa) are filled with pseudo-random
// bits generated by rand48Next(). The remaining 4 bits are a copy
// of the 4 most significant bits of the significand. This results
// in bit patterns between 0x3ff0000000000000 and 0x3fffffffffffffff,
// which correspond to uniformly distributed floating-point values
// between 1.0 and 1.99999999999999978. Subtracting 1.0 from those
// values produces numbers between 0.0 and 0.99999999999999978, that
// is, between 0.0 and 1.0-DBL_EPSILON.
//
rand48Next (state);
union {double d; Int64 i;} u;
u.i = (Int64 (0x3ff) << 52) | // sign and exponent
(Int64 (state[2]) << 36) | // significand
(Int64 (state[1]) << 20) |
(Int64 (state[0]) << 4) |
(Int64 (state[2]) >> 12);
return u.d - 1;
}
double
drand48 ()
{
return IMATH_INTERNAL_NAMESPACE::erand48 (staticState);
}
long int
nrand48 (unsigned short state[3])
{
//
// Generate uniformly distributed integers between 0 and 0x7fffffff.
//
rand48Next (state);
return ((long int) (state[2]) << 15) |
((long int) (state[1]) >> 1);
}
long int
lrand48 ()
{
return IMATH_INTERNAL_NAMESPACE::nrand48 (staticState);
}
void
srand48 (long int seed)
{
staticState[2] = (unsigned short)(seed >> 16);
staticState[1] = (unsigned short)(seed);
staticState[0] = 0x330e;
}
float
Rand32::nextf ()
{
//
// Generate single-precision floating-point values between 0.0 and 1.0:
//
// The exponent is set to 0x7f, which indicates a value greater than
// or equal to 1.0, and less than 2.0. The 23 bits of the significand
// (mantissa) are filled with pseudo-random bits generated by
// Rand32::next(). This results in in bit patterns between 0x3f800000
// and 0x3fffffff, which correspond to uniformly distributed floating-
// point values between 1.0 and 1.99999988. Subtracting 1.0 from
// those values produces numbers between 0.0 and 0.99999988, that is,
// between 0.0 and 1.0-FLT_EPSILON.
//
next ();
union {float f; unsigned int i;} u;
u.i = 0x3f800000 | (_state & 0x7fffff);
return u.f - 1;
}
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

View File

@@ -0,0 +1,401 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHRANDOM_H
#define INCLUDED_IMATHRANDOM_H
//-----------------------------------------------------------------------------
//
// Generators for uniformly distributed pseudo-random numbers and
// functions that use those generators to generate numbers with
// non-uniform distributions:
//
// class Rand32
// class Rand48
// solidSphereRand()
// hollowSphereRand()
// gaussRand()
// gaussSphereRand()
//
// Note: class Rand48() calls erand48() and nrand48(), which are not
// available on all operating systems. For compatibility we include
// our own versions of erand48() and nrand48(). Our functions have
// been reverse-engineered from the corresponding Unix/Linux man page.
//
//-----------------------------------------------------------------------------
#include "ImathNamespace.h"
#include "ImathExport.h"
#include <stdlib.h>
#include <math.h>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//-----------------------------------------------
// Fast random-number generator that generates
// a uniformly distributed sequence with a period
// length of 2^32.
//-----------------------------------------------
class IMATH_EXPORT Rand32
{
public:
//------------
// Constructor
//------------
Rand32 (unsigned long int seed = 0);
//--------------------------------
// Re-initialize with a given seed
//--------------------------------
void init (unsigned long int seed);
//----------------------------------------------------------
// Get the next value in the sequence (range: [false, true])
//----------------------------------------------------------
bool nextb ();
//---------------------------------------------------------------
// Get the next value in the sequence (range: [0 ... 0xffffffff])
//---------------------------------------------------------------
unsigned long int nexti ();
//------------------------------------------------------
// Get the next value in the sequence (range: [0 ... 1[)
//------------------------------------------------------
float nextf ();
//-------------------------------------------------------------------
// Get the next value in the sequence (range [rangeMin ... rangeMax[)
//-------------------------------------------------------------------
float nextf (float rangeMin, float rangeMax);
private:
void next ();
unsigned long int _state;
};
//--------------------------------------------------------
// Random-number generator based on the C Standard Library
// functions erand48(), nrand48() & company; generates a
// uniformly distributed sequence.
//--------------------------------------------------------
class Rand48
{
public:
//------------
// Constructor
//------------
Rand48 (unsigned long int seed = 0);
//--------------------------------
// Re-initialize with a given seed
//--------------------------------
void init (unsigned long int seed);
//----------------------------------------------------------
// Get the next value in the sequence (range: [false, true])
//----------------------------------------------------------
bool nextb ();
//---------------------------------------------------------------
// Get the next value in the sequence (range: [0 ... 0x7fffffff])
//---------------------------------------------------------------
long int nexti ();
//------------------------------------------------------
// Get the next value in the sequence (range: [0 ... 1[)
//------------------------------------------------------
double nextf ();
//-------------------------------------------------------------------
// Get the next value in the sequence (range [rangeMin ... rangeMax[)
//-------------------------------------------------------------------
double nextf (double rangeMin, double rangeMax);
private:
unsigned short int _state[3];
};
//------------------------------------------------------------
// Return random points uniformly distributed in a sphere with
// radius 1 around the origin (distance from origin <= 1).
//------------------------------------------------------------
template <class Vec, class Rand>
Vec
solidSphereRand (Rand &rand);
//-------------------------------------------------------------
// Return random points uniformly distributed on the surface of
// a sphere with radius 1 around the origin.
//-------------------------------------------------------------
template <class Vec, class Rand>
Vec
hollowSphereRand (Rand &rand);
//-----------------------------------------------
// Return random numbers with a normal (Gaussian)
// distribution with zero mean and unit variance.
//-----------------------------------------------
template <class Rand>
float
gaussRand (Rand &rand);
//----------------------------------------------------
// Return random points whose distance from the origin
// has a normal (Gaussian) distribution with zero mean
// and unit variance.
//----------------------------------------------------
template <class Vec, class Rand>
Vec
gaussSphereRand (Rand &rand);
//---------------------------------
// erand48(), nrand48() and friends
//---------------------------------
IMATH_EXPORT double erand48 (unsigned short state[3]);
IMATH_EXPORT double drand48 ();
IMATH_EXPORT long int nrand48 (unsigned short state[3]);
IMATH_EXPORT long int lrand48 ();
IMATH_EXPORT void srand48 (long int seed);
//---------------
// Implementation
//---------------
inline void
Rand32::init (unsigned long int seed)
{
_state = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
}
inline
Rand32::Rand32 (unsigned long int seed)
{
init (seed);
}
inline void
Rand32::next ()
{
_state = 1664525L * _state + 1013904223L;
}
inline bool
Rand32::nextb ()
{
next ();
// Return the 31st (most significant) bit, by and-ing with 2 ^ 31.
return !!(_state & 2147483648UL);
}
inline unsigned long int
Rand32::nexti ()
{
next ();
return _state & 0xffffffff;
}
inline float
Rand32::nextf (float rangeMin, float rangeMax)
{
float f = nextf();
return rangeMin * (1 - f) + rangeMax * f;
}
inline void
Rand48::init (unsigned long int seed)
{
seed = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
_state[0] = (unsigned short int) (seed & 0xFFFF);
_state[1] = (unsigned short int) ((seed >> 16) & 0xFFFF);
_state[2] = (unsigned short int) (seed & 0xFFFF);
}
inline
Rand48::Rand48 (unsigned long int seed)
{
init (seed);
}
inline bool
Rand48::nextb ()
{
return nrand48 (_state) & 1;
}
inline long int
Rand48::nexti ()
{
return nrand48 (_state);
}
inline double
Rand48::nextf ()
{
return erand48 (_state);
}
inline double
Rand48::nextf (double rangeMin, double rangeMax)
{
double f = nextf();
return rangeMin * (1 - f) + rangeMax * f;
}
template <class Vec, class Rand>
Vec
solidSphereRand (Rand &rand)
{
Vec v;
do
{
for (unsigned int i = 0; i < Vec::dimensions(); i++)
v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
}
while (v.length2() > 1);
return v;
}
template <class Vec, class Rand>
Vec
hollowSphereRand (Rand &rand)
{
Vec v;
typename Vec::BaseType length;
do
{
for (unsigned int i = 0; i < Vec::dimensions(); i++)
v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
length = v.length();
}
while (length > 1 || length == 0);
return v / length;
}
template <class Rand>
float
gaussRand (Rand &rand)
{
float x; // Note: to avoid numerical problems with very small
float y; // numbers, we make these variables singe-precision
float length2; // floats, but later we call the double-precision log()
// and sqrt() functions instead of logf() and sqrtf().
do
{
x = float (rand.nextf (-1, 1));
y = float (rand.nextf (-1, 1));
length2 = x * x + y * y;
}
while (length2 >= 1 || length2 == 0);
return x * sqrt (-2 * log (double (length2)) / length2);
}
template <class Vec, class Rand>
Vec
gaussSphereRand (Rand &rand)
{
return hollowSphereRand <Vec> (rand) * gaussRand (rand);
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHRANDOM_H

View File

@@ -0,0 +1,219 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHROOTS_H
#define INCLUDED_IMATHROOTS_H
//---------------------------------------------------------------------
//
// Functions to solve linear, quadratic or cubic equations
//
//---------------------------------------------------------------------
#include "ImathMath.h"
#include "ImathNamespace.h"
#include <complex>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//--------------------------------------------------------------------------
// Find the real solutions of a linear, quadratic or cubic equation:
//
// function equation solved
//
// solveLinear (a, b, x) a * x + b == 0
// solveQuadratic (a, b, c, x) a * x*x + b * x + c == 0
// solveNormalizedCubic (r, s, t, x) x*x*x + r * x*x + s * x + t == 0
// solveCubic (a, b, c, d, x) a * x*x*x + b * x*x + c * x + d == 0
//
// Return value:
//
// 3 three real solutions, stored in x[0], x[1] and x[2]
// 2 two real solutions, stored in x[0] and x[1]
// 1 one real solution, stored in x[1]
// 0 no real solutions
// -1 all real numbers are solutions
//
// Notes:
//
// * It is possible that an equation has real solutions, but that the
// solutions (or some intermediate result) are not representable.
// In this case, either some of the solutions returned are invalid
// (nan or infinity), or, if floating-point exceptions have been
// enabled with Iex::mathExcOn(), an Iex::MathExc exception is
// thrown.
//
// * Cubic equations are solved using Cardano's Formula; even though
// only real solutions are produced, some intermediate results are
// complex (std::complex<T>).
//
//--------------------------------------------------------------------------
template <class T> int solveLinear (T a, T b, T &x);
template <class T> int solveQuadratic (T a, T b, T c, T x[2]);
template <class T> int solveNormalizedCubic (T r, T s, T t, T x[3]);
template <class T> int solveCubic (T a, T b, T c, T d, T x[3]);
//---------------
// Implementation
//---------------
template <class T>
int
solveLinear (T a, T b, T &x)
{
if (a != 0)
{
x = -b / a;
return 1;
}
else if (b != 0)
{
return 0;
}
else
{
return -1;
}
}
template <class T>
int
solveQuadratic (T a, T b, T c, T x[2])
{
if (a == 0)
{
return solveLinear (b, c, x[0]);
}
else
{
T D = b * b - 4 * a * c;
if (D > 0)
{
T s = Math<T>::sqrt (D);
T q = -(b + (b > 0 ? 1 : -1) * s) / T(2);
x[0] = q / a;
x[1] = c / q;
return 2;
}
if (D == 0)
{
x[0] = -b / (2 * a);
return 1;
}
else
{
return 0;
}
}
}
template <class T>
int
solveNormalizedCubic (T r, T s, T t, T x[3])
{
T p = (3 * s - r * r) / 3;
T q = 2 * r * r * r / 27 - r * s / 3 + t;
T p3 = p / 3;
T q2 = q / 2;
T D = p3 * p3 * p3 + q2 * q2;
if (D == 0 && p3 == 0)
{
x[0] = -r / 3;
x[1] = -r / 3;
x[2] = -r / 3;
return 1;
}
std::complex<T> u = std::pow (-q / 2 + std::sqrt (std::complex<T> (D)),
T (1) / T (3));
std::complex<T> v = -p / (T (3) * u);
const T sqrt3 = T (1.73205080756887729352744634150587); // enough digits
// for long double
std::complex<T> y0 (u + v);
std::complex<T> y1 (-(u + v) / T (2) +
(u - v) / T (2) * std::complex<T> (0, sqrt3));
std::complex<T> y2 (-(u + v) / T (2) -
(u - v) / T (2) * std::complex<T> (0, sqrt3));
if (D > 0)
{
x[0] = y0.real() - r / 3;
return 1;
}
else if (D == 0)
{
x[0] = y0.real() - r / 3;
x[1] = y1.real() - r / 3;
return 2;
}
else
{
x[0] = y0.real() - r / 3;
x[1] = y1.real() - r / 3;
x[2] = y2.real() - r / 3;
return 3;
}
}
template <class T>
int
solveCubic (T a, T b, T c, T d, T x[3])
{
if (a == 0)
{
return solveQuadratic (b, c, d, x);
}
else
{
return solveNormalizedCubic (b / a, c / a, d / a, x);
}
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHROOTS_H

View File

@@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Specializations of the Shear6<T> template.
//
//----------------------------------------------------------------------------
#include "ImathShear.h"
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
// empty
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

View File

@@ -0,0 +1,656 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2012, 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_IMATHSHEAR_H
#define INCLUDED_IMATHSHEAR_H
//----------------------------------------------------
//
// Shear6 class template.
//
//----------------------------------------------------
#include "ImathExc.h"
#include "ImathLimits.h"
#include "ImathMath.h"
#include "ImathVec.h"
#include "ImathNamespace.h"
#include <iostream>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T> class Shear6
{
public:
//-------------------
// Access to elements
//-------------------
T xy, xz, yz, yx, zx, zy;
T & operator [] (int i);
const T & operator [] (int i) const;
//-------------
// Constructors
//-------------
Shear6 (); // (0 0 0 0 0 0)
Shear6 (T XY, T XZ, T YZ); // (XY XZ YZ 0 0 0)
Shear6 (const Vec3<T> &v); // (v.x v.y v.z 0 0 0)
template <class S> // (v.x v.y v.z 0 0 0)
Shear6 (const Vec3<S> &v);
Shear6 (T XY, T XZ, T YZ, // (XY XZ YZ YX ZX ZY)
T YX, T ZX, T ZY);
//---------------------------------
// Copy constructors and assignment
//---------------------------------
Shear6 (const Shear6 &h);
template <class S> Shear6 (const Shear6<S> &h);
const Shear6 & operator = (const Shear6 &h);
template <class S>
const Shear6 & operator = (const Vec3<S> &v);
//----------------------
// Compatibility with Sb
//----------------------
template <class S>
void setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY);
template <class S>
void setValue (const Shear6<S> &h);
template <class S>
void getValue (S &XY, S &XZ, S &YZ,
S &YX, S &ZX, S &ZY) const;
template <class S>
void getValue (Shear6<S> &h) const;
T * getValue();
const T * getValue() const;
//---------
// Equality
//---------
template <class S>
bool operator == (const Shear6<S> &h) const;
template <class S>
bool operator != (const Shear6<S> &h) const;
//-----------------------------------------------------------------------
// Compare two shears and test if they are "approximately equal":
//
// equalWithAbsError (h, e)
//
// Returns true if the coefficients of this and h are the same with
// an absolute error of no more than e, i.e., for all i
//
// abs (this[i] - h[i]) <= e
//
// equalWithRelError (h, e)
//
// Returns true if the coefficients of this and h are the same with
// a relative error of no more than e, i.e., for all i
//
// abs (this[i] - h[i]) <= e * abs (this[i])
//-----------------------------------------------------------------------
bool equalWithAbsError (const Shear6<T> &h, T e) const;
bool equalWithRelError (const Shear6<T> &h, T e) const;
//------------------------
// Component-wise addition
//------------------------
const Shear6 & operator += (const Shear6 &h);
Shear6 operator + (const Shear6 &h) const;
//---------------------------
// Component-wise subtraction
//---------------------------
const Shear6 & operator -= (const Shear6 &h);
Shear6 operator - (const Shear6 &h) const;
//------------------------------------
// Component-wise multiplication by -1
//------------------------------------
Shear6 operator - () const;
const Shear6 & negate ();
//------------------------------
// Component-wise multiplication
//------------------------------
const Shear6 & operator *= (const Shear6 &h);
const Shear6 & operator *= (T a);
Shear6 operator * (const Shear6 &h) const;
Shear6 operator * (T a) const;
//------------------------
// Component-wise division
//------------------------
const Shear6 & operator /= (const Shear6 &h);
const Shear6 & operator /= (T a);
Shear6 operator / (const Shear6 &h) const;
Shear6 operator / (T a) const;
//----------------------------------------------------------
// Number of dimensions, i.e. number of elements in a Shear6
//----------------------------------------------------------
static unsigned int dimensions() {return 6;}
//-------------------------------------------------
// Limitations of type T (see also class limits<T>)
//-------------------------------------------------
static T baseTypeMin() {return limits<T>::min();}
static T baseTypeMax() {return limits<T>::max();}
static T baseTypeSmallest() {return limits<T>::smallest();}
static T baseTypeEpsilon() {return limits<T>::epsilon();}
//--------------------------------------------------------------
// Base type -- in templates, which accept a parameter, V, which
// could be either a Vec2<T> or a Shear6<T>, you can refer to T as
// V::BaseType
//--------------------------------------------------------------
typedef T BaseType;
};
//--------------
// Stream output
//--------------
template <class T>
std::ostream & operator << (std::ostream &s, const Shear6<T> &h);
//----------------------------------------------------
// Reverse multiplication: scalar * Shear6<T>
//----------------------------------------------------
template <class S, class T> Shear6<T> operator * (S a, const Shear6<T> &h);
//-------------------------
// Typedefs for convenience
//-------------------------
typedef Vec3 <float> Shear3f;
typedef Vec3 <double> Shear3d;
typedef Shear6 <float> Shear6f;
typedef Shear6 <double> Shear6d;
//-----------------------
// Implementation of Shear6
//-----------------------
template <class T>
inline T &
Shear6<T>::operator [] (int i)
{
return (&xy)[i];
}
template <class T>
inline const T &
Shear6<T>::operator [] (int i) const
{
return (&xy)[i];
}
template <class T>
inline
Shear6<T>::Shear6 ()
{
xy = xz = yz = yx = zx = zy = 0;
}
template <class T>
inline
Shear6<T>::Shear6 (T XY, T XZ, T YZ)
{
xy = XY;
xz = XZ;
yz = YZ;
yx = 0;
zx = 0;
zy = 0;
}
template <class T>
inline
Shear6<T>::Shear6 (const Vec3<T> &v)
{
xy = v.x;
xz = v.y;
yz = v.z;
yx = 0;
zx = 0;
zy = 0;
}
template <class T>
template <class S>
inline
Shear6<T>::Shear6 (const Vec3<S> &v)
{
xy = T (v.x);
xz = T (v.y);
yz = T (v.z);
yx = 0;
zx = 0;
zy = 0;
}
template <class T>
inline
Shear6<T>::Shear6 (T XY, T XZ, T YZ, T YX, T ZX, T ZY)
{
xy = XY;
xz = XZ;
yz = YZ;
yx = YX;
zx = ZX;
zy = ZY;
}
template <class T>
inline
Shear6<T>::Shear6 (const Shear6 &h)
{
xy = h.xy;
xz = h.xz;
yz = h.yz;
yx = h.yx;
zx = h.zx;
zy = h.zy;
}
template <class T>
template <class S>
inline
Shear6<T>::Shear6 (const Shear6<S> &h)
{
xy = T (h.xy);
xz = T (h.xz);
yz = T (h.yz);
yx = T (h.yx);
zx = T (h.zx);
zy = T (h.zy);
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator = (const Shear6 &h)
{
xy = h.xy;
xz = h.xz;
yz = h.yz;
yx = h.yx;
zx = h.zx;
zy = h.zy;
return *this;
}
template <class T>
template <class S>
inline const Shear6<T> &
Shear6<T>::operator = (const Vec3<S> &v)
{
xy = T (v.x);
xz = T (v.y);
yz = T (v.z);
yx = 0;
zx = 0;
zy = 0;
return *this;
}
template <class T>
template <class S>
inline void
Shear6<T>::setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY)
{
xy = T (XY);
xz = T (XZ);
yz = T (YZ);
yx = T (YX);
zx = T (ZX);
zy = T (ZY);
}
template <class T>
template <class S>
inline void
Shear6<T>::setValue (const Shear6<S> &h)
{
xy = T (h.xy);
xz = T (h.xz);
yz = T (h.yz);
yx = T (h.yx);
zx = T (h.zx);
zy = T (h.zy);
}
template <class T>
template <class S>
inline void
Shear6<T>::getValue (S &XY, S &XZ, S &YZ, S &YX, S &ZX, S &ZY) const
{
XY = S (xy);
XZ = S (xz);
YZ = S (yz);
YX = S (yx);
ZX = S (zx);
ZY = S (zy);
}
template <class T>
template <class S>
inline void
Shear6<T>::getValue (Shear6<S> &h) const
{
h.xy = S (xy);
h.xz = S (xz);
h.yz = S (yz);
h.yx = S (yx);
h.zx = S (zx);
h.zy = S (zy);
}
template <class T>
inline T *
Shear6<T>::getValue()
{
return (T *) &xy;
}
template <class T>
inline const T *
Shear6<T>::getValue() const
{
return (const T *) &xy;
}
template <class T>
template <class S>
inline bool
Shear6<T>::operator == (const Shear6<S> &h) const
{
return xy == h.xy && xz == h.xz && yz == h.yz &&
yx == h.yx && zx == h.zx && zy == h.zy;
}
template <class T>
template <class S>
inline bool
Shear6<T>::operator != (const Shear6<S> &h) const
{
return xy != h.xy || xz != h.xz || yz != h.yz ||
yx != h.yx || zx != h.zx || zy != h.zy;
}
template <class T>
bool
Shear6<T>::equalWithAbsError (const Shear6<T> &h, T e) const
{
for (int i = 0; i < 6; i++)
if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], h[i], e))
return false;
return true;
}
template <class T>
bool
Shear6<T>::equalWithRelError (const Shear6<T> &h, T e) const
{
for (int i = 0; i < 6; i++)
if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], h[i], e))
return false;
return true;
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator += (const Shear6 &h)
{
xy += h.xy;
xz += h.xz;
yz += h.yz;
yx += h.yx;
zx += h.zx;
zy += h.zy;
return *this;
}
template <class T>
inline Shear6<T>
Shear6<T>::operator + (const Shear6 &h) const
{
return Shear6 (xy + h.xy, xz + h.xz, yz + h.yz,
yx + h.yx, zx + h.zx, zy + h.zy);
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator -= (const Shear6 &h)
{
xy -= h.xy;
xz -= h.xz;
yz -= h.yz;
yx -= h.yx;
zx -= h.zx;
zy -= h.zy;
return *this;
}
template <class T>
inline Shear6<T>
Shear6<T>::operator - (const Shear6 &h) const
{
return Shear6 (xy - h.xy, xz - h.xz, yz - h.yz,
yx - h.yx, zx - h.zx, zy - h.zy);
}
template <class T>
inline Shear6<T>
Shear6<T>::operator - () const
{
return Shear6 (-xy, -xz, -yz, -yx, -zx, -zy);
}
template <class T>
inline const Shear6<T> &
Shear6<T>::negate ()
{
xy = -xy;
xz = -xz;
yz = -yz;
yx = -yx;
zx = -zx;
zy = -zy;
return *this;
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator *= (const Shear6 &h)
{
xy *= h.xy;
xz *= h.xz;
yz *= h.yz;
yx *= h.yx;
zx *= h.zx;
zy *= h.zy;
return *this;
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator *= (T a)
{
xy *= a;
xz *= a;
yz *= a;
yx *= a;
zx *= a;
zy *= a;
return *this;
}
template <class T>
inline Shear6<T>
Shear6<T>::operator * (const Shear6 &h) const
{
return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz,
yx * h.yx, zx * h.zx, zy * h.zy);
}
template <class T>
inline Shear6<T>
Shear6<T>::operator * (T a) const
{
return Shear6 (xy * a, xz * a, yz * a,
yx * a, zx * a, zy * a);
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator /= (const Shear6 &h)
{
xy /= h.xy;
xz /= h.xz;
yz /= h.yz;
yx /= h.yx;
zx /= h.zx;
zy /= h.zy;
return *this;
}
template <class T>
inline const Shear6<T> &
Shear6<T>::operator /= (T a)
{
xy /= a;
xz /= a;
yz /= a;
yx /= a;
zx /= a;
zy /= a;
return *this;
}
template <class T>
inline Shear6<T>
Shear6<T>::operator / (const Shear6 &h) const
{
return Shear6 (xy / h.xy, xz / h.xz, yz / h.yz,
yx / h.yx, zx / h.zx, zy / h.zy);
}
template <class T>
inline Shear6<T>
Shear6<T>::operator / (T a) const
{
return Shear6 (xy / a, xz / a, yz / a,
yx / a, zx / a, zy / a);
}
//-----------------------------
// Stream output implementation
//-----------------------------
template <class T>
std::ostream &
operator << (std::ostream &s, const Shear6<T> &h)
{
return s << '('
<< h.xy << ' ' << h.xz << ' ' << h.yz
<< h.yx << ' ' << h.zx << ' ' << h.zy
<< ')';
}
//-----------------------------------------
// Implementation of reverse multiplication
//-----------------------------------------
template <class S, class T>
inline Shear6<T>
operator * (S a, const Shear6<T> &h)
{
return Shear6<T> (a * h.xy, a * h.xz, a * h.yz,
a * h.yx, a * h.zx, a * h.zy);
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHSHEAR_H

View File

@@ -0,0 +1,177 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHSPHERE_H
#define INCLUDED_IMATHSPHERE_H
//-------------------------------------
//
// A 3D sphere class template
//
//-------------------------------------
#include "ImathVec.h"
#include "ImathBox.h"
#include "ImathLine.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Sphere3
{
public:
Vec3<T> center;
T radius;
//---------------
// Constructors
//---------------
Sphere3() : center(0,0,0), radius(0) {}
Sphere3(const Vec3<T> &c, T r) : center(c), radius(r) {}
//-------------------------------------------------------------------
// Utilities:
//
// s.circumscribe(b) sets center and radius of sphere s
// so that the s tightly encloses box b.
//
// s.intersectT (l, t) If sphere s and line l intersect, then
// intersectT() computes the smallest t,
// t >= 0, so that l(t) is a point on the
// sphere. intersectT() then returns true.
//
// If s and l do not intersect, intersectT()
// returns false.
//
// s.intersect (l, i) If sphere s and line l intersect, then
// intersect() calls s.intersectT(l,t) and
// computes i = l(t).
//
// If s and l do not intersect, intersect()
// returns false.
//
//-------------------------------------------------------------------
void circumscribe(const Box<Vec3<T> > &box);
bool intersect(const Line3<T> &l, Vec3<T> &intersection) const;
bool intersectT(const Line3<T> &l, T &t) const;
};
//--------------------
// Convenient typedefs
//--------------------
typedef Sphere3<float> Sphere3f;
typedef Sphere3<double> Sphere3d;
//---------------
// Implementation
//---------------
template <class T>
void Sphere3<T>::circumscribe(const Box<Vec3<T> > &box)
{
center = T(0.5) * (box.min + box.max);
radius = (box.max - center).length();
}
template <class T>
bool Sphere3<T>::intersectT(const Line3<T> &line, T &t) const
{
bool doesIntersect = true;
Vec3<T> v = line.pos - center;
T B = T(2.0) * (line.dir ^ v);
T C = (v ^ v) - (radius * radius);
// compute discriminant
// if negative, there is no intersection
T discr = B*B - T(4.0)*C;
if (discr < 0.0)
{
// line and Sphere3 do not intersect
doesIntersect = false;
}
else
{
// t0: (-B - sqrt(B^2 - 4AC)) / 2A (A = 1)
T sqroot = Math<T>::sqrt(discr);
t = (-B - sqroot) * T(0.5);
if (t < 0.0)
{
// no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A (A = 1)
t = (-B + sqroot) * T(0.5);
}
if (t < 0.0)
doesIntersect = false;
}
return doesIntersect;
}
template <class T>
bool Sphere3<T>::intersect(const Line3<T> &line, Vec3<T> &intersection) const
{
T t;
if (intersectT (line, t))
{
intersection = line(t);
return true;
}
else
{
return false;
}
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHSPHERE_H

View File

@@ -0,0 +1,583 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Specializations of the Vec2<T> and Vec3<T> templates.
//
//----------------------------------------------------------------------------
#include "ImathVec.h"
#include "ImathExport.h"
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
// suppress exception specification warnings
#pragma warning(disable:4290)
#endif
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
namespace
{
template<class T>
bool
normalizeOrThrow(Vec2<T> &v)
{
int axis = -1;
for (int i = 0; i < 2; i ++)
{
if (v[i] != 0)
{
if (axis != -1)
{
throw IntVecNormalizeExc ("Cannot normalize an integer "
"vector unless it is parallel "
"to a principal axis");
}
axis = i;
}
}
v[axis] = (v[axis] > 0) ? 1 : -1;
return true;
}
template<class T>
bool
normalizeOrThrow(Vec3<T> &v)
{
int axis = -1;
for (int i = 0; i < 3; i ++)
{
if (v[i] != 0)
{
if (axis != -1)
{
throw IntVecNormalizeExc ("Cannot normalize an integer "
"vector unless it is parallel "
"to a principal axis");
}
axis = i;
}
}
v[axis] = (v[axis] > 0) ? 1 : -1;
return true;
}
template<class T>
bool
normalizeOrThrow(Vec4<T> &v)
{
int axis = -1;
for (int i = 0; i < 4; i ++)
{
if (v[i] != 0)
{
if (axis != -1)
{
throw IntVecNormalizeExc ("Cannot normalize an integer "
"vector unless it is parallel "
"to a principal axis");
}
axis = i;
}
}
v[axis] = (v[axis] > 0) ? 1 : -1;
return true;
}
}
// Vec2<short>
template <>
IMATH_EXPORT
short
Vec2<short>::length () const
{
float lenF = Math<float>::sqrt ((float)dot (*this));
short lenS = (short) (lenF + 0.5f);
return lenS;
}
template <>
IMATH_EXPORT
const Vec2<short> &
Vec2<short>::normalize ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec2<short> &
Vec2<short>::normalizeExc ()
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec2<short> &
Vec2<short>::normalizeNonNull ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
Vec2<short>
Vec2<short>::normalized () const
{
Vec2<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
IMATH_EXPORT
Vec2<short>
Vec2<short>::normalizedExc () const
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec2<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
IMATH_EXPORT
Vec2<short>
Vec2<short>::normalizedNonNull () const
{
Vec2<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
// Vec2<int>
template <>
IMATH_EXPORT
int
Vec2<int>::length () const
{
float lenF = Math<float>::sqrt ((float)dot (*this));
int lenI = (int) (lenF + 0.5f);
return lenI;
}
template <>
IMATH_EXPORT
const Vec2<int> &
Vec2<int>::normalize ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec2<int> &
Vec2<int>::normalizeExc ()
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec2<int> &
Vec2<int>::normalizeNonNull ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
Vec2<int>
Vec2<int>::normalized () const
{
Vec2<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
IMATH_EXPORT
Vec2<int>
Vec2<int>::normalizedExc () const
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec2<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
IMATH_EXPORT
Vec2<int>
Vec2<int>::normalizedNonNull () const
{
Vec2<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
// Vec3<short>
template <>
IMATH_EXPORT
short
Vec3<short>::length () const
{
float lenF = Math<float>::sqrt ((float)dot (*this));
short lenS = (short) (lenF + 0.5f);
return lenS;
}
template <>
IMATH_EXPORT
const Vec3<short> &
Vec3<short>::normalize ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec3<short> &
Vec3<short>::normalizeExc ()
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec3<short> &
Vec3<short>::normalizeNonNull ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
Vec3<short>
Vec3<short>::normalized () const
{
Vec3<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
IMATH_EXPORT
Vec3<short>
Vec3<short>::normalizedExc () const
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec3<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
IMATH_EXPORT
Vec3<short>
Vec3<short>::normalizedNonNull () const
{
Vec3<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
// Vec3<int>
template <>
IMATH_EXPORT
int
Vec3<int>::length () const
{
float lenF = Math<float>::sqrt ((float)dot (*this));
int lenI = (int) (lenF + 0.5f);
return lenI;
}
template <>
IMATH_EXPORT
const Vec3<int> &
Vec3<int>::normalize ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec3<int> &
Vec3<int>::normalizeExc ()
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec3<int> &
Vec3<int>::normalizeNonNull ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
Vec3<int>
Vec3<int>::normalized () const
{
Vec3<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
IMATH_EXPORT
Vec3<int>
Vec3<int>::normalizedExc () const
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec3<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
IMATH_EXPORT
Vec3<int>
Vec3<int>::normalizedNonNull () const
{
Vec3<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
// Vec4<short>
template <>
IMATH_EXPORT
short
Vec4<short>::length () const
{
float lenF = Math<float>::sqrt ((float)dot (*this));
short lenS = (short) (lenF + 0.5f);
return lenS;
}
template <>
IMATH_EXPORT
const Vec4<short> &
Vec4<short>::normalize ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec4<short> &
Vec4<short>::normalizeExc ()
{
if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec4<short> &
Vec4<short>::normalizeNonNull ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
IMATH_EXPORT
Vec4<short>
Vec4<short>::normalized () const
{
Vec4<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
IMATH_EXPORT
Vec4<short>
Vec4<short>::normalizedExc () const
{
if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec4<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
IMATH_EXPORT
Vec4<short>
Vec4<short>::normalizedNonNull () const
{
Vec4<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
// Vec4<int>
template <>
IMATH_EXPORT
int
Vec4<int>::length () const
{
float lenF = Math<float>::sqrt ((float)dot (*this));
int lenI = (int) (lenF + 0.5f);
return lenI;
}
template <>
IMATH_EXPORT
const Vec4<int> &
Vec4<int>::normalize ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec4<int> &
Vec4<int>::normalizeExc ()
{
if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
const Vec4<int> &
Vec4<int>::normalizeNonNull ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
IMATH_EXPORT
Vec4<int>
Vec4<int>::normalized () const
{
Vec4<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
IMATH_EXPORT
Vec4<int>
Vec4<int>::normalizedExc () const
{
if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec4<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
IMATH_EXPORT
Vec4<int>
Vec4<int>::normalizedNonNull () const
{
Vec4<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, 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_IMATHVECALGO_H
#define INCLUDED_IMATHVECALGO_H
//-------------------------------------------------------------------------
//
// This file contains algorithms applied to or in conjunction
// with points (Imath::Vec2 and Imath::Vec3).
// The assumption made is that these functions are called much
// less often than the basic point functions or these functions
// require more support classes.
//
//-------------------------------------------------------------------------
#include "ImathVec.h"
#include "ImathLimits.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//-----------------------------------------------------------------
// Find the projection of vector t onto vector s (Vec2, Vec3, Vec4)
//-----------------------------------------------------------------
template <class Vec> Vec project (const Vec &s, const Vec &t);
//------------------------------------------------
// Find a vector that is perpendicular to s and
// in the same plane as s and t (Vec2, Vec3, Vec4)
//------------------------------------------------
template <class Vec> Vec orthogonal (const Vec &s, const Vec &t);
//-----------------------------------------------
// Find the direction of a ray s after reflection
// off a plane with normal t (Vec2, Vec3, Vec4)
//-----------------------------------------------
template <class Vec> Vec reflect (const Vec &s, const Vec &t);
//--------------------------------------------------------------------
// Find the vertex of triangle (v0, v1, v2) that is closest to point p
// (Vec2, Vec3, Vec4)
//--------------------------------------------------------------------
template <class Vec> Vec closestVertex (const Vec &v0,
const Vec &v1,
const Vec &v2,
const Vec &p);
//---------------
// Implementation
//---------------
template <class Vec>
Vec
project (const Vec &s, const Vec &t)
{
Vec sNormalized = s.normalized();
return sNormalized * (sNormalized ^ t);
}
template <class Vec>
Vec
orthogonal (const Vec &s, const Vec &t)
{
return t - project (s, t);
}
template <class Vec>
Vec
reflect (const Vec &s, const Vec &t)
{
return s - typename Vec::BaseType(2) * (s - project(t, s));
}
template <class Vec>
Vec
closestVertex(const Vec &v0,
const Vec &v1,
const Vec &v2,
const Vec &p)
{
Vec nearest = v0;
typename Vec::BaseType neardot = (v0 - p).length2();
typename Vec::BaseType tmp = (v1 - p).length2();
if (tmp < neardot)
{
neardot = tmp;
nearest = v1;
}
tmp = (v2 - p).length2();
if (tmp < neardot)
{
neardot = tmp;
nearest = v2;
}
return nearest;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHVECALGO_H

View File

@@ -0,0 +1,44 @@
## Process this file with automake to produce Makefile.in
lib_LTLIBRARIES = libImath.la
libImath_la_SOURCES = ImathShear.cpp ImathMatrixAlgo.cpp ImathVec.cpp \
ImathColorAlgo.cpp ImathFun.cpp \
ImathColorAlgo.h ImathMatrixAlgo.h ImathVec.h \
ImathShear.h ImathFun.h ImathBox.h ImathBoxAlgo.h \
ImathEuler.h ImathExc.h ImathLimits.h ImathLine.h \
ImathLineAlgo.h ImathMatrix.h ImathPlane.h \
ImathSphere.h ImathVecAlgo.h ImathQuat.h \
ImathFrustum.h ImathMath.h ImathGL.h \
ImathColor.h ImathRandom.h ImathRoots.h \
ImathHalfLimits.h ImathInterval.h ImathGLU.h \
ImathFrame.h ImathPlatform.h \
ImathBox.cpp ImathRandom.cpp ImathInt64.h \
ImathFrustumTest.h
libImath_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
if LIB_SUFFIX_EXISTS
libImath_la_LDFLAGS += -release @LIB_SUFFIX@
endif
libImath_la_LIBADD = ../Iex/libIex.la
libImathincludedir = $(includedir)/OpenEXR
libImathinclude_HEADERS = ImathColorAlgo.h ImathMatrixAlgo.h ImathVec.h \
ImathShear.h ImathFun.h ImathBox.h ImathBoxAlgo.h \
ImathEuler.h ImathExc.h ImathLimits.h ImathLine.h \
ImathLineAlgo.h ImathMatrix.h ImathPlane.h \
ImathSphere.h ImathVecAlgo.h ImathQuat.h \
ImathFrustum.h ImathMath.h ImathGL.h \
ImathColor.h ImathRandom.h ImathRoots.h \
ImathHalfLimits.h ImathInterval.h ImathGLU.h \
ImathFrame.h ImathPlatform.h ImathInt64.h \
ImathNamespace.h ImathForward.h ImathExport.h \
ImathFrustumTest.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/Half \
-I$(top_srcdir)/config
EXTRA_DIST = CMakeLists.txt