init - 初始化项目

This commit is contained in:
Lee Nony
2022-05-06 01:58:53 +08:00
commit 90a5cc7cb6
6772 changed files with 2837787 additions and 0 deletions

37
3rdparty/openexr/Imath/ImathBox.cpp vendored Normal file
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

849
3rdparty/openexr/Imath/ImathBox.h vendored Normal file
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

1016
3rdparty/openexr/Imath/ImathBoxAlgo.h vendored Normal file

File diff suppressed because it is too large Load Diff

736
3rdparty/openexr/Imath/ImathColor.h vendored Normal file
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

257
3rdparty/openexr/Imath/ImathColorAlgo.h vendored Normal file
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

927
3rdparty/openexr/Imath/ImathEuler.h vendored Normal file
View File

@@ -0,0 +1,927 @@
///////////////////////////////////////////////////////////////////////////
//
// 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)
{
const T pi = static_cast<T>(M_PI);
angle = fmod(T (angle), T (2 * pi));
if (angle < -pi) angle += 2 * pi;
if (angle > +pi) angle -= 2 * 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

73
3rdparty/openexr/Imath/ImathExc.h vendored Normal file
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

46
3rdparty/openexr/Imath/ImathExport.h vendored Normal file
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

72
3rdparty/openexr/Imath/ImathForward.h vendored Normal file
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

192
3rdparty/openexr/Imath/ImathFrame.h vendored Normal file
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

741
3rdparty/openexr/Imath/ImathFrustum.h vendored Normal file
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

181
3rdparty/openexr/Imath/ImathFun.cpp vendored Normal file
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

269
3rdparty/openexr/Imath/ImathFun.h vendored Normal file
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,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

65
3rdparty/openexr/Imath/ImathInt64.h vendored Normal file
View File

@@ -0,0 +1,65 @@
///////////////////////////////////////////////////////////////////////////
//
// 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;
typedef __int64 SInt64;
#elif ULONG_MAX == 18446744073709551615LU
typedef long unsigned int Int64;
typedef long int SInt64;
#else
typedef long long unsigned int Int64;
typedef long long int SInt64;
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATH_INT64_H

226
3rdparty/openexr/Imath/ImathInterval.h vendored Normal file
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

268
3rdparty/openexr/Imath/ImathLimits.h vendored Normal file
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

185
3rdparty/openexr/Imath/ImathLine.h vendored Normal file
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

288
3rdparty/openexr/Imath/ImathLineAlgo.h vendored Normal file
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

208
3rdparty/openexr/Imath/ImathMath.h vendored Normal file
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

3433
3rdparty/openexr/Imath/ImathMatrix.h vendored Normal file

File diff suppressed because it is too large Load Diff

1252
3rdparty/openexr/Imath/ImathMatrixAlgo.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

1425
3rdparty/openexr/Imath/ImathMatrixAlgo.h vendored Normal file

File diff suppressed because it is too large Load Diff

115
3rdparty/openexr/Imath/ImathNamespace.h vendored Normal file
View File

@@ -0,0 +1,115 @@
///////////////////////////////////////////////////////////////////////////
//
// 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"
#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 }
#endif /* INCLUDED_IMATHNAMESPACE_H */

257
3rdparty/openexr/Imath/ImathPlane.h vendored Normal file
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

112
3rdparty/openexr/Imath/ImathPlatform.h vendored Normal file
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

965
3rdparty/openexr/Imath/ImathQuat.h vendored Normal file
View File

@@ -0,0 +1,965 @@
///////////////////////////////////////////////////////////////////////////
//
// 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>
#include <algorithm>
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

194
3rdparty/openexr/Imath/ImathRandom.cpp vendored Normal file
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

401
3rdparty/openexr/Imath/ImathRandom.h vendored Normal file
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

219
3rdparty/openexr/Imath/ImathRoots.h vendored Normal file
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

54
3rdparty/openexr/Imath/ImathShear.cpp vendored Normal file
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

656
3rdparty/openexr/Imath/ImathShear.h vendored Normal file
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

177
3rdparty/openexr/Imath/ImathSphere.h vendored Normal file
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

583
3rdparty/openexr/Imath/ImathVec.cpp vendored Normal file
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

2227
3rdparty/openexr/Imath/ImathVec.h vendored Normal file

File diff suppressed because it is too large Load Diff

147
3rdparty/openexr/Imath/ImathVecAlgo.h vendored Normal file
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