Compare commits

...
1 Commits
576 changed files with 0 additions and 97955 deletions
-17
View File
@@ -1,17 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
CVS
-39
View File
@@ -1,39 +0,0 @@
Developers:
-----------
Florian Kainz <kainz@ilm.com>
Rod Bogart <rgb@ilm.com>
Drew Hess <dhess@ilm.com>
Paul Schneider <paultschneider@mac.com>
Bill Anderson <wja@ilm.com>
Wojciech Jarosz <wjarosz@ucsd.edu>
Contributors:
-------------
Simon Green <SGreen@nvidia.com>
Rito Trevino <etrevino@ilm.com>
Josh Pines
Christian Rouet
Rodrigo Damazio <rdamazio@lsi.usp.br>
Greg Ward <gward@lmi.net>
Joseph Goldstone <joseph@lp.com>
Loren Carpenter, Pixar Animation Studios
Win32 build system:
-------------------
Nick Porcino <NPorcino@lucasarts.com>
Win32 port contributors:
------------------------
Dustin Graves <dgraves@computer.org>
Jukka Liimatta <jukka.liimatta@twilight3d.com>
Baumann Konstantin <Konstantin.Baumann@hpi.uni-potsdam.de>
Daniel Koch <daniel@eyeonline.com>
E. Scott Larsen <larsene@cs.unc.edu>
stephan mantler <step@acm.org>
Andreas Kahler <AKahler@nxn-software.com>
Frank Jargstorff <fjargstorff@nvidia.com>
Lutz Latta
-34
View File
@@ -1,34 +0,0 @@
Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
Entertainment Company Ltd. Portions contributed and copyright held by
others as indicated. 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
any other contributors to this software 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.
-4
View File
@@ -1,4 +0,0 @@
Version 0.9.0:
* Initial release of this code as a separate library.
Previously the libraries contained were part of version 1.4.0 of
OpenEXR
-16
View File
@@ -1,16 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
-32
View File
@@ -1,32 +0,0 @@
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libHalf.la
libHalf_la_SOURCES = half.cpp half.h halfFunction.h halfLimits.h
libHalf_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
libHalfincludedir = $(includedir)/OpenEXR
libHalfinclude_HEADERS = half.h halfFunction.h halfLimits.h
# these are used to build eLut.h and toFloat.h dynamically
EXTRA_DIST = eLut.cpp toFloat.cpp
CLEANFILES = eLut eLut.h toFloat toFloat.h
eLut_SOURCES = eLut.cpp
toFloat_SOURCES = toFloat.cpp
eLut.h: eLut
./eLut > eLut.h
toFloat.h: toFloat
./toFloat > toFloat.h
BUILT_SOURCES = eLut.h toFloat.h
noinst_PROGRAMS = eLut toFloat
-114
View File
@@ -1,114 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>
using namespace std;
//-----------------------------------------------------
// Compute a lookup table for float-to-half conversion.
//
// When indexed with the combined sign and exponent of
// a float, the table either returns the combined sign
// and exponent of the corresponding half, or zero if
// the corresponding half may not be normalized (zero,
// denormalized, overflow).
//-----------------------------------------------------
void
initELut (unsigned short eLut[])
{
for (int i = 0; i < 0x100; i++)
{
int e = (i & 0x0ff) - (127 - 15);
if (e <= 0 || e >= 30)
{
//
// Special case
//
eLut[i] = 0;
eLut[i | 0x100] = 0;
}
else
{
//
// Common case - normalized half, no exponent overflow possible
//
eLut[i] = (e << 10);
eLut[i | 0x100] = ((e << 10) | 0x8000);
}
}
}
//------------------------------------------------------------
// Main - prints the sign-and-exponent conversion lookup table
//------------------------------------------------------------
int
main ()
{
const int tableSize = 1 << 9;
unsigned short eLut[tableSize];
initELut (eLut);
cout << "//\n"
"// This is an automatically generated file.\n"
"// Do not edit.\n"
"//\n\n";
cout << "{\n ";
for (int i = 0; i < tableSize; i++)
{
cout << setw (5) << eLut[i] << ", ";
if (i % 8 == 7)
{
cout << "\n";
if (i < tableSize - 1)
cout << " ";
}
}
cout << "};\n";
return 0;
}
-311
View File
@@ -1,311 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// class half --
// implementation of non-inline members
//
//---------------------------------------------------------------------------
#include <assert.h>
#include "half.h"
using namespace std;
//-------------------------------------------------------------
// Lookup tables for half-to-float and float-to-half conversion
//-------------------------------------------------------------
#if defined (OPENEXR_DLL)
__declspec(dllexport) half::uif _toFloat[1 << 16] =
#include "toFloat.h"
__declspec(dllexport) unsigned short _eLut[1 << 9] =
#include "eLut.h"
#else
const half::uif half::_toFloat[1 << 16] =
#include "toFloat.h"
const unsigned short half::_eLut[1 << 9] =
#include "eLut.h"
#endif
//-----------------------------------------------
// Overflow handler for float-to-half conversion;
// generates a hardware floating-point overflow,
// which may be trapped by the operating system.
//-----------------------------------------------
float
half::overflow ()
{
volatile float f = 1e10;
for (int i = 0; i < 10; i++)
f *= f; // this will overflow before
// the for­loop terminates
return f;
}
//-----------------------------------------------------
// Float-to-half conversion -- general case, including
// zeroes, denormalized numbers and exponent overflows.
//-----------------------------------------------------
short
half::convert (int i)
{
//
// Our floating point number, f, is represented by the bit
// pattern in integer i. Disassemble that bit pattern into
// the sign, s, the exponent, e, and the significand, m.
// Shift s into the position where it will go in in the
// resulting half number.
// Adjust e, accounting for the different exponent bias
// of float and half (127 versus 15).
//
register int s = (i >> 16) & 0x00008000;
register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
register int m = i & 0x007fffff;
//
// Now reassemble s, e and m into a half:
//
if (e <= 0)
{
if (e < -10)
{
//
// E is less than -10. The absolute value of f is
// less than HALF_MIN (f may be a small normalized
// float, a denormalized float or a zero).
//
// We convert f to a half zero with the same sign as f.
//
return s;
}
//
// E is between -10 and 0. F is a normalized float
// whose magnitude is less than HALF_NRM_MIN.
//
// We convert f to a denormalized half.
//
m = (m | 0x00800000) >> (1 - e);
//
// Round to nearest, round "0.5" up.
//
// Rounding may cause the significand to overflow and make
// our number normalized. Because of the way a half's bits
// are laid out, we don't have to treat this case separately;
// the code below will handle it correctly.
//
if (m & 0x00001000)
m += 0x00002000;
//
// Assemble the half from s, e (zero) and m.
//
return s | (m >> 13);
}
else if (e == 0xff - (127 - 15))
{
if (m == 0)
{
//
// F is an infinity; convert f to a half
// infinity with the same sign as f.
//
return s | 0x7c00;
}
else
{
//
// F is a NAN; we produce a half NAN that preserves
// the sign bit and the 10 leftmost bits of the
// significand of f, with one exception: If the 10
// leftmost bits are all zero, the NAN would turn
// into an infinity, so we have to set at least one
// bit in the significand.
//
m >>= 13;
return s | 0x7c00 | m | (m == 0);
}
}
else
{
//
// E is greater than zero. F is a normalized float.
// We try to convert f to a normalized half.
//
//
// Round to nearest, round "0.5" up
//
if (m & 0x00001000)
{
m += 0x00002000;
if (m & 0x00800000)
{
m = 0; // overflow in significand,
e += 1; // adjust exponent
}
}
//
// Handle exponent overflow
//
if (e > 30)
{
overflow (); // Cause a hardware floating point overflow;
return s | 0x7c00; // if this returns, the half becomes an
} // infinity with the same sign as f.
//
// Assemble the half from s, e and m.
//
return s | (e << 10) | (m >> 13);
}
}
//---------------------
// Stream I/O operators
//---------------------
ostream &
operator << (ostream &os, half h)
{
os << float (h);
return os;
}
istream &
operator >> (istream &is, half &h)
{
float f;
is >> f;
h = half (f);
return is;
}
//---------------------------------------
// Functions to print the bit-layout of
// floats and halfs, mostly for debugging
//---------------------------------------
void
printBits (ostream &os, half h)
{
unsigned short b = h.bits();
for (int i = 15; i >= 0; i--)
{
os << (((b >> i) & 1)? '1': '0');
if (i == 15 || i == 10)
os << ' ';
}
}
void
printBits (ostream &os, float f)
{
half::uif x;
x.f = f;
for (int i = 31; i >= 0; i--)
{
os << (((x.i >> i) & 1)? '1': '0');
if (i == 31 || i == 23)
os << ' ';
}
}
void
printBits (char c[19], half h)
{
unsigned short b = h.bits();
for (int i = 15, j = 0; i >= 0; i--, j++)
{
c[j] = (((b >> i) & 1)? '1': '0');
if (i == 15 || i == 10)
c[++j] = ' ';
}
c[18] = 0;
}
void
printBits (char c[35], float f)
{
half::uif x;
x.f = f;
for (int i = 31, j = 0; i >= 0; i--, j++)
{
c[j] = (((x.i >> i) & 1)? '1': '0');
if (i == 31 || i == 23)
c[++j] = ' ';
}
c[34] = 0;
}
-775
View File
@@ -1,775 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// half -- a 16-bit floating point number class:
//
// Type half can represent positive and negative numbers whose
// magnitude is between roughly 6.1e-5 and 6.5e+4 with a relative
// error of 9.8e-4; numbers smaller than 6.1e-5 can be represented
// with an absolute error of 6.0e-8. All integers from -2048 to
// +2048 can be represented exactly.
//
// Type half behaves (almost) like the built-in C++ floating point
// types. In arithmetic expressions, half, float and double can be
// mixed freely. Here are a few examples:
//
// half a (3.5);
// float b (a + sqrt (a));
// a += b;
// b += a;
// b = a + 7;
//
// Conversions from half to float are lossless; all half numbers
// are exactly representable as floats.
//
// Conversions from float to half may not preserve the float's
// value exactly. If a float is not representable as a half, the
// float value is rounded to the nearest representable half. If
// a float value is exactly in the middle between the two closest
// representable half values, then the float value is rounded to
// the half with the greater magnitude.
//
// Overflows during float-to-half conversions cause arithmetic
// exceptions. An overflow occurs when the float value to be
// converted is too large to be represented as a half, or if the
// float value is an infinity or a NAN.
//
// The implementation of type half makes the following assumptions
// about the implementation of the built-in C++ types:
//
// float is an IEEE 754 single-precision number
// sizeof (float) == 4
// sizeof (unsigned int) == sizeof (float)
// alignof (unsigned int) == alignof (float)
// sizeof (unsigned short) == 2
//
//---------------------------------------------------------------------------
#ifndef _HALF_H_
#define _HALF_H_
#include <iostream>
class half
{
public:
//-------------
// Constructors
//-------------
half (); // no initialization
half (float f);
//--------------------
// Conversion to float
//--------------------
operator float () const;
//------------
// Unary minus
//------------
half operator - () const;
//-----------
// Assignment
//-----------
half & operator = (half h);
half & operator = (float f);
half & operator += (half h);
half & operator += (float f);
half & operator -= (half h);
half & operator -= (float f);
half & operator *= (half h);
half & operator *= (float f);
half & operator /= (half h);
half & operator /= (float f);
//---------------------------------------------------------
// Round to n-bit precision (n should be between 0 and 10).
// After rounding, the significand's 10-n least significant
// bits will be zero.
//---------------------------------------------------------
half round (unsigned int n) const;
//--------------------------------------------------------------------
// Classification:
//
// h.isFinite() returns true if h is a normalized number,
// a denormalized number or zero
//
// h.isNormalized() returns true if h is a normalized number
//
// h.isDenormalized() returns true if h is a denormalized number
//
// h.isZero() returns true if h is zero
//
// h.isNan() returns true if h is a NAN
//
// h.isInfinity() returns true if h is a positive
// or a negative infinity
//
// h.isNegative() returns true if the sign bit of h
// is set (negative)
//--------------------------------------------------------------------
bool isFinite () const;
bool isNormalized () const;
bool isDenormalized () const;
bool isZero () const;
bool isNan () const;
bool isInfinity () const;
bool isNegative () const;
//--------------------------------------------
// Special values
//
// posInf() returns +infinity
//
// negInf() returns -infinity
//
// qNan() returns a NAN with the bit
// pattern 0111111111111111
//
// sNan() returns a NAN with the bit
// pattern 0111110111111111
//--------------------------------------------
static half posInf ();
static half negInf ();
static half qNan ();
static half sNan ();
//--------------------------------------
// Access to the internal representation
//--------------------------------------
unsigned short bits () const;
void setBits (unsigned short bits);
public:
union uif
{
unsigned int i;
float f;
};
private:
static short convert (int i);
static float overflow ();
unsigned short _h;
//---------------------------------------------------
// Windows dynamic libraries don't like static
// member variables.
//---------------------------------------------------
#ifndef OPENEXR_DLL
static const uif _toFloat[1 << 16];
static const unsigned short _eLut[1 << 9];
#endif
};
#if defined(OPENEXR_DLL)
//--------------------------------------
// Lookup tables defined for Windows DLL
//--------------------------------------
#if defined(HALF_EXPORTS)
extern __declspec(dllexport) half::uif _toFloat[1 << 16];
extern __declspec(dllexport) unsigned short _eLut[1 << 9];
#else
extern __declspec(dllimport) half::uif _toFloat[1 << 16];
extern __declspec(dllimport) unsigned short _eLut[1 << 9];
#endif
#endif
//-----------
// Stream I/O
//-----------
std::ostream & operator << (std::ostream &os, half h);
std::istream & operator >> (std::istream &is, half &h);
//----------
// Debugging
//----------
void printBits (std::ostream &os, half h);
void printBits (std::ostream &os, float f);
void printBits (char c[19], half h);
void printBits (char c[35], float f);
//-------------------------------------------------------------------------
// Limits
//
// Visual C++ will complain if HALF_MIN, HALF_NRM_MIN etc. are not float
// constants, but at least one other compiler (gcc 2.96) produces incorrect
// results if they are.
//-------------------------------------------------------------------------
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#define HALF_MIN 5.96046448e-08f // Smallest positive half
#define HALF_NRM_MIN 6.10351562e-05f // Smallest positive normalized half
#define HALF_MAX 65504.0f // Largest positive half
#define HALF_EPSILON 0.00097656f // Smallest positive e for which
// half (1.0 + e) != half (1.0)
#else
#define HALF_MIN 5.96046448e-08 // Smallest positive half
#define HALF_NRM_MIN 6.10351562e-05 // Smallest positive normalized half
#define HALF_MAX 65504.0 // Largest positive half
#define HALF_EPSILON 0.00097656 // Smallest positive e for which
// half (1.0 + e) != half (1.0)
#endif
#define HALF_MANT_DIG 11 // Number of digits in mantissa
// (significand + hidden leading 1)
#define HALF_DIG 2 // Number of base 10 digits that
// can be represented without change
#define HALF_RADIX 2 // Base of the exponent
#define HALF_MIN_EXP -13 // Minimum negative integer such that
// HALF_RADIX raised to the power of
// one less than that integer is a
// normalized half
#define HALF_MAX_EXP 16 // Maximum positive integer such that
// HALF_RADIX raised to the power of
// one less than that integer is a
// normalized half
#define HALF_MIN_10_EXP -4 // Minimum positive integer such
// that 10 raised to that power is
// a normalized half
#define HALF_MAX_10_EXP 4 // Maximum positive integer such
// that 10 raised to that power is
// a normalized half
//---------------------------------------------------------------------------
//
// Implementation --
//
// Representation of a float:
//
// We assume that a float, f, is an IEEE 754 single-precision
// floating point number, whose bits are arranged as follows:
//
// 31 (msb)
// |
// | 30 23
// | | |
// | | | 22 0 (lsb)
// | | | | |
// X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
//
// s e m
//
// S is the sign-bit, e is the exponent and m is the significand.
//
// If e is between 1 and 254, f is a normalized number:
//
// s e-127
// f = (-1) * 2 * 1.m
//
// If e is 0, and m is not zero, f is a denormalized number:
//
// s -126
// f = (-1) * 2 * 0.m
//
// If e and m are both zero, f is zero:
//
// f = 0.0
//
// If e is 255, f is an "infinity" or "not a number" (NAN),
// depending on whether m is zero or not.
//
// Examples:
//
// 0 00000000 00000000000000000000000 = 0.0
// 0 01111110 00000000000000000000000 = 0.5
// 0 01111111 00000000000000000000000 = 1.0
// 0 10000000 00000000000000000000000 = 2.0
// 0 10000000 10000000000000000000000 = 3.0
// 1 10000101 11110000010000000000000 = -124.0625
// 0 11111111 00000000000000000000000 = +infinity
// 1 11111111 00000000000000000000000 = -infinity
// 0 11111111 10000000000000000000000 = NAN
// 1 11111111 11111111111111111111111 = NAN
//
// Representation of a half:
//
// Here is the bit-layout for a half number, h:
//
// 15 (msb)
// |
// | 14 10
// | | |
// | | | 9 0 (lsb)
// | | | | |
// X XXXXX XXXXXXXXXX
//
// s e m
//
// S is the sign-bit, e is the exponent and m is the significand.
//
// If e is between 1 and 30, h is a normalized number:
//
// s e-15
// h = (-1) * 2 * 1.m
//
// If e is 0, and m is not zero, h is a denormalized number:
//
// S -14
// h = (-1) * 2 * 0.m
//
// If e and m are both zero, h is zero:
//
// h = 0.0
//
// If e is 31, h is an "infinity" or "not a number" (NAN),
// depending on whether m is zero or not.
//
// Examples:
//
// 0 00000 0000000000 = 0.0
// 0 01110 0000000000 = 0.5
// 0 01111 0000000000 = 1.0
// 0 10000 0000000000 = 2.0
// 0 10000 1000000000 = 3.0
// 1 10101 1111000001 = -124.0625
// 0 11111 0000000000 = +infinity
// 1 11111 0000000000 = -infinity
// 0 11111 1000000000 = NAN
// 1 11111 1111111111 = NAN
//
// Conversion:
//
// Converting from a float to a half requires some non-trivial bit
// manipulations. In some cases, this makes conversion relatively
// slow, but the most common case is accelerated via table lookups.
//
// Converting back from a half to a float is easier because we don't
// have to do any rounding. In addition, there are only 65536
// different half numbers; we can convert each of those numbers once
// and store the results in a table. Later, all conversions can be
// done using only simple table lookups.
//
//---------------------------------------------------------------------------
//--------------------
// Simple constructors
//--------------------
inline
half::half ()
{
// no initialization
}
//----------------------------
// Half-from-float constructor
//----------------------------
inline
half::half (float f)
{
uif x;
x.f = f;
if (f == 0)
{
//
// Common special case - zero.
// Preserve the zero's sign bit.
//
_h = (x.i >> 16);
}
else
{
//
// We extract the combined sign and exponent, e, from our
// floating-point number, f. Then we convert e to the sign
// and exponent of the half number via a table lookup.
//
// For the most common case, where a normalized half is produced,
// the table lookup returns a non-zero value; in this case, all
// we have to do is round f's significand to 10 bits and combine
// the result with e.
//
// For all other cases (overflow, zeroes, denormalized numbers
// resulting from underflow, infinities and NANs), the table
// lookup returns zero, and we call a longer, non-inline function
// to do the float-to-half conversion.
//
register int e = (x.i >> 23) & 0x000001ff;
e = _eLut[e];
if (e)
{
//
// Simple case - round the significand and
// combine it with the sign and exponent.
//
_h = e + (((x.i & 0x007fffff) + 0x00001000) >> 13);
}
else
{
//
// Difficult case - call a function.
//
_h = convert (x.i);
}
}
}
//------------------------------------------
// Half-to-float conversion via table lookup
//------------------------------------------
inline
half::operator float () const
{
return _toFloat[_h].f;
}
//-------------------------
// Round to n-bit precision
//-------------------------
inline half
half::round (unsigned int n) const
{
//
// Parameter check.
//
if (n >= 10)
return *this;
//
// Disassemble h into the sign, s,
// and the combined exponent and significand, e.
//
unsigned short s = _h & 0x8000;
unsigned short e = _h & 0x7fff;
//
// Round the exponent and significand to the nearest value
// where ones occur only in the (10-n) most significant bits.
// Note that the exponent adjusts automatically if rounding
// up causes the significand to overflow.
//
e >>= 9 - n;
e += e & 1;
e <<= 9 - n;
//
// Check for exponent overflow.
//
if (e >= 0x7c00)
{
//
// Overflow occurred -- truncate instead of rounding.
//
e = _h;
e >>= 10 - n;
e <<= 10 - n;
}
//
// Put the original sign bit back.
//
half h;
h._h = s | e;
return h;
}
//-----------------------
// Other inline functions
//-----------------------
inline half
half::operator - () const
{
half h;
h._h = _h ^ 0x8000;
return h;
}
inline half &
half::operator = (half h)
{
_h = h._h;
return *this;
}
inline half &
half::operator = (float f)
{
*this = half (f);
return *this;
}
inline half &
half::operator += (half h)
{
*this = half (float (*this) + float (h));
return *this;
}
inline half &
half::operator += (float f)
{
*this = half (float (*this) + f);
return *this;
}
inline half &
half::operator -= (half h)
{
*this = half (float (*this) - float (h));
return *this;
}
inline half &
half::operator -= (float f)
{
*this = half (float (*this) - f);
return *this;
}
inline half &
half::operator *= (half h)
{
*this = half (float (*this) * float (h));
return *this;
}
inline half &
half::operator *= (float f)
{
*this = half (float (*this) * f);
return *this;
}
inline half &
half::operator /= (half h)
{
*this = half (float (*this) / float (h));
return *this;
}
inline half &
half::operator /= (float f)
{
*this = half (float (*this) / f);
return *this;
}
inline bool
half::isFinite () const
{
unsigned short e = (_h >> 10) & 0x001f;
return e < 31;
}
inline bool
half::isNormalized () const
{
unsigned short e = (_h >> 10) & 0x001f;
return e > 0 && e < 31;
}
inline bool
half::isDenormalized () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 0 && m != 0;
}
inline bool
half::isZero () const
{
return (_h & 0x7fff) == 0;
}
inline bool
half::isNan () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 31 && m != 0;
}
inline bool
half::isInfinity () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 31 && m == 0;
}
inline bool
half::isNegative () const
{
return (_h & 0x8000) != 0;
}
inline half
half::posInf ()
{
half h;
h._h = 0x7c00;
return h;
}
inline half
half::negInf ()
{
half h;
h._h = 0xfc00;
return h;
}
inline half
half::qNan ()
{
half h;
h._h = 0x7fff;
return h;
}
inline half
half::sNan ()
{
half h;
h._h = 0x7dff;
return h;
}
inline unsigned short
half::bits () const
{
return _h;
}
inline void
half::setBits (unsigned short bits)
{
_h = bits;
}
#undef HALF_EXPORT_CONST
#endif
-159
View File
@@ -1,159 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// halfFunction<T> -- a class for fast evaluation
// of half --> T functions
//
// The constructor for a halfFunction object,
//
// halfFunction (function,
// domainMin, domainMax,
// defaultValue,
// posInfValue, negInfValue,
// nanValue);
//
// evaluates the function for all finite half values in the interval
// [domainMin, domainMax], and stores the results in a lookup table.
// For finite half values that are not in [domainMin, domainMax], the
// constructor stores defaultValue in the table. For positive infinity,
// negative infinity and NANs, posInfValue, negInfValue and nanValue
// are stored in the table.
//
// The tabulated function can then be evaluated quickly for arbitrary
// half values by calling the the halfFunction object's operator()
// method.
//
// Example:
//
// #include <math.h>
// #include <halfFunction.h>
//
// halfFunction<half> hsin (sin);
//
// halfFunction<half> hsqrt (sqrt, // function
// 0, HALF_MAX, // domain
// half::qNan(), // sqrt(x) for x < 0
// half::posInf(), // sqrt(+inf)
// half::qNan(), // sqrt(-inf)
// half::qNan()); // sqrt(nan)
//
// half x = hsin (1);
// half y = hsqrt (3.5);
//
//---------------------------------------------------------------------------
#ifndef _HALF_FUNCTION_H_
#define _HALF_FUNCTION_H_
#include <float.h>
#include "half.h"
template <class T>
class halfFunction
{
public:
//------------
// Constructor
//------------
template <class Function>
halfFunction (Function f,
half domainMin = -HALF_MAX,
half domainMax = HALF_MAX,
T defaultValue = 0,
T posInfValue = 0,
T negInfValue = 0,
T nanValue = 0);
//-----------
// Evaluation
//-----------
T operator () (half x) const;
private:
T _lut[1 << 16];
};
//---------------
// Implementation
//---------------
template <class T>
template <class Function>
halfFunction<T>::halfFunction (Function f,
half domainMin,
half domainMax,
T defaultValue,
T posInfValue,
T negInfValue,
T nanValue)
{
for (int i = 0; i < (1 << 16); i++)
{
half x;
x.setBits (i);
if (x.isNan())
_lut[i] = nanValue;
else if (x.isInfinity())
_lut[i] = x.isNegative()? negInfValue: posInfValue;
else if (x < domainMin || x > domainMax)
_lut[i] = defaultValue;
else
_lut[i] = f (x);
}
}
template <class T>
inline T
halfFunction<T>::operator () (half x) const
{
return _lut[x.bits()];
}
#endif
-102
View File
@@ -1,102 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
#ifndef INCLUDED_HALF_LIMITS_H
#define INCLUDED_HALF_LIMITS_H
//------------------------------------------------------------------------
//
// C++ standard library-style numeric_limits for class half
//
//------------------------------------------------------------------------
#include <limits>
#include "half.h"
namespace std {
template <>
class numeric_limits <half>
{
public:
static const bool is_specialized = true;
static half min () throw () {return HALF_NRM_MIN;}
static half max () throw () {return HALF_MAX;}
static const int digits = HALF_MANT_DIG;
static const int digits10 = HALF_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
static const int radix = HALF_RADIX;
static half epsilon () throw () {return HALF_EPSILON;}
static half round_error () throw () {return HALF_EPSILON / 2;}
static const int min_exponent = HALF_MIN_EXP;
static const int min_exponent10 = HALF_MIN_10_EXP;
static const int max_exponent = HALF_MAX_EXP;
static const int max_exponent10 = HALF_MAX_10_EXP;
static const bool has_infinity = true;
static const bool has_quiet_NaN = true;
static const bool has_signaling_NaN = true;
static const float_denorm_style has_denorm = denorm_present;
static const bool has_denorm_loss = false;
static half infinity () throw () {return half::posInf();}
static half quiet_NaN () throw () {return half::qNan();}
static half signaling_NaN () throw () {return half::sNan();}
static half denorm_min () throw () {return HALF_MIN;}
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = true;
static const bool tinyness_before = false;
static const float_round_style round_style = round_to_nearest;
};
} // namespace std
#endif
-164
View File
@@ -1,164 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
//
// toFloat
//
// A program to generate the lookup table for half-to-float
// conversion needed by class half.
// The program loops over all 65536 possible half numbers,
// converts each of them to a float, and prints the result.
//
//---------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
using namespace std;
//---------------------------------------------------
// Interpret an unsigned short bit pattern as a half,
// and convert that half to the corresponding float's
// bit pattern.
//---------------------------------------------------
unsigned int
halfToFloat (unsigned short y)
{
int s = (y >> 15) & 0x00000001;
int e = (y >> 10) & 0x0000001f;
int m = y & 0x000003ff;
if (e == 0)
{
if (m == 0)
{
//
// Plus or minus zero
//
return s << 31;
}
else
{
//
// Denormalized number -- renormalize it
//
while (!(m & 0x00000400))
{
m <<= 1;
e -= 1;
}
e += 1;
m &= ~0x00000400;
}
}
else if (e == 31)
{
if (m == 0)
{
//
// Positive or negative infinity
//
return (s << 31) | 0x7f800000;
}
else
{
//
// Nan -- preserve sign and significand bits
//
return (s << 31) | 0x7f800000 | (m << 13);
}
}
//
// Normalized number
//
e = e + (127 - 15);
m = m << 13;
//
// Assemble s, e and m.
//
return (s << 31) | (e << 23) | m;
}
//---------------------------------------------
// Main - prints the half-to-float lookup table
//---------------------------------------------
int
main ()
{
cout.precision (9);
cout.setf (ios_base::hex, ios_base::basefield);
cout << "//\n"
"// This is an automatically generated file.\n"
"// Do not edit.\n"
"//\n\n";
cout << "{\n ";
const int iMax = (1 << 16);
for (int i = 0; i < iMax; i++)
{
cout << "{0x" << setfill ('0') << setw (8) << halfToFloat (i) << "}, ";
if (i % 4 == 3)
{
cout << "\n";
if (i < iMax - 1)
cout << " ";
}
}
cout << "};\n";
return 0;
}
-16
View File
@@ -1,16 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
-17
View File
@@ -1,17 +0,0 @@
## Process this file with automake to produce Makefile.in
check_PROGRAMS = HalfTest
HalfTest_SOURCES = main.cpp testArithmetic.cpp testArithmetic.h \
testBitPatterns.cpp testBitPatterns.h \
testClassification.cpp testClassification.h \
testError.cpp testError.h testFunction.cpp \
testFunction.h testLimits.cpp testLimits.h testSize.cpp \
testSize.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Half -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Half -lHalf
TESTS = HalfTest
-32
View File
@@ -1,32 +0,0 @@
#include <testSize.h>
#include <testArithmetic.h>
#include <testError.h>
#include <testBitPatterns.h>
#include <testClassification.h>
#include <testLimits.h>
#include <testFunction.h>
#include <iostream>
#include <string.h>
#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x();
int
main (int argc, char *argv[])
{
std::cout << "\ntesting type half:\n\n" << std::flush;
TEST (testSize);
TEST (testArithmetic);
TEST (testNormalizedConversionError);
TEST (testDenormalizedConversionError);
TEST (testRoundingError);
TEST (testBitPatterns);
TEST (testClassification);
TEST (testLimits);
TEST (testFunction);
return 0;
}
-55
View File
@@ -1,55 +0,0 @@
#include <testArithmetic.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
void
testArithmetic ()
{
cout << "basic arithmetic operations:\n";
float f1 (1);
float f2 (2);
half h1 (3);
half h2 (4);
cout << "f1 = " << f1 << ", "
"f2 = " << f2 << ", "
"h1 = " << h1 << ", "
"h2 = " << h2 << endl;
h1 = f1 + f2;
assert (h1 == 3);
cout << "h1 = f1 + f2: " << h1 << endl;
h2 += f1;
assert (h2 == 5);
cout << "h2 += f1: " << h2 << endl;
h2 = h1 + h2;
assert (h2 == 8);
cout << "h2 = h1 + h2: " << h2 << endl;
h2 += h1;
assert (h2 == 11);
cout << "h2 += h1: " << h2 << endl;
h1 = h2;
assert (h1 == 11);
cout << "h1 = h2: " << h1 << endl;
h2 = -h1;
assert (h2 == -11);
cout << "h2 = -h1: " << h2 << endl;
cout << "ok\n\n" << flush;
}
-3
View File
@@ -1,3 +0,0 @@
void testArithmetic ();
-460
View File
@@ -1,460 +0,0 @@
#include <testBitPatterns.h>
#include "half.h"
#include <float.h>
#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;
namespace {
bool
equalBitPatterns (const char *b1, const char *b2)
{
//
// Returns true if the characters in zero-terminated string b1
// are the same as the charaters in string b2, except for places
// where b1 or b2 contains an 'X'. For example:
//
// equalBitPatterns ("100", "100") returns true
// equalBitPatterns ("100", "101") returns false
// equalBitPatterns ("10X", "101") returns true
// equalBitPatterns ("10X", "100") returns true
//
while (*b1 && *b2)
{
if (*b1 != *b2 && *b1 != 'X' && *b2 != 'X')
return false;
++b1;
++b2;
}
return !(*b1 || *b2);
}
void
testBits (float f, const char bh[19], const char bg[35])
{
half h (f);
float g (h);
cout.width (15);
cout.precision (8);
cout << f << " ";
printBits (cout, f);
cout << " ";
printBits (cout, h);
cout << '\n';
cout.width (15);
cout << g << " ";
printBits (cout, g);
cout << "\n\n";
if (bh || bg)
{
char ch[19], cg[35];
printBits (ch, h);
printBits (cg, g);
if (!equalBitPatterns (ch, bh))
{
cout << "error: expected " << bh << ", got " << ch << endl;
assert (false);
}
if (!equalBitPatterns (cg, bg))
{
cout << "error: expected " << bg << ", got " << cg << endl;
assert (false);
}
}
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testBitPatterns()
{
cout << "specific bit patterns\n\n";
//
// Numbers close to 1.0
//
testBits (1.0,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0 + HALF_EPSILON,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0 + HALF_EPSILON * 0.5,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0 + HALF_EPSILON * 0.4999,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0 + HALF_EPSILON * 0.5001,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0 - HALF_EPSILON * 0.5,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
testBits (1.0 - HALF_EPSILON * 0.5 * 0.5,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0 - HALF_EPSILON * 0.5 * 0.4999,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0 - HALF_EPSILON * 0.5 * 0.5001,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
//
// Numbers close to HALF_MIN
//
testBits (HALF_MIN,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.4999,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5001,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.4999,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5001,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
//
// Numbers close to HALF_NRM_MIN
//
testBits (HALF_NRM_MIN,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.4999,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5001,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN - HALF_MIN,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.5,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.49995,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.50005,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
//
// Small positive integers and simple decimal fractions
//
testBits (2,
"0 10000 0000000000",
"0 10000000 00000000000000000000000");
testBits (3,
"0 10000 1000000000",
"0 10000000 10000000000000000000000");
testBits (10,
"0 10010 0100000000",
"0 10000010 01000000000000000000000");
testBits (0.1,
"0 01011 1001100110",
"0 01111011 10011001100000000000000");
testBits (0.2,
"0 01100 1001100110",
"0 01111100 10011001100000000000000");
testBits (0.3,
"0 01101 0011001101",
"0 01111101 00110011010000000000000");
//
// Numbers close to HALF_MAX
//
testBits (HALF_MAX,
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * 1.0,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0 - HALF_EPSILON * 0.25),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0 - HALF_EPSILON * 0.25005),
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * (1.0 - HALF_EPSILON * 0.24995),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
//
// Large positive numbers, positive infinity and NANs
//
testBits (HALF_MAX * HALF_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (FLT_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosInfinity(),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosQNan1(),
"0 11111 1111111111", // nan
"0 11111111 11111111110000000000000"); // nan
testBits (floatPosQNan2(),
"0 11111 1010101010", // nan
"0 11111111 10101010100000000000000"); // nan
//
// Numbers close to -1.0
//
testBits (-1.0,
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0 + HALF_EPSILON),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0 + HALF_EPSILON * 0.5),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0 + HALF_EPSILON * 0.4999),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0 + HALF_EPSILON * 0.5001),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0 - HALF_EPSILON * 0.5),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
testBits (-(1.0 - HALF_EPSILON * 0.5 * 0.5),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0 - HALF_EPSILON * 0.5 * 0.4999),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0 - HALF_EPSILON * 0.5 * 0.5001),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
//
// Numbers close to -HALF_MIN
//
testBits (-HALF_MIN,
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.4999),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5001),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN),
"X 00000 0000000000",
"X 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.4999),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5001),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
//
// Numbers close to -HALF_NRM_MIN
//
testBits (-HALF_NRM_MIN,
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.4999),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5001),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.5),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.49995),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.50005),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
//
// Small negative integers and simple decimal fractions
//
testBits (-2,
"1 10000 0000000000",
"1 10000000 00000000000000000000000");
testBits (-3,
"1 10000 1000000000",
"1 10000000 10000000000000000000000");
testBits (-10,
"1 10010 0100000000",
"1 10000010 01000000000000000000000");
testBits (-0.1,
"1 01011 1001100110",
"1 01111011 10011001100000000000000");
testBits (-0.2,
"1 01100 1001100110",
"1 01111100 10011001100000000000000");
testBits (-0.3,
"1 01101 0011001101",
"1 01111101 00110011010000000000000");
//
// Numbers close to -HALF_MAX
//
testBits (-HALF_MAX,
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * 1.0,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0 - HALF_EPSILON * 0.25),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0 - HALF_EPSILON * 0.25005),
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * (1.0 - HALF_EPSILON * 0.24995),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
//
// Large negative numbers, negative infinity and NANs
//
testBits (-HALF_MAX * HALF_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-FLT_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegInfinity(),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegQNan1(),
"1 11111 1111111111", // nan
"1 11111111 11111111110000000000000"); // nan
testBits (floatNegQNan2(),
"1 11111 1010101010", // nan
"1 11111111 10101010100000000000000"); // nan
cout << "ok\n\n" << flush;
}
-3
View File
@@ -1,3 +0,0 @@
void testBitPatterns ();
-170
View File
@@ -1,170 +0,0 @@
#include <testClassification.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
void
testClass (half h,
bool finite,
bool normalized,
bool denormalized,
bool zero,
bool nan,
bool infinity,
bool negative)
{
cout.width (15);
cout.precision (8);
cout << h << " ";
printBits (cout, h);
cout << " ";
if (h.isFinite())
cout << "finite ";
if (h.isNormalized())
cout << "normalized ";
if (h.isDenormalized())
cout << "denormalized ";
if (h.isZero())
cout << "zero ";
if (h.isNan())
cout << "nan ";
if (h.isInfinity())
cout << "infinity ";
if (h.isNegative())
cout << "negative ";
cout << endl;
assert (h.isFinite() == finite);
assert (h.isNormalized() == normalized);
assert (h.isDenormalized() == denormalized);
assert (h.isZero() == zero);
assert (h.isNan() == nan);
assert (h.isInfinity() == infinity);
assert (h.isNegative() == negative);
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testClassification()
{
cout << "classification of bit patterns\n\n";
//
// fini norm deno zero nan inf neg
//
testClass (0.0, 1, 0, 0, 1, 0, 0, 0);
testClass (1.0, 1, 1, 0, 0, 0, 0, 0);
testClass (1.0 + HALF_EPSILON, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (HALF_MIN + HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (HALF_NRM_MIN, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_NRM_MIN + HALF_MIN, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_NRM_MIN - HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (2.0, 1, 1, 0, 0, 0, 0, 0);
testClass (3.0, 1, 1, 0, 0, 0, 0, 0);
testClass (0.1, 1, 1, 0, 0, 0, 0, 0);
testClass (0.2, 1, 1, 0, 0, 0, 0, 0);
testClass (0.3, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_MAX, 1, 1, 0, 0, 0, 0, 0);
testClass (floatPosInfinity(), 0, 0, 0, 0, 0, 1, 0);
testClass (floatPosQNan1(), 0, 0, 0, 0, 1, 0, 0);
testClass (floatPosQNan2(), 0, 0, 0, 0, 1, 0, 0);
testClass (-1.0, 1, 1, 0, 0, 0, 0, 1);
testClass (-1.0 - HALF_EPSILON, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_MIN, 1, 0, 1, 0, 0, 0, 1);
testClass (-HALF_MIN - HALF_MIN, 1, 0, 1, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN - HALF_MIN,1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN + HALF_MIN,1, 0, 1, 0, 0, 0, 1);
testClass (-2.0, 1, 1, 0, 0, 0, 0, 1);
testClass (-3.0, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.1, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.2, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.3, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_MAX, 1, 1, 0, 0, 0, 0, 1);
testClass (floatNegInfinity(), 0, 0, 0, 0, 0, 1, 1);
testClass (floatNegQNan1(), 0, 0, 0, 0, 1, 0, 1);
testClass (floatNegQNan2(), 0, 0, 0, 0, 1, 0, 1);
cout << "\n";
testClass (half::posInf(), 0, 0, 0, 0, 0, 1, 0);
testClass (half::negInf(), 0, 0, 0, 0, 0, 1, 1);
testClass (half::qNan(), 0, 0, 0, 0, 1, 0, 0);
testClass (half::sNan(), 0, 0, 0, 0, 1, 0, 0);
cout << "ok\n\n" << flush;
}
-3
View File
@@ -1,3 +0,0 @@
void testClassification ();
-212
View File
@@ -1,212 +0,0 @@
#include <testError.h>
#include "half.h"
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
namespace {
float
drand()
{
return static_cast<float> (rand()/(RAND_MAX+1.0f));
}
} // namespace
void
testNormalizedConversionError()
{
cout << "float-to-half conversion error for normalized half numbers\n";
float eMax = 0;
for (int i = 0; i < 20000000; i++)
{
float f (drand() * HALF_MAX);
if (f < HALF_NRM_MIN)
continue;
if (i & 1)
f = -f;
half h (f);
float e = 1.0 - h/f;
if (e < 0)
e = -e;
if (e > HALF_EPSILON * 0.5)
{
cout << "float = " << f <<
", half = " << h <<
", error = " << e << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << HALF_EPSILON * 0.5 << endl;
cout << "ok\n\n" << flush;
}
void
testDenormalizedConversionError()
{
cout << "float-to-half conversion error for denormalized half numbers\n";
float eMax = 0;
for (int i = 0; i < 20000000; i++)
{
float f (drand() * (HALF_NRM_MIN - HALF_MIN));
if (i & 1)
f = -f;
half h (f);
float e = h - f;
if (e < 0)
e = -e;
if (e > HALF_MIN * 0.5)
{
cout << "float = " << f <<
", half = " << h <<
", error = " << e << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << HALF_MIN * 0.5 << endl;
cout << "ok\n\n" << flush;
}
namespace {
void
testNormalizedRounding (int n)
{
cout << "rounding normalized numbers to " << n << "-bit precision\n";
float eExpected = (n < 10)? HALF_EPSILON * 0.5 * (1 << (10 - n)): 0;
float eMax = 0;
for (int i = 0; i < 200000; i++)
{
half h (drand() * HALF_MAX);
if (h < HALF_NRM_MIN)
continue;
if (i & 1)
h = -h;
half r (h.round(n));
float e = 1.0 - r/h;
if (e < 0)
e = -e;
if (e > eExpected)
{
cout << "half = " << h <<
", rounded = " << r <<
", error = " << e <<
", expected error = " << eExpected << endl;
printBits (cout, h);
cout << endl;
printBits (cout, r);
cout << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << eExpected << endl;
cout << "ok\n\n" << flush;
}
void
testDenormalizedRounding (int n)
{
cout << "rounding denormalized numbers to " << n << "-bit precision\n";
float eExpected = (n < 10)? HALF_MIN * 0.5 * (1 << (10 - n)): 0;
float eMax = 0;
for (int i = 0; i < 200000; i++)
{
half h (drand() * (HALF_NRM_MIN - HALF_MIN));
if (i & 1)
h = -h;
half r (h.round(n));
float e = r - h;
if (e < 0)
e = -e;
if (e > eExpected)
{
cout << "half = " << h <<
", rounded = " << r <<
", error = " << e <<
", expected error = " << eExpected << endl;
printBits (cout, h);
cout << endl;
printBits (cout, r);
cout << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << eExpected << endl;
cout << "ok\n\n" << flush;
}
} // namespace
void
testRoundingError ()
{
testNormalizedRounding (10);
testDenormalizedRounding (10);
testNormalizedRounding (9);
testDenormalizedRounding (9);
testNormalizedRounding (1);
testDenormalizedRounding (1);
testNormalizedRounding (0);
testDenormalizedRounding (0);
}
-5
View File
@@ -1,5 +0,0 @@
void testNormalizedConversionError ();
void testDenormalizedConversionError ();
void testRoundingError ();
-68
View File
@@ -1,68 +0,0 @@
#include <testFunction.h>
#include "halfFunction.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
float
divideByTwo (float x)
{
return x / 2;
}
struct timesN
{
timesN (float n): n (n) {}
float operator () (float x) {return x * n;}
float n;
};
} // namespace
void
testFunction ()
{
cout << "halfFunction<T>\n";
halfFunction <float> d2 (divideByTwo);
assert (d2 (0) == 0);
assert (d2 (2) == 1);
assert (d2 (-2) == -1);
assert (d2 (HALF_MAX) == HALF_MAX / 2);
assert (d2 (-HALF_MAX) == -HALF_MAX / 2);
assert (d2 (half::posInf()) == 0);
assert (d2 (half::negInf()) == 0);
assert (d2 (half::qNan()) == 0);
halfFunction <half> t5 (timesN (5), // function
0, HALF_MAX / 8, // domain
-1, // default value
half::posInf(), // posInfValue
half::negInf(), // negInfValue
half::qNan()); // nanValue
assert (t5 (0) == 0);
assert (t5 (2) == 10);
assert (t5 (-2) == -1);
assert (t5 (HALF_MAX) == -1);
assert (t5 (-HALF_MAX) == -1);
assert ( t5(half::posInf()).isInfinity());
assert (!t5(half::posInf()).isNegative());
assert (t5(half::negInf()).isInfinity());
assert (t5(half::negInf()).isNegative());
assert (t5(half::qNan()).isNan());
cout << "ok\n\n" << flush;
}
-3
View File
@@ -1,3 +0,0 @@
void testFunction ();
-94
View File
@@ -1,94 +0,0 @@
#include <testLimits.h>
#include "halfLimits.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
float
mypow (int x, int y)
{
bool negative = false;
if (y < 0)
{
negative = true;
y = -y;
}
float z = 1;
while (y > 0)
{
z *= x;
y -= 1;
}
if (negative)
z = 1 / z;
return z;
}
} // namespace
void
testLimits()
{
cout << "values in std::numeric_limits<half>\n";
cout << "min_exponent\n";
{
half h (mypow (2, numeric_limits<half>::min_exponent - 1));
assert (h.isNormalized());
}
{
half h (mypow (2, numeric_limits<half>::min_exponent - 2));
assert (h.isDenormalized());
}
cout << "max_exponent\n";
{
half h (mypow (2, numeric_limits<half>::max_exponent - 1));
assert (h.isNormalized());
}
{
half h (mypow (2, numeric_limits<half>::max_exponent));
assert (h.isInfinity());
}
cout << "min_exponent10\n";
{
half h (mypow (10, numeric_limits<half>::min_exponent10));
assert (h.isNormalized());
}
{
half h (mypow (10, numeric_limits<half>::min_exponent10 - 1));
assert (h.isDenormalized());
}
cout << "max_exponent10\n";
{
half h (mypow (10, numeric_limits<half>::max_exponent10));
assert (h.isNormalized());
}
{
half h (mypow (10, numeric_limits<half>::max_exponent10 + 1));
assert (h.isInfinity());
}
cout << "ok\n\n" << flush;
}
-3
View File
@@ -1,3 +0,0 @@
void testLimits ();
-27
View File
@@ -1,27 +0,0 @@
#include <testSize.h>
#include "half.h"
#include <iostream>
#include <assert.h>
#include <stddef.h>
using namespace std;
void
testSize ()
{
cout << "size and alignment\n";
half h[2];
int size = sizeof (half);
ptrdiff_t algn = (char *)&h[1] - (char *)&h[0];
cout << "sizeof (half) = " << size << endl;
cout << "alignof (half) = " << (int) algn << endl;
assert (size == 2 && algn == 2);
cout << "ok\n\n" << flush;
}
-3
View File
@@ -1,3 +0,0 @@
void testSize ();
-2
View File
@@ -1,2 +0,0 @@
See the README file for instructions on how to build IlmBase from
source.
-16
View File
@@ -1,16 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
-60
View File
@@ -1,60 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IEX_H
#define INCLUDED_IEX_H
//--------------------------------
//
// Exception handling
//
//--------------------------------
#include "IexMacros.h"
#include "IexBaseExc.h"
#include "IexMathExc.h"
#include "IexThrowErrnoExc.h"
// Note that we do not include file IexErrnoExc.h here. That file
// defines over 150 classes and significantly slows down compilation.
// If you throw ErrnoExc exceptions using the throwErrnoExc() function,
// you don't need IexErrnoExc.h. You have to include IexErrnoExc.h
// only if you want to catch specific subclasses of ErrnoExc.
#endif
-129
View File
@@ -1,129 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------
//
// Constructors and destructors for our exception base class.
//
//---------------------------------------------------------------------
#include "IexBaseExc.h"
namespace Iex {
namespace {
StackTracer currentStackTracer = 0;
} // namespace
void
setStackTracer (StackTracer stackTracer)
{
currentStackTracer = stackTracer;
}
StackTracer
stackTracer ()
{
return currentStackTracer;
}
BaseExc::BaseExc (const char* s) throw () :
std::string (s? s: ""),
_stackTrace (currentStackTracer? currentStackTracer(): "")
{
// empty
}
BaseExc::BaseExc (const std::string &s) throw () :
std::string (s),
_stackTrace (currentStackTracer? currentStackTracer(): "")
{
// empty
}
BaseExc::BaseExc (std::stringstream &s) throw () :
std::string (s.str()),
_stackTrace (currentStackTracer? currentStackTracer(): "")
{
// empty
}
BaseExc::BaseExc (const BaseExc &be) throw () :
std::string (be),
_stackTrace (be._stackTrace)
{
// empty
}
BaseExc::~BaseExc () throw ()
{
// empty
}
const char *
BaseExc::what () const throw ()
{
return c_str();
}
BaseExc &
BaseExc::assign (std::stringstream &s)
{
std::string::assign (s.str());
return *this;
}
BaseExc &
BaseExc::append (std::stringstream &s)
{
std::string::append (s.str());
return *this;
}
} // namespace Iex
-266
View File
@@ -1,266 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IEXBASEEXC_H
#define INCLUDED_IEXBASEEXC_H
//----------------------------------------------------------
//
// A general exception base class, and a few
// useful exceptions derived from the base class.
//
//----------------------------------------------------------
#include <string>
#include <exception>
#include <sstream>
namespace Iex {
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
// Tell MS VC++ to suppress exception specification warnings
#pragma warning(disable:4290)
#endif
//-------------------------------
// Our most basic exception class
//-------------------------------
class BaseExc: public std::string, public std::exception
{
public:
//----------------------------
// Constructors and destructor
//----------------------------
BaseExc (const char *s = 0) throw(); // std::string (s)
BaseExc (const std::string &s) throw(); // std::string (s)
BaseExc (std::stringstream &s) throw(); // std::string (s.str())
BaseExc (const BaseExc &be) throw();
virtual ~BaseExc () throw ();
//--------------------------------------------
// what() method -- e.what() returns e.c_str()
//--------------------------------------------
virtual const char * what () const throw ();
//--------------------------------------------------
// Convenient methods to change the exception's text
//--------------------------------------------------
BaseExc & assign (std::stringstream &s); // assign (s.str())
BaseExc & operator = (std::stringstream &s);
BaseExc & append (std::stringstream &s); // append (s.str())
BaseExc & operator += (std::stringstream &s);
//--------------------------------------------------
// These methods from the base class get obscured by
// the definitions above.
//--------------------------------------------------
BaseExc & assign (const char *s);
BaseExc & operator = (const char *s);
BaseExc & append (const char *s);
BaseExc & operator += (const char *s);
//--------------------------------------------------
// Stack trace for the point at which the exception
// was thrown. The stack trace will be an empty
// string unless a working stack-tracing routine
// has been installed (see below, setStackTracer()).
//--------------------------------------------------
const std::string & stackTrace () const;
private:
std::string _stackTrace;
};
//-----------------------------------------------------
// A macro to save typing when declararing an exception
// class derived directly or indirectly from BaseExc:
//-----------------------------------------------------
#define DEFINE_EXC(name, base) \
class name: public base \
{ \
public: \
name (const char* text=0) throw(): base (text) {} \
name (const std::string &text) throw(): base (text) {} \
name (std::stringstream &text) throw(): base (text) {} \
};
//--------------------------------------------------------
// Some exceptions which should be useful in most programs
//--------------------------------------------------------
DEFINE_EXC (ArgExc, BaseExc) // Invalid arguments to a function call
DEFINE_EXC (LogicExc, BaseExc) // General error in a program's logic,
// for example, a function was called
// in a context where the call does
// not make sense.
DEFINE_EXC (InputExc, BaseExc) // Invalid input data, e.g. from a file
DEFINE_EXC (IoExc, BaseExc) // Input or output operation failed
DEFINE_EXC (MathExc, BaseExc) // Arithmetic exception; more specific
// exceptions derived from this class
// are defined in ExcMath.h
DEFINE_EXC (ErrnoExc, BaseExc) // Base class for exceptions corresponding
// to errno values (see errno.h); more
// specific exceptions derived from this
// class are defined in ExcErrno.h
DEFINE_EXC (NoImplExc, BaseExc) // Missing method exception e.g. from a
// call to a method that is only partially
// or not at all implemented. A reminder
// to lazy software people to get back
// to work.
DEFINE_EXC (NullExc, BaseExc) // A pointer is inappropriately null.
DEFINE_EXC (TypeExc, BaseExc) // An object is an inappropriate type,
// i.e. a dynamnic_cast failed.
//----------------------------------------------------------------------
// Stack-tracing support:
//
// setStackTracer(st)
//
// installs a stack-tracing routine, st, which will be called from
// class BaseExc's constructor every time an exception derived from
// BaseExc is thrown. The stack-tracing routine should return a
// string that contains a printable representation of the program's
// current call stack. This string will be stored in the BaseExc
// object; the string is accesible via the BaseExc::stackTrace()
// method.
//
// setStackTracer(0)
//
// removes the current stack tracing routine. When an exception
// derived from BaseExc is thrown, the stack trace string stored
// in the BaseExc object will be empty.
//
// stackTracer()
//
// returns a pointer to the current stack-tracing routine, or 0
// if there is no current stack stack-tracing routine.
//
//----------------------------------------------------------------------
typedef std::string (* StackTracer) ();
void setStackTracer (StackTracer stackTracer);
StackTracer stackTracer ();
//-----------------
// Inline functions
//-----------------
inline BaseExc &
BaseExc::operator = (std::stringstream &s)
{
return assign (s);
}
inline BaseExc &
BaseExc::operator += (std::stringstream &s)
{
return append (s);
}
inline BaseExc &
BaseExc::assign (const char *s)
{
std::string::assign(s);
return *this;
}
inline BaseExc &
BaseExc::operator = (const char *s)
{
return assign(s);
}
inline BaseExc &
BaseExc::append (const char *s)
{
std::string::append(s);
return *this;
}
inline BaseExc &
BaseExc::operator += (const char *s)
{
return append(s);
}
inline const std::string &
BaseExc::stackTrace () const
{
return _stackTrace;
}
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#pragma warning(default:4290)
#endif
} // namespace Iex
#endif
-210
View File
@@ -1,210 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IEXERRNOEXC_H
#define INCLUDED_IEXERRNOEXC_H
//----------------------------------------------------------------
//
// Exceptions which correspond to "errno" error codes.
//
//----------------------------------------------------------------
#include "IexBaseExc.h"
namespace Iex {
DEFINE_EXC (EpermExc, ErrnoExc)
DEFINE_EXC (EnoentExc, ErrnoExc)
DEFINE_EXC (EsrchExc, ErrnoExc)
DEFINE_EXC (EintrExc, ErrnoExc)
DEFINE_EXC (EioExc, ErrnoExc)
DEFINE_EXC (EnxioExc, ErrnoExc)
DEFINE_EXC (E2bigExc, ErrnoExc)
DEFINE_EXC (EnoexecExc, ErrnoExc)
DEFINE_EXC (EbadfExc, ErrnoExc)
DEFINE_EXC (EchildExc, ErrnoExc)
DEFINE_EXC (EagainExc, ErrnoExc)
DEFINE_EXC (EnomemExc, ErrnoExc)
DEFINE_EXC (EaccesExc, ErrnoExc)
DEFINE_EXC (EfaultExc, ErrnoExc)
DEFINE_EXC (EnotblkExc, ErrnoExc)
DEFINE_EXC (EbusyExc, ErrnoExc)
DEFINE_EXC (EexistExc, ErrnoExc)
DEFINE_EXC (ExdevExc, ErrnoExc)
DEFINE_EXC (EnodevExc, ErrnoExc)
DEFINE_EXC (EnotdirExc, ErrnoExc)
DEFINE_EXC (EisdirExc, ErrnoExc)
DEFINE_EXC (EinvalExc, ErrnoExc)
DEFINE_EXC (EnfileExc, ErrnoExc)
DEFINE_EXC (EmfileExc, ErrnoExc)
DEFINE_EXC (EnottyExc, ErrnoExc)
DEFINE_EXC (EtxtbsyExc, ErrnoExc)
DEFINE_EXC (EfbigExc, ErrnoExc)
DEFINE_EXC (EnospcExc, ErrnoExc)
DEFINE_EXC (EspipeExc, ErrnoExc)
DEFINE_EXC (ErofsExc, ErrnoExc)
DEFINE_EXC (EmlinkExc, ErrnoExc)
DEFINE_EXC (EpipeExc, ErrnoExc)
DEFINE_EXC (EdomExc, ErrnoExc)
DEFINE_EXC (ErangeExc, ErrnoExc)
DEFINE_EXC (EnomsgExc, ErrnoExc)
DEFINE_EXC (EidrmExc, ErrnoExc)
DEFINE_EXC (EchrngExc, ErrnoExc)
DEFINE_EXC (El2nsyncExc, ErrnoExc)
DEFINE_EXC (El3hltExc, ErrnoExc)
DEFINE_EXC (El3rstExc, ErrnoExc)
DEFINE_EXC (ElnrngExc, ErrnoExc)
DEFINE_EXC (EunatchExc, ErrnoExc)
DEFINE_EXC (EnocsiExc, ErrnoExc)
DEFINE_EXC (El2hltExc, ErrnoExc)
DEFINE_EXC (EdeadlkExc, ErrnoExc)
DEFINE_EXC (EnolckExc, ErrnoExc)
DEFINE_EXC (EbadeExc, ErrnoExc)
DEFINE_EXC (EbadrExc, ErrnoExc)
DEFINE_EXC (ExfullExc, ErrnoExc)
DEFINE_EXC (EnoanoExc, ErrnoExc)
DEFINE_EXC (EbadrqcExc, ErrnoExc)
DEFINE_EXC (EbadsltExc, ErrnoExc)
DEFINE_EXC (EdeadlockExc, ErrnoExc)
DEFINE_EXC (EbfontExc, ErrnoExc)
DEFINE_EXC (EnostrExc, ErrnoExc)
DEFINE_EXC (EnodataExc, ErrnoExc)
DEFINE_EXC (EtimeExc, ErrnoExc)
DEFINE_EXC (EnosrExc, ErrnoExc)
DEFINE_EXC (EnonetExc, ErrnoExc)
DEFINE_EXC (EnopkgExc, ErrnoExc)
DEFINE_EXC (EremoteExc, ErrnoExc)
DEFINE_EXC (EnolinkExc, ErrnoExc)
DEFINE_EXC (EadvExc, ErrnoExc)
DEFINE_EXC (EsrmntExc, ErrnoExc)
DEFINE_EXC (EcommExc, ErrnoExc)
DEFINE_EXC (EprotoExc, ErrnoExc)
DEFINE_EXC (EmultihopExc, ErrnoExc)
DEFINE_EXC (EbadmsgExc, ErrnoExc)
DEFINE_EXC (EnametoolongExc, ErrnoExc)
DEFINE_EXC (EoverflowExc, ErrnoExc)
DEFINE_EXC (EnotuniqExc, ErrnoExc)
DEFINE_EXC (EbadfdExc, ErrnoExc)
DEFINE_EXC (EremchgExc, ErrnoExc)
DEFINE_EXC (ElibaccExc, ErrnoExc)
DEFINE_EXC (ElibbadExc, ErrnoExc)
DEFINE_EXC (ElibscnExc, ErrnoExc)
DEFINE_EXC (ElibmaxExc, ErrnoExc)
DEFINE_EXC (ElibexecExc, ErrnoExc)
DEFINE_EXC (EilseqExc, ErrnoExc)
DEFINE_EXC (EnosysExc, ErrnoExc)
DEFINE_EXC (EloopExc, ErrnoExc)
DEFINE_EXC (ErestartExc, ErrnoExc)
DEFINE_EXC (EstrpipeExc, ErrnoExc)
DEFINE_EXC (EnotemptyExc, ErrnoExc)
DEFINE_EXC (EusersExc, ErrnoExc)
DEFINE_EXC (EnotsockExc, ErrnoExc)
DEFINE_EXC (EdestaddrreqExc, ErrnoExc)
DEFINE_EXC (EmsgsizeExc, ErrnoExc)
DEFINE_EXC (EprototypeExc, ErrnoExc)
DEFINE_EXC (EnoprotooptExc, ErrnoExc)
DEFINE_EXC (EprotonosupportExc, ErrnoExc)
DEFINE_EXC (EsocktnosupportExc, ErrnoExc)
DEFINE_EXC (EopnotsuppExc, ErrnoExc)
DEFINE_EXC (EpfnosupportExc, ErrnoExc)
DEFINE_EXC (EafnosupportExc, ErrnoExc)
DEFINE_EXC (EaddrinuseExc, ErrnoExc)
DEFINE_EXC (EaddrnotavailExc, ErrnoExc)
DEFINE_EXC (EnetdownExc, ErrnoExc)
DEFINE_EXC (EnetunreachExc, ErrnoExc)
DEFINE_EXC (EnetresetExc, ErrnoExc)
DEFINE_EXC (EconnabortedExc, ErrnoExc)
DEFINE_EXC (EconnresetExc, ErrnoExc)
DEFINE_EXC (EnobufsExc, ErrnoExc)
DEFINE_EXC (EisconnExc, ErrnoExc)
DEFINE_EXC (EnotconnExc, ErrnoExc)
DEFINE_EXC (EshutdownExc, ErrnoExc)
DEFINE_EXC (EtoomanyrefsExc, ErrnoExc)
DEFINE_EXC (EtimedoutExc, ErrnoExc)
DEFINE_EXC (EconnrefusedExc, ErrnoExc)
DEFINE_EXC (EhostdownExc, ErrnoExc)
DEFINE_EXC (EhostunreachExc, ErrnoExc)
DEFINE_EXC (EalreadyExc, ErrnoExc)
DEFINE_EXC (EinprogressExc, ErrnoExc)
DEFINE_EXC (EstaleExc, ErrnoExc)
DEFINE_EXC (EioresidExc, ErrnoExc)
DEFINE_EXC (EucleanExc, ErrnoExc)
DEFINE_EXC (EnotnamExc, ErrnoExc)
DEFINE_EXC (EnavailExc, ErrnoExc)
DEFINE_EXC (EisnamExc, ErrnoExc)
DEFINE_EXC (EremoteioExc, ErrnoExc)
DEFINE_EXC (EinitExc, ErrnoExc)
DEFINE_EXC (EremdevExc, ErrnoExc)
DEFINE_EXC (EcanceledExc, ErrnoExc)
DEFINE_EXC (EnolimfileExc, ErrnoExc)
DEFINE_EXC (EproclimExc, ErrnoExc)
DEFINE_EXC (EdisjointExc, ErrnoExc)
DEFINE_EXC (EnologinExc, ErrnoExc)
DEFINE_EXC (EloginlimExc, ErrnoExc)
DEFINE_EXC (EgrouploopExc, ErrnoExc)
DEFINE_EXC (EnoattachExc, ErrnoExc)
DEFINE_EXC (EnotsupExc, ErrnoExc)
DEFINE_EXC (EnoattrExc, ErrnoExc)
DEFINE_EXC (EdircorruptedExc, ErrnoExc)
DEFINE_EXC (EdquotExc, ErrnoExc)
DEFINE_EXC (EnfsremoteExc, ErrnoExc)
DEFINE_EXC (EcontrollerExc, ErrnoExc)
DEFINE_EXC (EnotcontrollerExc, ErrnoExc)
DEFINE_EXC (EenqueuedExc, ErrnoExc)
DEFINE_EXC (EnotenqueuedExc, ErrnoExc)
DEFINE_EXC (EjoinedExc, ErrnoExc)
DEFINE_EXC (EnotjoinedExc, ErrnoExc)
DEFINE_EXC (EnoprocExc, ErrnoExc)
DEFINE_EXC (EmustrunExc, ErrnoExc)
DEFINE_EXC (EnotstoppedExc, ErrnoExc)
DEFINE_EXC (EclockcpuExc, ErrnoExc)
DEFINE_EXC (EinvalstateExc, ErrnoExc)
DEFINE_EXC (EnoexistExc, ErrnoExc)
DEFINE_EXC (EendofminorExc, ErrnoExc)
DEFINE_EXC (EbufsizeExc, ErrnoExc)
DEFINE_EXC (EemptyExc, ErrnoExc)
DEFINE_EXC (EnointrgroupExc, ErrnoExc)
DEFINE_EXC (EinvalmodeExc, ErrnoExc)
DEFINE_EXC (EcantextentExc, ErrnoExc)
DEFINE_EXC (EinvaltimeExc, ErrnoExc)
DEFINE_EXC (EdestroyedExc, ErrnoExc)
} // namespace Iex
#endif
-148
View File
@@ -1,148 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IEXMACROS_H
#define INCLUDED_IEXMACROS_H
//--------------------------------------------------------------------
//
// Macros which make throwing exceptions more convenient
//
//--------------------------------------------------------------------
#include <sstream>
//----------------------------------------------------------------------------
// A macro to throw exceptions whose text is assembled using stringstreams.
//
// Example:
//
// THROW (InputExc, "Syntax error in line " << line ", " << file << ".");
//
//----------------------------------------------------------------------------
#define THROW(type, text) \
do \
{ \
std::stringstream s; \
s << text; \
throw type (s); \
} \
while (0)
//----------------------------------------------------------------------------
// Macros to add to or to replace the text of an exception.
// The new text is assembled using stringstreams.
//
// Examples:
//
// Append to end of an exception's text:
//
// catch (BaseExc &e)
// {
// APPEND_EXC (e, " Directory " << name << " does not exist.");
// throw;
// }
//
// Replace an exception's text:
//
// catch (BaseExc &e)
// {
// REPLACE_EXC (e, "Directory " << name << " does not exist. " << e);
// throw;
// }
//----------------------------------------------------------------------------
#define APPEND_EXC(exc, text) \
do \
{ \
std::stringstream s; \
s << text; \
exc.append (s); \
} \
while (0)
#define REPLACE_EXC(exc, text) \
do \
{ \
std::stringstream s; \
s << text; \
exc.assign (s); \
} \
while (0)
//-------------------------------------------------------------
// A macro to throw ErrnoExc exceptions whose text is assembled
// using stringstreams:
//
// Example:
//
// THROW_ERRNO ("Cannot open file " << name << " (%T).");
//
//-------------------------------------------------------------
#define THROW_ERRNO(text) \
do \
{ \
std::stringstream s; \
s << text; \
::Iex::throwErrnoExc (s.str()); \
} \
while (0)
//-------------------------------------------------------------
// A macro to throw exceptions if an assertion is false.
//
// Example:
//
// ASSERT (NullExc, ptr != NULL, "Null pointer" );
//
//-------------------------------------------------------------
#define ASSERT(assertion, type, text) \
do \
{ \
if( (assertion) == false ) \
THROW( type, text ); \
} \
while (0)
#endif
-58
View File
@@ -1,58 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IEXMATHEXC_H
#define INCLUDED_IEXMATHEXC_H
#include "IexBaseExc.h"
namespace Iex {
//---------------------------------------------------------
// Exception classess which correspond to specific floating
// point exceptions.
//---------------------------------------------------------
DEFINE_EXC (OverflowExc, MathExc) // Overflow
DEFINE_EXC (UnderflowExc, MathExc) // Underflow
DEFINE_EXC (DivzeroExc, MathExc) // Division by zero
DEFINE_EXC (InexactExc, MathExc) // Inexact result
DEFINE_EXC (InvalidFpOpExc, MathExc) // Invalid operation
} // namespace Iex
#endif
-859
View File
@@ -1,859 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------
//
// Exceptions that correspond to "errno" error codes,
// and a function to make throwing those exceptions easy.
//
//----------------------------------------------------------------
#include "IexThrowErrnoExc.h"
#include "IexErrnoExc.h"
#include <string.h>
#include <errno.h>
namespace Iex {
void throwErrnoExc (const std::string &text, int errnum)
{
const char *entext = strerror (errnum);
std::string tmp (text);
int pos;
while (-1 != (pos = tmp.find ("%T")))
tmp.replace (pos, 2, entext, strlen (entext));
switch (errnum)
{
#if defined (EPERM)
case EPERM:
throw EpermExc (tmp);
#endif
#if defined (ENOENT)
case ENOENT:
throw EnoentExc (tmp);
#endif
#if defined (ESRCH)
case ESRCH:
throw EsrchExc (tmp);
#endif
#if defined (EINTR)
case EINTR:
throw EintrExc (tmp);
#endif
#if defined (EIO)
case EIO:
throw EioExc (tmp);
#endif
#if defined (ENXIO)
case ENXIO:
throw EnxioExc (tmp);
#endif
#if defined (E2BIG)
case E2BIG:
throw E2bigExc (tmp);
#endif
#if defined (ENOEXEC)
case ENOEXEC:
throw EnoexecExc (tmp);
#endif
#if defined (EBADF)
case EBADF:
throw EbadfExc (tmp);
#endif
#if defined (ECHILD)
case ECHILD:
throw EchildExc (tmp);
#endif
#if defined (EAGAIN)
case EAGAIN:
throw EagainExc (tmp);
#endif
#if defined (ENOMEM)
case ENOMEM:
throw EnomemExc (tmp);
#endif
#if defined (EACCES)
case EACCES:
throw EaccesExc (tmp);
#endif
#if defined (EFAULT)
case EFAULT:
throw EfaultExc (tmp);
#endif
#if defined (ENOTBLK)
case ENOTBLK:
throw EnotblkExc (tmp);
#endif
#if defined (EBUSY)
case EBUSY:
throw EbusyExc (tmp);
#endif
#if defined (EEXIST)
case EEXIST:
throw EexistExc (tmp);
#endif
#if defined (EXDEV)
case EXDEV:
throw ExdevExc (tmp);
#endif
#if defined (ENODEV)
case ENODEV:
throw EnodevExc (tmp);
#endif
#if defined (ENOTDIR)
case ENOTDIR:
throw EnotdirExc (tmp);
#endif
#if defined (EISDIR)
case EISDIR:
throw EisdirExc (tmp);
#endif
#if defined (EINVAL)
case EINVAL:
throw EinvalExc (tmp);
#endif
#if defined (ENFILE)
case ENFILE:
throw EnfileExc (tmp);
#endif
#if defined (EMFILE)
case EMFILE:
throw EmfileExc (tmp);
#endif
#if defined (ENOTTY)
case ENOTTY:
throw EnottyExc (tmp);
#endif
#if defined (ETXTBSY)
case ETXTBSY:
throw EtxtbsyExc (tmp);
#endif
#if defined (EFBIG)
case EFBIG:
throw EfbigExc (tmp);
#endif
#if defined (ENOSPC)
case ENOSPC:
throw EnospcExc (tmp);
#endif
#if defined (ESPIPE)
case ESPIPE:
throw EspipeExc (tmp);
#endif
#if defined (EROFS)
case EROFS:
throw ErofsExc (tmp);
#endif
#if defined (EMLINK)
case EMLINK:
throw EmlinkExc (tmp);
#endif
#if defined (EPIPE)
case EPIPE:
throw EpipeExc (tmp);
#endif
#if defined (EDOM)
case EDOM:
throw EdomExc (tmp);
#endif
#if defined (ERANGE)
case ERANGE:
throw ErangeExc (tmp);
#endif
#if defined (ENOMSG)
case ENOMSG:
throw EnomsgExc (tmp);
#endif
#if defined (EIDRM)
case EIDRM:
throw EidrmExc (tmp);
#endif
#if defined (ECHRNG)
case ECHRNG:
throw EchrngExc (tmp);
#endif
#if defined (EL2NSYNC)
case EL2NSYNC:
throw El2nsyncExc (tmp);
#endif
#if defined (EL3HLT)
case EL3HLT:
throw El3hltExc (tmp);
#endif
#if defined (EL3RST)
case EL3RST:
throw El3rstExc (tmp);
#endif
#if defined (ELNRNG)
case ELNRNG:
throw ElnrngExc (tmp);
#endif
#if defined (EUNATCH)
case EUNATCH:
throw EunatchExc (tmp);
#endif
#if defined (ENOSCI)
case ENOCSI:
throw EnocsiExc (tmp);
#endif
#if defined (EL2HLT)
case EL2HLT:
throw El2hltExc (tmp);
#endif
#if defined (EDEADLK)
case EDEADLK:
throw EdeadlkExc (tmp);
#endif
#if defined (ENOLCK)
case ENOLCK:
throw EnolckExc (tmp);
#endif
#if defined (EBADE)
case EBADE:
throw EbadeExc (tmp);
#endif
#if defined (EBADR)
case EBADR:
throw EbadrExc (tmp);
#endif
#if defined (EXFULL)
case EXFULL:
throw ExfullExc (tmp);
#endif
#if defined (ENOANO)
case ENOANO:
throw EnoanoExc (tmp);
#endif
#if defined (EBADRQC)
case EBADRQC:
throw EbadrqcExc (tmp);
#endif
#if defined (EBADSLT)
case EBADSLT:
throw EbadsltExc (tmp);
#endif
#if defined (EDEADLOCK) && defined (EDEADLK)
#if EDEADLOCK != EDEADLK
case EDEADLOCK:
throw EdeadlockExc (tmp);
#endif
#elif defined (EDEADLOCK)
case EDEADLOCK:
throw EdeadlockExc (tmp);
#endif
#if defined (EBFONT)
case EBFONT:
throw EbfontExc (tmp);
#endif
#if defined (ENOSTR)
case ENOSTR:
throw EnostrExc (tmp);
#endif
#if defined (ENODATA)
case ENODATA:
throw EnodataExc (tmp);
#endif
#if defined (ETIME)
case ETIME:
throw EtimeExc (tmp);
#endif
#if defined (ENOSR)
case ENOSR:
throw EnosrExc (tmp);
#endif
#if defined (ENONET)
case ENONET:
throw EnonetExc (tmp);
#endif
#if defined (ENOPKG)
case ENOPKG:
throw EnopkgExc (tmp);
#endif
#if defined (EREMOTE)
case EREMOTE:
throw EremoteExc (tmp);
#endif
#if defined (ENOLINK)
case ENOLINK:
throw EnolinkExc (tmp);
#endif
#if defined (EADV)
case EADV:
throw EadvExc (tmp);
#endif
#if defined (ESRMNT)
case ESRMNT:
throw EsrmntExc (tmp);
#endif
#if defined (ECOMM)
case ECOMM:
throw EcommExc (tmp);
#endif
#if defined (EPROTO)
case EPROTO:
throw EprotoExc (tmp);
#endif
#if defined (EMULTIHOP)
case EMULTIHOP:
throw EmultihopExc (tmp);
#endif
#if defined (EBADMSG)
case EBADMSG:
throw EbadmsgExc (tmp);
#endif
#if defined (ENAMETOOLONG)
case ENAMETOOLONG:
throw EnametoolongExc (tmp);
#endif
#if defined (EOVERFLOW)
case EOVERFLOW:
throw EoverflowExc (tmp);
#endif
#if defined (ENOTUNIQ)
case ENOTUNIQ:
throw EnotuniqExc (tmp);
#endif
#if defined (EBADFD)
case EBADFD:
throw EbadfdExc (tmp);
#endif
#if defined (EREMCHG)
case EREMCHG:
throw EremchgExc (tmp);
#endif
#if defined (ELIBACC)
case ELIBACC:
throw ElibaccExc (tmp);
#endif
#if defined (ELIBBAD)
case ELIBBAD:
throw ElibbadExc (tmp);
#endif
#if defined (ELIBSCN)
case ELIBSCN:
throw ElibscnExc (tmp);
#endif
#if defined (ELIBMAX)
case ELIBMAX:
throw ElibmaxExc (tmp);
#endif
#if defined (ELIBEXEC)
case ELIBEXEC:
throw ElibexecExc (tmp);
#endif
#if defined (EILSEQ)
case EILSEQ:
throw EilseqExc (tmp);
#endif
#if defined (ENOSYS)
case ENOSYS:
throw EnosysExc (tmp);
#endif
#if defined (ELOOP)
case ELOOP:
throw EloopExc (tmp);
#endif
#if defined (ERESTART)
case ERESTART:
throw ErestartExc (tmp);
#endif
#if defined (ESTRPIPE)
case ESTRPIPE:
throw EstrpipeExc (tmp);
#endif
#if defined (ENOTEMPTY)
case ENOTEMPTY:
throw EnotemptyExc (tmp);
#endif
#if defined (EUSERS)
case EUSERS:
throw EusersExc (tmp);
#endif
#if defined (ENOTSOCK)
case ENOTSOCK:
throw EnotsockExc (tmp);
#endif
#if defined (EDESTADDRREQ)
case EDESTADDRREQ:
throw EdestaddrreqExc (tmp);
#endif
#if defined (EMSGSIZE)
case EMSGSIZE:
throw EmsgsizeExc (tmp);
#endif
#if defined (EPROTOTYPE)
case EPROTOTYPE:
throw EprototypeExc (tmp);
#endif
#if defined (ENOPROTOOPT)
case ENOPROTOOPT:
throw EnoprotooptExc (tmp);
#endif
#if defined (EPROTONOSUPPORT)
case EPROTONOSUPPORT:
throw EprotonosupportExc (tmp);
#endif
#if defined (ESOCKTNOSUPPORT)
case ESOCKTNOSUPPORT:
throw EsocktnosupportExc (tmp);
#endif
#if defined (EOPNOTSUPP)
case EOPNOTSUPP:
throw EopnotsuppExc (tmp);
#endif
#if defined (EPFNOSUPPORT)
case EPFNOSUPPORT:
throw EpfnosupportExc (tmp);
#endif
#if defined (EAFNOSUPPORT)
case EAFNOSUPPORT:
throw EafnosupportExc (tmp);
#endif
#if defined (EADDRINUSE)
case EADDRINUSE:
throw EaddrinuseExc (tmp);
#endif
#if defined (EADDRNOTAVAIL)
case EADDRNOTAVAIL:
throw EaddrnotavailExc (tmp);
#endif
#if defined (ENETDOWN)
case ENETDOWN:
throw EnetdownExc (tmp);
#endif
#if defined (ENETUNREACH)
case ENETUNREACH:
throw EnetunreachExc (tmp);
#endif
#if defined (ENETRESET)
case ENETRESET:
throw EnetresetExc (tmp);
#endif
#if defined (ECONNABORTED)
case ECONNABORTED:
throw EconnabortedExc (tmp);
#endif
#if defined (ECONNRESET)
case ECONNRESET:
throw EconnresetExc (tmp);
#endif
#if defined (ENOBUFS)
case ENOBUFS:
throw EnobufsExc (tmp);
#endif
#if defined (EISCONN)
case EISCONN:
throw EisconnExc (tmp);
#endif
#if defined (ENOTCONN)
case ENOTCONN:
throw EnotconnExc (tmp);
#endif
#if defined (ESHUTDOWN)
case ESHUTDOWN:
throw EshutdownExc (tmp);
#endif
#if defined (ETOOMANYREFS)
case ETOOMANYREFS:
throw EtoomanyrefsExc (tmp);
#endif
#if defined (ETIMEDOUT)
case ETIMEDOUT:
throw EtimedoutExc (tmp);
#endif
#if defined (ECONNREFUSED)
case ECONNREFUSED:
throw EconnrefusedExc (tmp);
#endif
#if defined (EHOSTDOWN)
case EHOSTDOWN:
throw EhostdownExc (tmp);
#endif
#if defined (EHOSTUNREACH)
case EHOSTUNREACH:
throw EhostunreachExc (tmp);
#endif
#if defined (EALREADY)
case EALREADY:
throw EalreadyExc (tmp);
#endif
#if defined (EINPROGRESS)
case EINPROGRESS:
throw EinprogressExc (tmp);
#endif
#if defined (ESTALE)
case ESTALE:
throw EstaleExc (tmp);
#endif
#if defined (EIORESID)
case EIORESID:
throw EioresidExc (tmp);
#endif
#if defined (EUCLEAN)
case EUCLEAN:
throw EucleanExc (tmp);
#endif
#if defined (ENOTNAM)
case ENOTNAM:
throw EnotnamExc (tmp);
#endif
#if defined (ENAVAIL)
case ENAVAIL:
throw EnavailExc (tmp);
#endif
#if defined (EISNAM)
case EISNAM:
throw EisnamExc (tmp);
#endif
#if defined (EREMOTEIO)
case EREMOTEIO:
throw EremoteioExc (tmp);
#endif
#if defined (EINIT)
case EINIT:
throw EinitExc (tmp);
#endif
#if defined (EREMDEV)
case EREMDEV:
throw EremdevExc (tmp);
#endif
#if defined (ECANCELED)
case ECANCELED:
throw EcanceledExc (tmp);
#endif
#if defined (ENOLIMFILE)
case ENOLIMFILE:
throw EnolimfileExc (tmp);
#endif
#if defined (EPROCLIM)
case EPROCLIM:
throw EproclimExc (tmp);
#endif
#if defined (EDISJOINT)
case EDISJOINT:
throw EdisjointExc (tmp);
#endif
#if defined (ENOLOGIN)
case ENOLOGIN:
throw EnologinExc (tmp);
#endif
#if defined (ELOGINLIM)
case ELOGINLIM:
throw EloginlimExc (tmp);
#endif
#if defined (EGROUPLOOP)
case EGROUPLOOP:
throw EgrouploopExc (tmp);
#endif
#if defined (ENOATTACH)
case ENOATTACH:
throw EnoattachExc (tmp);
#endif
#if defined (ENOTSUP) && defined (EOPNOTSUPP)
#if ENOTSUP != EOPNOTSUPP
case ENOTSUP:
throw EnotsupExc (tmp);
#endif
#elif defined (ENOTSUP)
case ENOTSUP:
throw EnotsupExc (tmp);
#endif
#if defined (ENOATTR)
case ENOATTR:
throw EnoattrExc (tmp);
#endif
#if defined (EDIRCORRUPTED)
case EDIRCORRUPTED:
throw EdircorruptedExc (tmp);
#endif
#if defined (EDQUOT)
case EDQUOT:
throw EdquotExc (tmp);
#endif
#if defined (ENFSREMOTE)
case ENFSREMOTE:
throw EnfsremoteExc (tmp);
#endif
#if defined (ECONTROLLER)
case ECONTROLLER:
throw EcontrollerExc (tmp);
#endif
#if defined (ENOTCONTROLLER)
case ENOTCONTROLLER:
throw EnotcontrollerExc (tmp);
#endif
#if defined (EENQUEUED)
case EENQUEUED:
throw EenqueuedExc (tmp);
#endif
#if defined (ENOTENQUEUED)
case ENOTENQUEUED:
throw EnotenqueuedExc (tmp);
#endif
#if defined (EJOINED)
case EJOINED:
throw EjoinedExc (tmp);
#endif
#if defined (ENOTJOINED)
case ENOTJOINED:
throw EnotjoinedExc (tmp);
#endif
#if defined (ENOPROC)
case ENOPROC:
throw EnoprocExc (tmp);
#endif
#if defined (EMUSTRUN)
case EMUSTRUN:
throw EmustrunExc (tmp);
#endif
#if defined (ENOTSTOPPED)
case ENOTSTOPPED:
throw EnotstoppedExc (tmp);
#endif
#if defined (ECLOCKCPU)
case ECLOCKCPU:
throw EclockcpuExc (tmp);
#endif
#if defined (EINVALSTATE)
case EINVALSTATE:
throw EinvalstateExc (tmp);
#endif
#if defined (ENOEXIST)
case ENOEXIST:
throw EnoexistExc (tmp);
#endif
#if defined (EENDOFMINOR)
case EENDOFMINOR:
throw EendofminorExc (tmp);
#endif
#if defined (EBUFSIZE)
case EBUFSIZE:
throw EbufsizeExc (tmp);
#endif
#if defined (EEMPTY)
case EEMPTY:
throw EemptyExc (tmp);
#endif
#if defined (ENOINTRGROUP)
case ENOINTRGROUP:
throw EnointrgroupExc (tmp);
#endif
#if defined (EINVALMODE)
case EINVALMODE:
throw EinvalmodeExc (tmp);
#endif
#if defined (ECANTEXTENT)
case ECANTEXTENT:
throw EcantextentExc (tmp);
#endif
#if defined (EINVALTIME)
case EINVALTIME:
throw EinvaltimeExc (tmp);
#endif
#if defined (EDESTROYED)
case EDESTROYED:
throw EdestroyedExc (tmp);
#endif
}
throw ErrnoExc (tmp);
}
void throwErrnoExc (const std::string &text)
{
throwErrnoExc (text, errno);
}
} // namespace Iex
-96
View File
@@ -1,96 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IEXTHROWERRNOEXC_H
#define INCLUDED_IEXTHROWERRNOEXC_H
//----------------------------------------------------------
//
// A function which throws ExcErrno exceptions
//
//----------------------------------------------------------
#include "IexBaseExc.h"
namespace Iex {
//--------------------------------------------------------------------------
//
// Function throwErrnoExc() throws an exception which corresponds to
// error code errnum. The exception text is initialized with a copy
// of the string passed to throwErrnoExc(), where all occurrences of
// "%T" have been replaced with the output of strerror(oserror()).
//
// Example:
//
// If opening file /tmp/output failed with an ENOENT error code,
// calling
//
// throwErrnoExc ();
//
// or
//
// throwErrnoExc ("%T.");
//
// will throw an EnoentExc whose text reads
//
// No such file or directory.
//
// More detailed messages can be assembled using stringstreams:
//
// std::stringstream s;
// s << "Cannot open file " << name << " (%T).";
// throwErrnoExc (s);
//
// The resulting exception contains the following text:
//
// Cannot open file /tmp/output (No such file or directory).
//
// Alternatively, you may want to use the THROW_ERRNO macro defined
// in IexMacros.h:
//
// THROW_ERRNO ("Cannot open file " << name << " (%T).")
//
//--------------------------------------------------------------------------
void throwErrnoExc (const std::string &txt, int errnum);
void throwErrnoExc (const std::string &txt = "%T." /*, int errnum = oserror() */);
} // namespace Iex
#endif
-16
View File
@@ -1,16 +0,0 @@
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libIex.la
libIex_la_SOURCES = IexThrowErrnoExc.cpp IexBaseExc.cpp IexBaseExc.h \
IexErrnoExc.h Iex.h IexMacros.h IexMathExc.h \
IexThrowErrnoExc.h
libIex_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
libIexincludedir = $(includedir)/OpenEXR
libIexinclude_HEADERS = IexBaseExc.h IexMathExc.h IexThrowErrnoExc.h \
IexErrnoExc.h IexMacros.h Iex.h
-16
View File
@@ -1,16 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
-11
View File
@@ -1,11 +0,0 @@
## Process this file with automake to produce Makefile.in
check_PROGRAMS = IexTest
IexTest_SOURCES = main.cpp testBaseExc.cpp testBaseExc.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Iex -lIex
TESTS = IexTest
-48
View File
@@ -1,48 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#include <testBaseExc.h>
#include <string.h>
#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x();
int
main (int argc, char *argv[])
{
TEST (testBaseExc);
return 0;
}
-210
View File
@@ -1,210 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#include <testBaseExc.h>
#include "Iex.h"
#include <iostream>
#include <stdexcept>
#include <assert.h>
namespace {
void
throwArgExc ()
{
throw Iex::ArgExc ("ArgExc");
}
void
throwLogicError ()
{
throw std::logic_error("logic_error");
}
void
throwInt ()
{
throw 3;
}
void
throwNested()
{
try
{
throwArgExc();
}
catch (const Iex::ArgExc &)
{
try
{
throwInt();
}
catch (...)
{
}
throw;
}
}
void
test1 ()
{
std::cout << "1" << std::endl;
try
{
throwArgExc();
}
catch (const Iex::ArgExc &)
{
return;
}
catch (std::exception &)
{
assert (false);
}
catch (...)
{
assert (false);
}
assert (false);
}
void
test2 ()
{
std::cout << "2" << std::endl;
try
{
throwLogicError();
}
catch (const Iex::ArgExc &)
{
assert (false);
}
catch (std::exception &)
{
return;
}
catch (...)
{
assert (false);
}
assert (false);
}
void
test3 ()
{
std::cout << "3" << std::endl;
try
{
throwArgExc();
}
catch (std::exception &)
{
return;
}
catch (...)
{
assert (false);
}
assert (false);
}
void
test4 ()
{
std::cout << "4" << std::endl;
try
{
throwInt();
}
catch (const Iex::ArgExc &)
{
assert (false);
}
catch (std::exception &)
{
assert (false);
}
catch (...)
{
return;
}
assert (false);
}
void
test5()
{
std::cout << "5" << std::endl;
try
{
throwNested();
}
catch (const Iex::ArgExc &e)
{
assert (e == "ArgExc");
}
}
} // namespace
void
testBaseExc()
{
std::cout << "See if throw and catch work:" << std::endl;
test1();
test2();
test3();
test4();
test5();
std::cout << "ok\n" << std::endl;
}
-38
View File
@@ -1,38 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
void testBaseExc();
-11
View File
@@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
OpenEXR_includedir=@includedir@/OpenEXR
Name: IlmBase
Description: Base math and exception libraries
Version: @ILMBASE_VERSION@
Libs: -L${libdir} -lImath -lHalf -lIex -lIlmThread @PTHREAD_LIBS@
Cflags: @PTHREAD_CFLAGS@ -I${OpenEXR_includedir}
-16
View File
@@ -1,16 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
-80
View File
@@ -1,80 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Thread -- dummy implementation for
// platforms that do not support threading
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if !defined (_WIN32) &&!(_WIN64) && !(HAVE_PTHREAD)
#include "IlmThread.h"
#include "Iex.h"
namespace IlmThread {
bool
supportsThreads ()
{
return false;
}
Thread::Thread ()
{
throw Iex::NoImplExc ("Threads not supported on this platform.");
}
Thread::~Thread ()
{
throw Iex::NoImplExc ("Threads not supported on this platform.");
}
void
Thread::start ()
{
throw Iex::NoImplExc ("Threads not supported on this platform.");
}
} // namespace IlmThread
#endif
-141
View File
@@ -1,141 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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_ILM_THREAD_H
#define INCLUDED_ILM_THREAD_H
//-----------------------------------------------------------------------------
//
// class Thread
//
// Class Thread is a portable interface to a system-dependent thread
// primitive. In order to make a thread actually do something useful,
// you must derive a subclass from class Thread and implement the
// run() function. If the operating system supports threading then
// the run() function will be executed int a new thread.
//
// The actual creation of the thread is done by the start() routine
// which then calls the run() function. In general the start()
// routine should be called from the constructor of the derived class.
//
// The base-class thread destructor will join/destroy the thread.
//
// IMPORTANT: Due to the mechanisms that encapsulate the low-level
// threading primitives in a C++ class there is a race condition
// with code resembling the following:
//
// {
// WorkerThread myThread;
// } // myThread goes out of scope, is destroyed
// // and the thread is joined
//
// The race is between the parent thread joining the child thread
// in the destructor of myThread, and the run() function in the
// child thread. If the destructor gets executed first then run()
// will be called with an invalid "this" pointer.
//
// This issue can be fixed by using a Semaphore to keep track of
// whether the run() function has already been called. You can
// include a Semaphore member variable within your derived class
// which you post() on in the run() function, and wait() on in the
// destructor before the thread is joined. Alternatively you could
// do something like this:
//
// Semaphore runStarted;
//
// void WorkerThread::run ()
// {
// runStarted.post()
// // do some work
// ...
// }
//
// {
// WorkerThread myThread;
// runStarted.wait (); // ensure that we have started
// // the run function
// } // myThread goes out of scope, is destroyed
// // and the thread is joined
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if defined _WIN32 || defined _WIN64
#ifdef NOMINMAX
#undef NOMINMAX
#endif
#define NOMINMAX
#include <windows.h>
#include <process.h>
#elif HAVE_PTHREAD
#include <pthread.h>
#endif
namespace IlmThread {
//
// Query function to determine if the current platform supports
// threads AND this library was compiled with threading enabled.
//
bool supportsThreads ();
class Thread
{
public:
Thread ();
virtual ~Thread ();
void start ();
virtual void run () = 0;
private:
#if defined _WIN32 || defined _WIN64
HANDLE _thread;
#elif HAVE_PTHREAD
pthread_t _thread;
#endif
void operator = (const Thread& t); // not implemented
Thread (const Thread& t); // not implemented
};
} // namespace IlmThread
#endif
-59
View File
@@ -1,59 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Mutex, class Lock -- dummy implementation
// for platforms that do not support threading
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
#include "IlmThreadMutex.h"
namespace IlmThread {
Mutex::Mutex () {}
Mutex::~Mutex () {}
void Mutex::lock () const {}
void Mutex::unlock () const {}
} // namespace IlmThread
#endif
-158
View File
@@ -1,158 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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_ILM_THREAD_MUTEX_H
#define INCLUDED_ILM_THREAD_MUTEX_H
//-----------------------------------------------------------------------------
//
// class Mutex, class Lock
//
// Class Mutex is a wrapper for a system-dependent mutual exclusion
// mechanism. Actual locking and unlocking of a Mutex object must
// be performed using an instance of a Lock (defined below).
//
// Class lock provides safe locking and unlocking of mutexes even in
// the presence of C++ exceptions. Constructing a Lock object locks
// the mutex; destroying the Lock unlocks the mutex.
//
// Lock objects are not themselves thread-safe. You should never
// share a Lock object among multiple threads.
//
// Typical usage:
//
// Mutex mtx; // Create a Mutex object that is visible
// //to multiple threads
//
// ... // create some threads
//
// // Then, within each thread, construct a critical section like so:
//
// {
// Lock lock (mtx); // Lock constructor locks the mutex
// ... // do some computation on shared data
// } // leaving the block unlocks the mutex
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if defined _WIN32 || defined _WIN64
#ifdef NOMINMAX
#undef NOMINMAX
#endif
#define NOMINMAX
#include <windows.h>
#elif HAVE_PTHREAD
#include <pthread.h>
#endif
namespace IlmThread {
class Lock;
class Mutex
{
public:
Mutex ();
virtual ~Mutex ();
private:
void lock () const;
void unlock () const;
#if defined _WIN32 || defined _WIN64
mutable CRITICAL_SECTION _mutex;
#elif HAVE_PTHREAD
mutable pthread_mutex_t _mutex;
#endif
void operator = (const Mutex& M); // not implemented
Mutex (const Mutex& M); // not implemented
friend class Lock;
};
class Lock
{
public:
Lock (const Mutex& m, bool autoLock = true):
_mutex (m),
_locked (false)
{
if (autoLock)
{
_mutex.lock();
_locked = true;
}
}
~Lock ()
{
if (_locked)
_mutex.unlock();
}
void acquire ()
{
_mutex.lock();
_locked = true;
}
void release ()
{
_mutex.unlock();
_locked = false;
}
bool locked ()
{
return _locked;
}
private:
const Mutex & _mutex;
bool _locked;
};
} // namespace IlmThread
#endif
-85
View File
@@ -1,85 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Mutex -- implementation for
// platforms that support Posix threads
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if HAVE_PTHREAD
#include "IlmThreadMutex.h"
#include "Iex.h"
#include <assert.h>
namespace IlmThread {
Mutex::Mutex ()
{
if (int error = ::pthread_mutex_init (&_mutex, 0))
Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error);
}
Mutex::~Mutex ()
{
int error = ::pthread_mutex_destroy (&_mutex);
assert (error == 0);
}
void
Mutex::lock () const
{
if (int error = ::pthread_mutex_lock (&_mutex))
Iex::throwErrnoExc ("Cannot lock mutex (%T).", error);
}
void
Mutex::unlock () const
{
if (int error = ::pthread_mutex_unlock (&_mutex))
Iex::throwErrnoExc ("Cannot unlock mutex (%T).", error);
}
} // namespace IlmThread
#endif
-73
View File
@@ -1,73 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Mutex -- implementation for Windows
//
//-----------------------------------------------------------------------------
#include "IlmThreadMutex.h"
#include "Iex.h"
namespace IlmThread {
Mutex::Mutex ()
{
::InitializeCriticalSection (&_mutex);
}
Mutex::~Mutex ()
{
::DeleteCriticalSection (&_mutex);
}
void
Mutex::lock () const
{
::EnterCriticalSection (&_mutex);
}
void
Mutex::unlock () const
{
::LeaveCriticalSection (&_mutex);
}
} // namespace IlmThread
-456
View File
@@ -1,456 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Task, class ThreadPool, class TaskGroup
//
//-----------------------------------------------------------------------------
#include "IlmThread.h"
#include "IlmThreadMutex.h"
#include "IlmThreadSemaphore.h"
#include "IlmThreadPool.h"
#include "Iex.h"
#include <list>
using namespace std;
namespace IlmThread {
namespace {
class WorkerThread: public Thread
{
public:
WorkerThread (ThreadPool::Data* data);
virtual void run ();
private:
ThreadPool::Data * _data;
};
} //namespace
struct TaskGroup::Data
{
Data ();
~Data ();
void addTask () ;
void removeTask ();
Semaphore isEmpty; // used to signal that the taskgroup is empty
int numPending; // number of pending tasks to still execute
};
struct ThreadPool::Data
{
Data ();
~Data();
void finish ();
bool stopped () const;
void stop ();
Semaphore taskSemaphore; // threads wait on this for ready tasks
Mutex taskMutex; // mutual exclusion for the tasks list
list<Task*> tasks; // the list of tasks to execute
size_t numTasks; // fast access to list size
// (list::size() can be O(n))
Semaphore threadSemaphore; // signaled when a thread starts executing
Mutex threadMutex; // mutual exclusion for threads list
list<WorkerThread*> threads; // the list of all threads
size_t numThreads; // fast access to list size
bool stopping; // flag indicating whether to stop threads
Mutex stopMutex; // mutual exclusion for stopping flag
};
//
// The global thread pool
//
ThreadPool gThreadPool (0);
//
// class WorkerThread
//
WorkerThread::WorkerThread (ThreadPool::Data* data):
_data (data)
{
start();
}
void
WorkerThread::run ()
{
//
// Signal that the thread has started executing
//
_data->threadSemaphore.post();
while (true)
{
//
// Wait for a task to become available
//
_data->taskSemaphore.wait();
{
Lock taskLock (_data->taskMutex);
//
// If there is a task pending, pop off the next task in the FIFO
//
if (_data->numTasks > 0)
{
Task* task = _data->tasks.front();
TaskGroup* taskGroup = task->group();
_data->tasks.pop_front();
_data->numTasks--;
taskLock.release();
task->execute();
taskLock.acquire();
delete task;
taskGroup->_data->removeTask();
}
else if (_data->stopped())
{
break;
}
}
}
}
//
// struct TaskGroup::Data
//
TaskGroup::Data::Data (): isEmpty (1), numPending (0)
{
// empty
}
TaskGroup::Data::~Data ()
{
//
// A TaskGroup acts like an "inverted" semaphore: if the count
// is above 0 then waiting on the taskgroup will block. This
// destructor waits until the taskgroup is empty before returning.
//
isEmpty.wait ();
}
void
TaskGroup::Data::addTask ()
{
//
// Any access to the taskgroup is protected by a mutex that is
// held by the threadpool. Therefore it is safe to access
// numPending before we wait on the semaphore.
//
if (numPending++ == 0)
isEmpty.wait ();
}
void
TaskGroup::Data::removeTask ()
{
if (--numPending == 0)
isEmpty.post ();
}
//
// struct ThreadPool::Data
//
ThreadPool::Data::Data (): numTasks (0), numThreads (0), stopping (false)
{
// empty
}
ThreadPool::Data::~Data()
{
Lock lock (threadMutex);
finish ();
}
void
ThreadPool::Data::finish ()
{
stop();
//
// Signal enough times to allow all threads to stop.
//
// Wait until all threads have started their run functions.
// If we do not wait before we destroy the threads then it's
// possible that the threads have not yet called their run
// functions.
// If this happens then the run function will be called off
// of an invalid object and we will crash, most likely with
// an error like: "pure virtual method called"
//
for (int i = 0; i < numThreads; i++)
{
taskSemaphore.post();
threadSemaphore.wait();
}
//
// Join all the threads
//
for (list<WorkerThread*>::iterator i = threads.begin();
i != threads.end();
++i)
{
delete (*i);
}
Lock lock1 (taskMutex);
Lock lock2 (stopMutex);
threads.clear();
tasks.clear();
numThreads = 0;
numTasks = 0;
stopping = false;
}
bool
ThreadPool::Data::stopped () const
{
Lock lock (stopMutex);
return stopping;
}
void
ThreadPool::Data::stop ()
{
Lock lock (stopMutex);
stopping = true;
}
//
// class Task
//
Task::Task (TaskGroup* g): _group(g)
{
// empty
}
Task::~Task()
{
// empty
}
TaskGroup*
Task::group ()
{
return _group;
}
TaskGroup::TaskGroup ():
_data (new Data())
{
// empty
}
TaskGroup::~TaskGroup ()
{
delete _data;
}
//
// class ThreadPool
//
ThreadPool::ThreadPool (unsigned nthreads):
_data (new Data())
{
setNumThreads (nthreads);
}
ThreadPool::~ThreadPool ()
{
delete _data;
}
int
ThreadPool::numThreads () const
{
Lock lock (_data->threadMutex);
return _data->numThreads;
}
void
ThreadPool::setNumThreads (int count)
{
if (count < 0)
throw Iex::ArgExc ("Attempt to set the number of threads "
"in a thread pool to a negative value.");
//
// Lock access to thread list and size
//
Lock lock (_data->threadMutex);
if (count > _data->numThreads)
{
//
// Add more threads
//
while (_data->numThreads < count)
{
_data->threads.push_back (new WorkerThread (_data));
_data->numThreads++;
}
}
else if (count < _data->numThreads)
{
//
// Wait until all existing threads are finished processing,
// then delete all threads.
//
_data->finish ();
//
// Add in new threads
//
while (_data->numThreads < count)
{
_data->threads.push_back (new WorkerThread (_data));
_data->numThreads++;
}
}
}
void
ThreadPool::addTask (Task* task)
{
//
// Lock the threads, needed to access numThreads
//
Lock lock (_data->threadMutex);
if (_data->numThreads == 0)
{
task->execute ();
delete task;
}
else
{
//
// Get exclusive access to the tasks queue
//
{
Lock taskLock (_data->taskMutex);
//
// Push the new task into the FIFO
//
_data->tasks.push_back (task);
_data->numTasks++;
task->group()->_data->addTask();
}
//
// Signal that we have a new task to process
//
_data->taskSemaphore.post ();
}
}
ThreadPool&
ThreadPool::globalThreadPool ()
{
return gThreadPool;
}
void
ThreadPool::addGlobalTask (Task* task)
{
gThreadPool.addTask (task);
}
} // namespace IlmThread
-156
View File
@@ -1,156 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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_ILM_THREAD_POOL_H
#define INCLUDED_ILM_THREAD_POOL_H
//-----------------------------------------------------------------------------
//
// class Task, class ThreadPool, class TaskGroup
//
// Class ThreadPool manages a set of worker threads and accepts
// tasks for processing. Tasks added to the thread pool are
// executed concurrently by the worker threads.
//
// Class Thread provides an abstract interface for a task which
// a ThreadPool works on. Derived classes need to implement the
// execute() function which performs the actual task.
//
// Class TaskTroup allows synchronization on the completion of a set
// of tasks. Every task that is added to a ThreadPool belongs to a
// single TaskGroup. The destructor of the TaskGroup waits for all
// tasks in the group to finish.
//
// Note: if you plan to use the ThreadPool interface in your own
// applications note that the implementation of the ThreadPool calls
// opertor delete on tasks as they complete. If you define a custom
// operator new for your tasks, for instance to use a custom heap,
// then you must also write an appropriate operator delete.
//
//-----------------------------------------------------------------------------
namespace IlmThread {
class TaskGroup;
class Task;
class ThreadPool
{
public:
//-------------------------------------------------------
// Constructor -- creates numThreads worker threads which
// wait until a task is available.
//-------------------------------------------------------
ThreadPool (unsigned numThreads = 0);
//-----------------------------------------------------------
// Destructor -- waits for all tasks to complete, joins all
// the threads to the calling thread, and then destroys them.
//-----------------------------------------------------------
virtual ~ThreadPool ();
//--------------------------------------------------------
// Query and set the number of worker threads in the pool.
//
// Warning: never call setNumThreads from within a worker
// thread as this will almost certainly cause a deadlock
// or crash.
//--------------------------------------------------------
int numThreads () const;
void setNumThreads (int count);
//------------------------------------------------------------
// Add a task for processing. The ThreadPool can handle any
// number of tasks regardless of the number of worker threads.
// The tasks are first added onto a queue, and are executed
// by threads as they become available, in FIFO order.
//------------------------------------------------------------
void addTask (Task* task);
//-------------------------------------------
// Access functions for the global threadpool
//-------------------------------------------
static ThreadPool& globalThreadPool ();
static void addGlobalTask (Task* task);
struct Data;
protected:
Data * _data;
};
class Task
{
public:
Task (TaskGroup* g);
virtual ~Task ();
virtual void execute () = 0;
TaskGroup * group();
protected:
TaskGroup * _group;
};
class TaskGroup
{
public:
TaskGroup();
~TaskGroup();
struct Data;
Data* const _data;
};
} // namespace IlmThread
#endif
-98
View File
@@ -1,98 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Thread -- implementation for
// platforms that support Posix threads
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if HAVE_PTHREAD
#include "IlmThread.h"
#include "Iex.h"
#include <assert.h>
extern "C"
{
typedef void * (* Start) (void *);
}
namespace IlmThread {
bool
supportsThreads ()
{
return true;
}
namespace {
void
threadLoop (void * t)
{
return (reinterpret_cast<Thread*>(t))->run();
}
} // namespace
Thread::Thread ()
{
// empty
}
Thread::~Thread ()
{
int error = ::pthread_join (_thread, 0);
assert (error == 0);
}
void
Thread::start ()
{
if (int error = ::pthread_create (&_thread, 0, Start (threadLoop), this))
Iex::throwErrnoExc ("Cannot create new thread (%T).", error);
}
} // namespace IlmThread
#endif
-60
View File
@@ -1,60 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- dummy implementation for
// for platforms that do not support threading
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
#include "IlmThreadSemaphore.h"
namespace IlmThread {
Semaphore::Semaphore (unsigned int value) {}
Semaphore::~Semaphore () {}
void Semaphore::wait () {}
bool Semaphore::tryWait () {return true;}
void Semaphore::post () {}
int Semaphore::value () const {return 0;}
} // namespace IlmThread
#endif
-110
View File
@@ -1,110 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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_ILM_THREAD_SEMAPHORE_H
#define INCLUDED_ILM_THREAD_SEMAPHORE_H
//-----------------------------------------------------------------------------
//
// class Semaphore -- a wrapper class for
// system-dependent counting semaphores
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if defined _WIN32 || defined _WIN64
#ifdef NOMINMAX
#undef NOMINMAX
#endif
#define NOMINMAX
#include <windows.h>
#elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
#include <pthread.h>
#elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
#include <semaphore.h>
#endif
namespace IlmThread {
class Semaphore
{
public:
Semaphore (unsigned int value = 0);
virtual ~Semaphore();
void wait();
bool tryWait();
void post();
int value() const;
private:
#if defined _WIN32 || defined _WIN64
mutable HANDLE _semaphore;
#elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
//
// If the platform has Posix threads but no semapohores,
// then we implement them ourselves using condition variables
//
struct sema_t
{
unsigned int count;
unsigned long numWaiting;
pthread_mutex_t mutex;
pthread_cond_t nonZero;
};
mutable sema_t _semaphore;
#elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
mutable sem_t _semaphore;
#endif
void operator = (const Semaphore& s); // not implemented
Semaphore (const Semaphore& s); // not implemented
};
} // namespace IlmThread
#endif
@@ -1,103 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- implementation for platforms
// that support Posix threads and Posix semaphores
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <assert.h>
namespace IlmThread {
Semaphore::Semaphore (unsigned int value)
{
if (::sem_init (&_semaphore, 0, value))
Iex::throwErrnoExc ("Cannot initialize semaphore (%T).");
}
Semaphore::~Semaphore ()
{
int error = ::sem_destroy (&_semaphore);
assert (error == 0);
}
void
Semaphore::wait ()
{
::sem_wait (&_semaphore);
}
bool
Semaphore::tryWait ()
{
return sem_trywait (&_semaphore) == 0;
}
void
Semaphore::post ()
{
if (::sem_post (&_semaphore))
Iex::throwErrnoExc ("Post operation on semaphore failed (%T).");
}
int
Semaphore::value () const
{
int value;
if (::sem_getvalue (&_semaphore, &value))
Iex::throwErrnoExc ("Cannot read semaphore value (%T).");
return value;
}
} // namespace IlmThread
#endif
@@ -1,155 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- implementation for for platforms that do
// support Posix threads but do not support Posix semaphores,
// for example, OS X
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <assert.h>
namespace IlmThread {
Semaphore::Semaphore (unsigned int value)
{
if (int error = ::pthread_mutex_init (&_semaphore.mutex, 0))
Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error);
if (int error = ::pthread_cond_init (&_semaphore.nonZero, 0))
Iex::throwErrnoExc ("Cannot initialize condition variable (%T).",
error);
_semaphore.count = value;
_semaphore.numWaiting = 0;
}
Semaphore::~Semaphore ()
{
int error = ::pthread_cond_destroy (&_semaphore.nonZero);
assert (error == 0);
error = ::pthread_mutex_destroy (&_semaphore.mutex);
assert (error == 0);
}
void
Semaphore::wait ()
{
::pthread_mutex_lock (&_semaphore.mutex);
_semaphore.numWaiting++;
while (_semaphore.count == 0)
{
if (int error = ::pthread_cond_wait (&_semaphore.nonZero,
&_semaphore.mutex))
{
::pthread_mutex_unlock (&_semaphore.mutex);
Iex::throwErrnoExc ("Cannot wait on condition variable (%T).",
error);
}
}
_semaphore.numWaiting--;
_semaphore.count--;
::pthread_mutex_unlock (&_semaphore.mutex);
}
bool
Semaphore::tryWait ()
{
::pthread_mutex_lock (&_semaphore.mutex);
if (_semaphore.count == 0)
{
::pthread_mutex_unlock (&_semaphore.mutex);
return false;
}
else
{
_semaphore.count--;
::pthread_mutex_unlock (&_semaphore.mutex);
return true;
}
}
void
Semaphore::post ()
{
::pthread_mutex_lock (&_semaphore.mutex);
if (_semaphore.numWaiting > 0)
{
if (int error = ::pthread_cond_signal (&_semaphore.nonZero))
{
::pthread_mutex_unlock (&_semaphore.mutex);
Iex::throwErrnoExc ("Cannot signal condition variable (%T).",
error);
}
}
_semaphore.count++;
::pthread_mutex_unlock (&_semaphore.mutex);
}
int
Semaphore::value () const
{
::pthread_mutex_lock (&_semaphore.mutex);
int value = _semaphore.count;
::pthread_mutex_unlock (&_semaphore.mutex);
return value;
}
} // namespace IlmThread
#endif
@@ -1,146 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- implementation for Windows
//
//-----------------------------------------------------------------------------
#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <string>
#include <assert.h>
#include <iostream>
namespace IlmThread {
using namespace Iex;
namespace {
std::string
errorString ()
{
LPSTR messageBuffer;
DWORD bufferLength;
std::string message;
//
// Call FormatMessage() to allow for message
// text to be acquired from the system.
//
if (bufferLength = FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
0,
GetLastError (),
MAKELANGID (LANG_NEUTRAL,
SUBLANG_DEFAULT),
(LPSTR) &messageBuffer,
0,
NULL))
{
message = messageBuffer;
LocalFree (messageBuffer);
}
return message;
}
} // namespace
Semaphore::Semaphore (unsigned int value)
{
if ((_semaphore = ::CreateSemaphore (0, value, 0x7fffffff, 0)) == 0)
{
THROW (LogicExc, "Could not create semaphore "
"(" << errorString() << ").");
}
}
Semaphore::~Semaphore()
{
bool ok = ::CloseHandle (_semaphore);
assert (ok);
}
void
Semaphore::wait()
{
if (::WaitForSingleObject (_semaphore, INFINITE) != WAIT_OBJECT_0)
{
THROW (LogicExc, "Could not wait on semaphore "
"(" << errorString() << ").");
}
}
bool
Semaphore::tryWait()
{
return ::WaitForSingleObject (_semaphore, 0) == WAIT_OBJECT_0;
}
void
Semaphore::post()
{
if (!::ReleaseSemaphore (_semaphore, 1, 0))
{
THROW (LogicExc, "Could not post on semaphore "
"(" << errorString() << ").");
}
}
int
Semaphore::value() const
{
LONG v = -1;
if (!::ReleaseSemaphore (_semaphore, 0, &v) || v < 0)
{
THROW (LogicExc, "Could not get value of semaphore "
"(" << errorString () << ").");
}
return v;
}
} // namespace IlmThread
-95
View File
@@ -1,95 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005, 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Thread -- implementation for Windows
//
//-----------------------------------------------------------------------------
#include "IlmThread.h"
#include "Iex.h"
#include <iostream>
#include <assert.h>
namespace IlmThread {
bool
supportsThreads ()
{
return true;
}
namespace {
unsigned __stdcall
threadLoop (void * t)
{
reinterpret_cast<Thread*>(t)->run();
_endthreadex (0);
return 0;
}
} // namespace
Thread::Thread ()
{
// empty
}
Thread::~Thread ()
{
DWORD status = ::WaitForSingleObject (_thread, INFINITE);
assert (status == WAIT_OBJECT_0);
bool ok = ::CloseHandle (_thread);
assert (ok);
}
void
Thread::start ()
{
unsigned id;
_thread = (HANDLE)::_beginthreadex (0, 0, &threadLoop, this, 0, &id);
if (_thread == 0)
Iex::throwErrnoExc ("Cannot create new thread (%T).");
}
} // namespace IlmThread
-26
View File
@@ -1,26 +0,0 @@
## Process this file with automake to produce Makefile.in
lib_LTLIBRARIES = libIlmThread.la
libIlmThread_la_SOURCES = IlmThreadPool.h IlmThread.h \
IlmThreadSemaphore.h IlmThreadMutex.h \
IlmThreadPool.cpp IlmThread.cpp \
IlmThreadSemaphore.cpp IlmThreadMutex.cpp \
IlmThreadPosix.cpp IlmThreadSemaphorePosix.cpp \
IlmThreadSemaphorePosixCompat.cpp \
IlmThreadMutexPosix.cpp
libIlmThread_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
libIlmThread_la_LIBADD = ../Iex/libIex.la
libIlmThreadincludedir = $(includedir)/OpenEXR
libIlmThreadinclude_HEADERS = IlmThreadPool.h IlmThread.h \
IlmThreadSemaphore.h IlmThreadMutex.h
noinst_HEADERS =
EXTRA_DIST = $(noinst_HEADERS) IlmThreadMutexWin32.cpp IlmThreadSemaphoreWin32.cpp \
IlmThreadWin32.cpp
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
-16
View File
@@ -1,16 +0,0 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
-37
View File
@@ -1,37 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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
-277
View File
@@ -1,277 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#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"
namespace Imath {
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);
//---------------------------------------------------
// 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;
};
//--------------------
// 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& minV, const T& maxV)
{
min = minV;
max = maxV;
}
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>::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>::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;
}
} // namespace Imath
#endif
-611
View File
@@ -1,611 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHBOXALGO_H
#define INCLUDED_IMATHBOXALGO_H
//---------------------------------------------------------------------------
//
// This file contains algorithms applied to or in conjunction
// with bounding boxes (Imath::Box). These algorithms require
// more headers to compile. The assumption made is that these
// functions are called much less often than the basic box
// functions or these functions require more support classes.
//
// Contains:
//
// T clip<T>(const T& in, const Box<T>& box)
//
// Vec3<T> closestPointOnBox(const Vec3<T>&, const Box<Vec3<T>>& )
//
// Vec3<T> closestPointInBox(const Vec3<T>&, const Box<Vec3<T>>& )
//
// void transform(Box<Vec3<T>>&, const Matrix44<T>&)
//
// bool findEntryAndExitPoints(const Line<T> &line,
// const Box< Vec3<T> > &box,
// Vec3<T> &enterPoint,
// Vec3<T> &exitPoint)
//
// bool intersects(const Box<Vec3<T>> &box,
// const Line3<T> &line,
// Vec3<T> result)
//
// bool intersects(const Box<Vec3<T>> &box, const Line3<T> &line)
//
//---------------------------------------------------------------------------
#include "ImathBox.h"
#include "ImathMatrix.h"
#include "ImathLineAlgo.h"
#include "ImathPlane.h"
namespace Imath {
template <class T>
inline T clip(const T& in, const Box<T>& box)
{
//
// Clip a point so that it lies inside the given bbox
//
T out;
for (int i=0; i<(int)box.min.dimensions(); i++)
{
if (in[i] < box.min[i]) out[i] = box.min[i];
else if (in[i] > box.max[i]) out[i] = box.max[i];
else out[i] = in[i];
}
return out;
}
//
// Return p if p is inside the box.
//
template <class T>
Vec3<T>
closestPointInBox(const Vec3<T>& p, const Box< Vec3<T> >& box )
{
Imath::V3f b;
if (p.x < box.min.x)
b.x = box.min.x;
else if (p.x > box.max.x)
b.x = box.max.x;
else
b.x = p.x;
if (p.y < box.min.y)
b.y = box.min.y;
else if (p.y > box.max.y)
b.y = box.max.y;
else
b.y = p.y;
if (p.z < box.min.z)
b.z = box.min.z;
else if (p.z > box.max.z)
b.z = box.max.z;
else
b.z = p.z;
return b;
}
template <class T>
Vec3<T> closestPointOnBox(const Vec3<T>& pt, const Box< Vec3<T> >& box )
{
//
// This sucker is specialized to work with a Vec3f and a box
// made of Vec3fs.
//
Vec3<T> result;
// trivial cases first
if (box.isEmpty())
return pt;
else if (pt == box.center())
{
// middle of z side
result[0] = (box.max[0] + box.min[0])/2.0;
result[1] = (box.max[1] + box.min[1])/2.0;
result[2] = box.max[2];
}
else
{
// Find the closest point on a unit box (from -1 to 1),
// then scale up.
// Find the vector from center to the point, then scale
// to a unit box.
Vec3<T> vec = pt - box.center();
T sizeX = box.max[0]-box.min[0];
T sizeY = box.max[1]-box.min[1];
T sizeZ = box.max[2]-box.min[2];
T halfX = sizeX/2.0;
T halfY = sizeY/2.0;
T halfZ = sizeZ/2.0;
if (halfX > 0.0)
vec[0] /= halfX;
if (halfY > 0.0)
vec[1] /= halfY;
if (halfZ > 0.0)
vec[2] /= halfZ;
// Side to snap side that has greatest magnitude in the vector.
Vec3<T> mag;
mag[0] = fabs(vec[0]);
mag[1] = fabs(vec[1]);
mag[2] = fabs(vec[2]);
result = mag;
// Check if beyond corners
if (result[0] > 1.0)
result[0] = 1.0;
if (result[1] > 1.0)
result[1] = 1.0;
if (result[2] > 1.0)
result[2] = 1.0;
// snap to appropriate side
if ((mag[0] > mag[1]) && (mag[0] > mag[2]))
{
result[0] = 1.0;
}
else if ((mag[1] > mag[0]) && (mag[1] > mag[2]))
{
result[1] = 1.0;
}
else if ((mag[2] > mag[0]) && (mag[2] > mag[1]))
{
result[2] = 1.0;
}
else if ((mag[0] == mag[1]) && (mag[0] == mag[2]))
{
// corner
result = Vec3<T>(1,1,1);
}
else if (mag[0] == mag[1])
{
// edge parallel with z
result[0] = 1.0;
result[1] = 1.0;
}
else if (mag[0] == mag[2])
{
// edge parallel with y
result[0] = 1.0;
result[2] = 1.0;
}
else if (mag[1] == mag[2])
{
// edge parallel with x
result[1] = 1.0;
result[2] = 1.0;
}
// Now make everything point the right way
for (int i=0; i < 3; i++)
{
if (vec[i] < 0.0)
result[i] = -result[i];
}
// scale back up and move to center
result[0] *= halfX;
result[1] *= halfY;
result[2] *= halfZ;
result += box.center();
}
return result;
}
template <class S, class T>
Box< Vec3<S> >
transform(const Box< Vec3<S> >& box, const Matrix44<T>& m)
{
// Transforms Box3f by matrix, enlarging Box3f to contain result.
// Clever method courtesy of Graphics Gems, pp. 548-550
//
// This works for projection matrices as well as simple affine
// transformations. Coordinates of the box are rehomogenized if there
// is a projection matrix
// a transformed empty box is still empty
if (box.isEmpty())
return box;
// If the last column is close enuf to ( 0 0 0 1 ) then we use the
// fast, affine version. The tricky affine method could maybe be
// extended to deal with the projection case as well, but its not
// worth it right now.
if (m[0][3] * m[0][3] + m[1][3] * m[1][3] + m[2][3] * m[2][3]
+ (1.0 - m[3][3]) * (1.0 - m[3][3]) < 0.00001)
{
// Affine version, use the Graphics Gems hack
int i, j;
Box< Vec3<S> > newBox;
for (i = 0; i < 3; i++)
{
newBox.min[i] = newBox.max[i] = (S) m[3][i];
for (j = 0; j < 3; j++)
{
float a, b;
a = (S) m[j][i] * box.min[j];
b = (S) m[j][i] * box.max[j];
if (a < b)
{
newBox.min[i] += a;
newBox.max[i] += b;
}
else
{
newBox.min[i] += b;
newBox.max[i] += a;
}
}
}
return newBox;
}
// This is a projection matrix. Do things the naive way.
Vec3<S> points[8];
/* Set up the eight points at the corners of the extent */
points[0][0] = points[1][0] = points[2][0] = points[3][0] = box.min[0];
points[4][0] = points[5][0] = points[6][0] = points[7][0] = box.max[0];
points[0][1] = points[1][1] = points[4][1] = points[5][1] = box.min[1];
points[2][1] = points[3][1] = points[6][1] = points[7][1] = box.max[1];
points[0][2] = points[2][2] = points[4][2] = points[6][2] = box.min[2];
points[1][2] = points[3][2] = points[5][2] = points[7][2] = box.max[2];
Box< Vec3<S> > newBox;
for (int i = 0; i < 8; i++)
newBox.extendBy(points[i] * m);
return newBox;
}
template <class T>
Box< Vec3<T> >
affineTransform(const Box< Vec3<T> > &bbox, const Matrix44<T> &M)
{
float min0, max0, min1, max1, min2, max2, a, b;
float min0new, max0new, min1new, max1new, min2new, max2new;
min0 = bbox.min[0];
max0 = bbox.max[0];
min1 = bbox.min[1];
max1 = bbox.max[1];
min2 = bbox.min[2];
max2 = bbox.max[2];
min0new = max0new = M[3][0];
a = M[0][0] * min0;
b = M[0][0] * max0;
if (a < b) {
min0new += a;
max0new += b;
} else {
min0new += b;
max0new += a;
}
a = M[1][0] * min1;
b = M[1][0] * max1;
if (a < b) {
min0new += a;
max0new += b;
} else {
min0new += b;
max0new += a;
}
a = M[2][0] * min2;
b = M[2][0] * max2;
if (a < b) {
min0new += a;
max0new += b;
} else {
min0new += b;
max0new += a;
}
min1new = max1new = M[3][1];
a = M[0][1] * min0;
b = M[0][1] * max0;
if (a < b) {
min1new += a;
max1new += b;
} else {
min1new += b;
max1new += a;
}
a = M[1][1] * min1;
b = M[1][1] * max1;
if (a < b) {
min1new += a;
max1new += b;
} else {
min1new += b;
max1new += a;
}
a = M[2][1] * min2;
b = M[2][1] * max2;
if (a < b) {
min1new += a;
max1new += b;
} else {
min1new += b;
max1new += a;
}
min2new = max2new = M[3][2];
a = M[0][2] * min0;
b = M[0][2] * max0;
if (a < b) {
min2new += a;
max2new += b;
} else {
min2new += b;
max2new += a;
}
a = M[1][2] * min1;
b = M[1][2] * max1;
if (a < b) {
min2new += a;
max2new += b;
} else {
min2new += b;
max2new += a;
}
a = M[2][2] * min2;
b = M[2][2] * max2;
if (a < b) {
min2new += a;
max2new += b;
} else {
min2new += b;
max2new += a;
}
Box< Vec3<T> > xbbox;
xbbox.min[0] = min0new;
xbbox.max[0] = max0new;
xbbox.min[1] = min1new;
xbbox.max[1] = max1new;
xbbox.min[2] = min2new;
xbbox.max[2] = max2new;
return xbbox;
}
template <class T>
bool findEntryAndExitPoints(const Line3<T>& line,
const Box<Vec3<T> >& box,
Vec3<T> &enterPoint,
Vec3<T> &exitPoint)
{
if ( box.isEmpty() ) return false;
if ( line.distanceTo(box.center()) > box.size().length()/2. ) return false;
Vec3<T> points[8], inter, bary;
Plane3<T> plane;
int i, v0, v1, v2;
bool front = false, valid, validIntersection = false;
// set up the eight coords of the corners of the box
for(i = 0; i < 8; i++)
{
points[i].setValue( i & 01 ? box.min[0] : box.max[0],
i & 02 ? box.min[1] : box.max[1],
i & 04 ? box.min[2] : box.max[2]);
}
// intersect the 12 triangles.
for(i = 0; i < 12; i++)
{
switch(i)
{
case 0: v0 = 2; v1 = 1; v2 = 0; break; // +z
case 1: v0 = 2; v1 = 3; v2 = 1; break;
case 2: v0 = 4; v1 = 5; v2 = 6; break; // -z
case 3: v0 = 6; v1 = 5; v2 = 7; break;
case 4: v0 = 0; v1 = 6; v2 = 2; break; // -x
case 5: v0 = 0; v1 = 4; v2 = 6; break;
case 6: v0 = 1; v1 = 3; v2 = 7; break; // +x
case 7: v0 = 1; v1 = 7; v2 = 5; break;
case 8: v0 = 1; v1 = 4; v2 = 0; break; // -y
case 9: v0 = 1; v1 = 5; v2 = 4; break;
case 10: v0 = 2; v1 = 7; v2 = 3; break; // +y
case 11: v0 = 2; v1 = 6; v2 = 7; break;
}
if((valid=intersect (line, points[v0], points[v1], points[v2],
inter, bary, front)) == true)
{
if(front == true)
{
enterPoint = inter;
validIntersection = valid;
}
else
{
exitPoint = inter;
validIntersection = valid;
}
}
}
return validIntersection;
}
template<class T>
bool intersects(const Box< Vec3<T> > &box,
const Line3<T> &line,
Vec3<T> &result)
{
/*
Fast Ray-Box Intersection
by Andrew Woo
from "Graphics Gems", Academic Press, 1990
*/
const int right = 0;
const int left = 1;
const int middle = 2;
const Vec3<T> &minB = box.min;
const Vec3<T> &maxB = box.max;
const Vec3<T> &origin = line.pos;
const Vec3<T> &dir = line.dir;
bool inside = true;
char quadrant[3];
int whichPlane;
float maxT[3];
float candidatePlane[3];
/* Find candidate planes; this loop can be avoided if
rays cast all from the eye(assume perpsective view) */
for (int i=0; i<3; i++)
{
if(origin[i] < minB[i])
{
quadrant[i] = left;
candidatePlane[i] = minB[i];
inside = false;
}
else if (origin[i] > maxB[i])
{
quadrant[i] = right;
candidatePlane[i] = maxB[i];
inside = false;
}
else
{
quadrant[i] = middle;
}
}
/* Ray origin inside bounding box */
if ( inside )
{
result = origin;
return true;
}
/* Calculate T distances to candidate planes */
for (int i = 0; i < 3; i++)
{
if (quadrant[i] != middle && dir[i] !=0.)
{
maxT[i] = (candidatePlane[i]-origin[i]) / dir[i];
}
else
{
maxT[i] = -1.;
}
}
/* Get largest of the maxT's for final choice of intersection */
whichPlane = 0;
for (int i = 1; i < 3; i++)
{
if (maxT[whichPlane] < maxT[i])
{
whichPlane = i;
}
}
/* Check final candidate actually inside box */
if (maxT[whichPlane] < 0.) return false;
for (int i = 0; i < 3; i++)
{
if (whichPlane != i)
{
result[i] = origin[i] + maxT[whichPlane] *dir[i];
if ((quadrant[i] == right && result[i] < minB[i]) ||
(quadrant[i] == left && result[i] > maxB[i]))
{
return false; /* outside box */
}
}
else
{
result[i] = candidatePlane[i];
}
}
return true;
}
template<class T>
bool intersects(const Box< Vec3<T> > &box, const Line3<T> &line)
{
Vec3<T> ignored;
return intersects(box,line,ignored);
}
} // namespace Imath
#endif
-734
View File
@@ -1,734 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHCOLOR_H
#define INCLUDED_IMATHCOLOR_H
//----------------------------------------------------
//
// A three and four component color class template.
//
//----------------------------------------------------
#include "ImathVec.h"
#include "half.h"
namespace Imath {
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);
}
} // namespace Imath
#endif
-178
View File
@@ -1,178 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Implementation of non-template items declared in ImathColorAlgo.h
//
//----------------------------------------------------------------------------
#include "ImathColorAlgo.h"
namespace Imath {
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);
}
} // namespace Imath
-256
View File
@@ -1,256 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHCOLORALGO_H
#define INCLUDED_IMATHCOLORALGO_H
#include "ImathColor.h"
#include "ImathMath.h"
#include "ImathLimits.h"
namespace Imath {
//
// Non-templated helper routines for color conversion.
// These routines eliminate type warnings under g++.
//
Vec3<double> hsv2rgb_d(const Vec3<double> &hsv);
Color4<double> hsv2rgb_d(const Color4<double> &hsv);
Vec3<double> rgb2hsv_d(const Vec3<double> &rgb);
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.g, 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.g, 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;
}
}
} // namespace Imath
#endif
-903
View File
@@ -1,903 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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 <iostream>
namespace Imath {
#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)
//----------------------------------------------------------------
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
//---------------------------------------------------------
void extract(const Matrix33<T>&);
void extract(const Matrix44<T>&);
void extract(const Quat<T>&);
Matrix33<T> toMatrix33() const;
Matrix44<T> toMatrix44() const;
Quat<T> toQuat() const;
Vec3<T> toXYZVector() const;
//---------------------------------------------------
// Use this function to unpack angles from ijk form
//---------------------------------------------------
void angleOrder(int &i, int &j, int &k) const;
//---------------------------------------------------
// Use this function to determine mapping from xyz to ijk
// - reshuffles the xyz to match the order
//---------------------------------------------------
void angleMapping(int &i, int &j, int &k) const;
//----------------------------------------------------------------------
//
// Utility methods for getting continuous rotations. None of these
// methods change the orientation given by its inputs (or at least
// that is the intent).
//
// angleMod() converts an angle to its equivalent in [-PI, PI]
//
// simpleXYZRotation() adjusts xyzRot so that its components differ
// from targetXyzRot by no more than +-PI
//
// nearestRotation() adjusts xyzRot so that its components differ
// from targetXyzRot by as little as possible.
// Note that xyz here really means ijk, because
// the order must be provided.
//
// makeNear() adjusts "this" Euler so that its components differ
// from target by as little as possible. This method
// might not make sense for Eulers with different order
// and it probably doesn't work for repeated axis and
// relative orderings (TODO).
//
//-----------------------------------------------------------------------
static float angleMod (T angle);
static void simpleXYZRotation (Vec3<T> &xyzRot,
const Vec3<T> &targetXyzRot);
static void nearestRotation (Vec3<T> &xyzRot,
const Vec3<T> &targetXyzRot,
Order order = XYZ);
void makeNear (const Euler<T> &target);
bool frameStatic() const { return _frameStatic; }
bool initialRepeated() const { return _initialRepeated; }
bool parityEven() const { return _parityEven; }
Axis initialAxis() const { return _initialAxis; }
protected:
bool _frameStatic : 1; // relative or static rotations
bool _initialRepeated : 1; // init axis repeated as last
bool _parityEven : 1; // "parity of axis permutation"
#if defined _WIN32 || defined _WIN64
Axis _initialAxis ; // First axis of rotation
#else
Axis _initialAxis : 2; // First axis of rotation
#endif
};
//--------------------
// Convenient typedefs
//--------------------
typedef Euler<float> Eulerf;
typedef Euler<double> Eulerd;
//---------------
// Implementation
//---------------
template<class T>
inline void
Euler<T>::angleOrder(int &i, int &j, int &k) const
{
i = _initialAxis;
j = _parityEven ? (i+1)%3 : (i > 0 ? i-1 : 2);
k = _parityEven ? (i > 0 ? i-1 : 2) : (i+1)%3;
}
template<class T>
inline void
Euler<T>::angleMapping(int &i, int &j, int &k) const
{
int m[3];
m[_initialAxis] = 0;
m[(_initialAxis+1) % 3] = _parityEven ? 1 : 2;
m[(_initialAxis+2) % 3] = _parityEven ? 2 : 1;
i = m[0];
j = m[1];
k = m[2];
}
template<class T>
inline void
Euler<T>::setXYZVector(const Vec3<T> &v)
{
int i,j,k;
angleMapping(i,j,k);
(*this)[i] = v.x;
(*this)[j] = v.y;
(*this)[k] = v.z;
}
template<class T>
inline Vec3<T>
Euler<T>::toXYZVector() const
{
int i,j,k;
angleMapping(i,j,k);
return Vec3<T>((*this)[i],(*this)[j],(*this)[k]);
}
template<class T>
Euler<T>::Euler() :
Vec3<T>(0,0,0),
_frameStatic(true),
_initialRepeated(false),
_parityEven(true),
_initialAxis(X)
{}
template<class T>
Euler<T>::Euler(typename Euler<T>::Order p) :
Vec3<T>(0,0,0),
_frameStatic(true),
_initialRepeated(false),
_parityEven(true),
_initialAxis(X)
{
setOrder(p);
}
template<class T>
inline Euler<T>::Euler( const Vec3<T> &v,
typename Euler<T>::Order p,
typename Euler<T>::InputLayout l )
{
setOrder(p);
if ( l == XYZLayout ) setXYZVector(v);
else { x = v.x; y = v.y; z = v.z; }
}
template<class T>
inline Euler<T>::Euler(const Euler<T> &euler)
{
operator=(euler);
}
template<class T>
inline Euler<T>::Euler(const Euler<T> &euler,Order p)
{
setOrder(p);
Matrix33<T> M = euler.toMatrix33();
extract(M);
}
template<class T>
inline Euler<T>::Euler( T xi, T yi, T zi,
typename Euler<T>::Order p,
typename Euler<T>::InputLayout l)
{
setOrder(p);
if ( l == XYZLayout ) setXYZVector(Vec3<T>(xi,yi,zi));
else { x = xi; y = yi; z = zi; }
}
template<class T>
inline Euler<T>::Euler( const Matrix33<T> &M, typename Euler::Order p )
{
setOrder(p);
extract(M);
}
template<class T>
inline Euler<T>::Euler( const Matrix44<T> &M, typename Euler::Order p )
{
setOrder(p);
extract(M);
}
template<class T>
inline void Euler<T>::extract(const Quat<T> &q)
{
extract(q.toMatrix33());
}
template<class T>
void Euler<T>::extract(const Matrix33<T> &M)
{
int i,j,k;
angleOrder(i,j,k);
if (_initialRepeated)
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][i], M[k][i]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
M[1][0], M[1][1], M[1][2], 0,
M[2][0], M[2][1], M[2][2], 0,
0, 0, 0, 1);
//
// Extract the other two angles, y and z, from N.
//
T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
y = Math<T>::atan2 (sy, N[i][i]);
z = Math<T>::atan2 (N[j][k], N[j][j]);
}
else
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][k], M[k][k]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
M[1][0], M[1][1], M[1][2], 0,
M[2][0], M[2][1], M[2][2], 0,
0, 0, 0, 1);
//
// Extract the other two angles, y and z, from N.
//
T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
y = Math<T>::atan2 (-N[i][k], cy);
z = Math<T>::atan2 (-N[j][i], N[j][j]);
}
if (!_parityEven)
*this *= -1;
if (!_frameStatic)
{
T t = x;
x = z;
z = t;
}
}
template<class T>
void Euler<T>::extract(const Matrix44<T> &M)
{
int i,j,k;
angleOrder(i,j,k);
if (_initialRepeated)
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][i], M[k][i]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * M;
//
// Extract the other two angles, y and z, from N.
//
T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
y = Math<T>::atan2 (sy, N[i][i]);
z = Math<T>::atan2 (N[j][k], N[j][j]);
}
else
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][k], M[k][k]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * M;
//
// Extract the other two angles, y and z, from N.
//
T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
y = Math<T>::atan2 (-N[i][k], cy);
z = Math<T>::atan2 (-N[j][i], N[j][j]);
}
if (!_parityEven)
*this *= -1;
if (!_frameStatic)
{
T t = x;
x = z;
z = t;
}
}
template<class T>
Matrix33<T> Euler<T>::toMatrix33() const
{
int i,j,k;
angleOrder(i,j,k);
Vec3<T> angles;
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles *= -1.0;
T ci = Math<T>::cos(angles.x);
T cj = Math<T>::cos(angles.y);
T ch = Math<T>::cos(angles.z);
T si = Math<T>::sin(angles.x);
T sj = Math<T>::sin(angles.y);
T sh = Math<T>::sin(angles.z);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
Matrix33<T> M;
if ( _initialRepeated )
{
M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci;
M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss;
}
else
{
M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci;
}
return M;
}
template<class T>
Matrix44<T> Euler<T>::toMatrix44() const
{
int i,j,k;
angleOrder(i,j,k);
Vec3<T> angles;
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles *= -1.0;
T ci = Math<T>::cos(angles.x);
T cj = Math<T>::cos(angles.y);
T ch = Math<T>::cos(angles.z);
T si = Math<T>::sin(angles.x);
T sj = Math<T>::sin(angles.y);
T sh = Math<T>::sin(angles.z);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
Matrix44<T> M;
if ( _initialRepeated )
{
M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci;
M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss;
}
else
{
M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci;
}
return M;
}
template<class T>
Quat<T> Euler<T>::toQuat() const
{
Vec3<T> angles;
int i,j,k;
angleOrder(i,j,k);
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles.y = -angles.y;
T ti = angles.x*0.5;
T tj = angles.y*0.5;
T th = angles.z*0.5;
T ci = Math<T>::cos(ti);
T cj = Math<T>::cos(tj);
T ch = Math<T>::cos(th);
T si = Math<T>::sin(ti);
T sj = Math<T>::sin(tj);
T sh = Math<T>::sin(th);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
T parity = _parityEven ? 1.0 : -1.0;
Quat<T> q;
Vec3<T> a;
if ( _initialRepeated )
{
a[i] = cj*(cs + sc);
a[j] = sj*(cc + ss) * parity,
a[k] = sj*(cs - sc);
q.r = cj*(cc - ss);
}
else
{
a[i] = cj*sc - sj*cs,
a[j] = (cj*ss + sj*cc) * parity,
a[k] = cj*cs - sj*sc;
q.r = cj*cc + sj*ss;
}
q.v = a;
return q;
}
template<class T>
inline bool
Euler<T>::legal(typename Euler<T>::Order order)
{
return (order & ~Legal) ? false : true;
}
template<class T>
typename Euler<T>::Order
Euler<T>::order() const
{
int foo = (_initialAxis == Z ? 0x2000 : (_initialAxis == Y ? 0x1000 : 0));
if (_parityEven) foo |= 0x0100;
if (_initialRepeated) foo |= 0x0010;
if (_frameStatic) foo++;
return (Order)foo;
}
template<class T>
inline void Euler<T>::setOrder(typename Euler<T>::Order p)
{
set( p & 0x2000 ? Z : (p & 0x1000 ? Y : X), // initial axis
!(p & 0x1), // static?
!!(p & 0x100), // permutation even?
!!(p & 0x10)); // initial repeats?
}
template<class T>
void Euler<T>::set(typename Euler<T>::Axis axis,
bool relative,
bool parityEven,
bool firstRepeats)
{
_initialAxis = axis;
_frameStatic = !relative;
_parityEven = parityEven;
_initialRepeated = firstRepeats;
}
template<class T>
const Euler<T>& Euler<T>::operator= (const Euler<T> &euler)
{
x = euler.x;
y = euler.y;
z = euler.z;
_initialAxis = euler._initialAxis;
_frameStatic = euler._frameStatic;
_parityEven = euler._parityEven;
_initialRepeated = euler._initialRepeated;
return *this;
}
template<class T>
const Euler<T>& Euler<T>::operator= (const Vec3<T> &v)
{
x = v.x;
y = v.y;
z = v.z;
return *this;
}
template<class T>
std::ostream& operator << (std::ostream &o, const Euler<T> &euler)
{
char a[3] = { 'X', 'Y', 'Z' };
const char* r = euler.frameStatic() ? "" : "r";
int i,j,k;
euler.angleOrder(i,j,k);
if ( euler.initialRepeated() ) k = i;
return o << "("
<< euler.x << " "
<< euler.y << " "
<< euler.z << " "
<< a[i] << a[j] << a[k] << r << ")";
}
template <class T>
float
Euler<T>::angleMod (T angle)
{
angle = fmod(T (angle), T (2 * M_PI));
if (angle < -M_PI) angle += 2 * M_PI;
if (angle > +M_PI) angle -= 2 * M_PI;
return angle;
}
template <class T>
void
Euler<T>::simpleXYZRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot)
{
Vec3<T> d = xyzRot - targetXyzRot;
xyzRot[0] = targetXyzRot[0] + angleMod(d[0]);
xyzRot[1] = targetXyzRot[1] + angleMod(d[1]);
xyzRot[2] = targetXyzRot[2] + angleMod(d[2]);
}
template <class T>
void
Euler<T>::nearestRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot,
Order order)
{
int i,j,k;
Euler<T> e (0,0,0, order);
e.angleOrder(i,j,k);
simpleXYZRotation(xyzRot, targetXyzRot);
Vec3<T> otherXyzRot;
otherXyzRot[i] = M_PI+xyzRot[i];
otherXyzRot[j] = M_PI-xyzRot[j];
otherXyzRot[k] = M_PI+xyzRot[k];
simpleXYZRotation(otherXyzRot, targetXyzRot);
Vec3<T> d = xyzRot - targetXyzRot;
Vec3<T> od = otherXyzRot - targetXyzRot;
T dMag = d.dot(d);
T odMag = od.dot(od);
if (odMag < dMag)
{
xyzRot = otherXyzRot;
}
}
template <class T>
void
Euler<T>::makeNear (const Euler<T> &target)
{
Vec3<T> xyzRot = toXYZVector();
Euler<T> targetSameOrder = Euler<T>(target, order());
Vec3<T> targetXyz = targetSameOrder.toXYZVector();
nearestRotation(xyzRot, targetXyz, order());
setXYZVector(xyzRot);
}
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#pragma warning(default:4244)
#endif
} // namespace Imath
#endif
-70
View File
@@ -1,70 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHEXC_H
#define INCLUDED_IMATHEXC_H
//-----------------------------------------------
//
// Imath library-specific exceptions
//
//-----------------------------------------------
#include "IexBaseExc.h"
namespace Imath {
DEFINE_EXC (NullVecExc, ::Iex::MathExc) // Attempt to normalize
// null vector
DEFINE_EXC (NullQuatExc, ::Iex::MathExc) // Attempt to normalize
// null quaternion
DEFINE_EXC (SingMatrixExc, ::Iex::MathExc) // Attempt to invert
// singular matrix
DEFINE_EXC (ZeroScaleExc, ::Iex::MathExc) // Attempt to remove zero
// scaling from matrix
DEFINE_EXC (IntVecNormalizeExc, ::Iex::MathExc) // Attempt to normalize
// a vector of whose elements
// are an integer type
} // namespace Imath
#endif
-190
View File
@@ -1,190 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHFRAME_H
#define INCLUDED_IMATHFRAME_H
namespace Imath {
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::firstFrame( p[0], p[1], p[2] );
// for( int i = 1; i < n - 1; i++ )
// {
// m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
// }
// m[n-1] = Imath::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;
}
} // namespace Imath
#endif
-722
View File
@@ -1,722 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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 "IexMathExc.h"
#if defined _WIN32 || defined _WIN64
#ifdef near
#undef near
#endif
#ifdef far
#undef far
#endif
#endif
namespace Imath {
//
// 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.
//
template<class T>
class Frustum
{
public:
Frustum();
Frustum(const Frustum &);
Frustum(T near, T far, T left, T right, T top, T bottom, bool ortho=false);
Frustum(T near, T far, 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 near, T far,
T left, T right,
T top, T bottom,
bool ortho=false);
void set(T near, T far, T fovx, T fovy, T aspect);
//------------------------------------------------------
// These functions modify an already valid frustum state
//------------------------------------------------------
void modifyNearAndFar(T near, T far);
void setOrthographic(bool);
//--------------
// Access
//--------------
bool orthographic() const { return _orthographic; }
T near() const { return _near; }
T far() const { return _far; }
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]);
void planes(Plane3<T> p[6], const Matrix44<T> &M);
//----------------------
// Derived Quantities
//----------------------
T fovx() const;
T fovy() const;
T aspect() const;
Matrix44<T> projectionMatrix() 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 _near;
T _far;
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 near, T far, T fovx, T fovy, T aspect)
{
set(near,far,fovx,fovy,aspect);
}
template<class T>
Frustum<T>::~Frustum()
{
}
template<class T>
const Frustum<T> &
Frustum<T>::operator = (const Frustum &f)
{
_near = f._near;
_far = f._far;
_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
_near == src._near &&
_far == src._far &&
_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)
{
_near = n;
_far = f;
_left = l;
_right = r;
_bottom = b;
_top = t;
_orthographic = o;
}
template<class T>
void Frustum<T>::modifyNearAndFar(T n, T f)
{
if ( _orthographic )
{
_near = n;
}
else
{
Line3<T> lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_near) );
Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_near) );
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;
_near = n;
_far = f;
}
_far = f;
}
template<class T>
void Frustum<T>::setOrthographic(bool ortho)
{
_orthographic = ortho;
}
template<class T>
void Frustum<T>::set(T near, T far, T fovx, T fovy, T aspect)
{
if (fovx != 0 && fovy != 0)
throw Iex::ArgExc ("fovx and fovy cannot both be non-zero.");
if (fovx != 0)
{
_right = near * Math<T>::tan(fovx/2.0);
_left = -_right;
_top = ((_right - _left)/aspect)/2.0;
_bottom = -_top;
}
else
{
_top = near * Math<T>::tan(fovy/2.0);
_bottom = -_top;
_right = (_top - _bottom) * aspect / 2.0;
_left = -_right;
}
_near = near;
_far = far;
_orthographic = false;
}
template<class T>
T Frustum<T>::fovx() const
{
return Math<T>::atan2(_right,_near) - Math<T>::atan2(_left,_near);
}
template<class T>
T Frustum<T>::fovy() const
{
return Math<T>::atan2(_top,_near) - Math<T>::atan2(_bottom,_near);
}
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::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 = _far+_near;
T farMinusNear = _far-_near;
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::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::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 * _far * _near;
if (abs(farMinusNear) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
{
throw Iex::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T D = farTimesNear / farMinusNear;
T twoTimesNear = 2 * _near;
if ((abs(rightMinusLeft) < 1 &&
abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
{
throw Iex::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>
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>(_near, _far, 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 - 2 * p.x + _right;
T leftMinusRight = _left-_right;
T bottomPlusTop = _bottom - 2 * p.y + _top;
T bottomMinusTop = _bottom-_top;
if ((abs(leftMinusRight) < 1 &&
abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
(abs(bottomMinusTop) < 1 &&
abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
{
throw Iex::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,-_near));
else
return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_near));
}
template<class T>
Vec2<T> Frustum<T>::projectPointToScreen(const Vec3<T> &point) const
{
if (orthographic() || point.z == 0)
return localToScreen( Vec2<T>( point.x, point.y ) );
else
return localToScreen( Vec2<T>( point.x * _near / -point.z,
point.y * _near / -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::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*(_far-_near) + (_far+_near))/2;
}
else
{
T farTimesNear = 2 * _far * _near;
T farMinusNear = Zp * (_far - _near) - _far - _near;
if (abs(farMinusNear) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
{
throw Iex::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 = _far-_near;
if ( _orthographic )
{
T farPlusNear = 2*depth + _far + _near;
if (abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
{
throw Iex::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*_far*_near;
if (abs(depth) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(depth))
{
throw Iex::DivzeroExc
("Bad call to DepthToZ function: value of `depth' "
"is too small");
}
T farPlusNear = farTimesNear/depth + _far + _near;
if (abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
{
throw Iex::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 * (-_near / p.z)
// Let q be p + (radius, 0, 0).
// X coord of projection of q = xq = (p.x - radius) * (-_near / p.z)
// X coord of projection of segment from p to q = r = xp - xq
// = radius * (-_near / 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(-_near) < limits<T>::max() * abs(p.z))
{
return radius * (-_near / p.z);
}
else
{
throw Iex::DivzeroExc
("Bad call to Frustum::screenRadius: the magnitude of `p' "
"is too small");
}
return radius * (-_near / p.z);
}
template<class T>
T Frustum<T>::worldRadius(const Vec3<T> &p, T radius) const
{
if (abs(-_near) > 1 || abs(p.z) < limits<T>::max() * abs(-_near))
{
return radius * (p.z / -_near);
}
else
{
throw Iex::DivzeroExc
("Bad viewing frustum: the near clipping plane is too "
"close to zero");
}
}
template<class T>
void Frustum<T>::planes(Plane3<T> p[6])
{
//
// Plane order: Top, Right, Bottom, Left, Near, Far.
// Normals point outwards.
//
if (! _orthographic)
{
Vec3<T> a( _left, _bottom, -_near);
Vec3<T> b( _left, _top, -_near);
Vec3<T> c( _right, _top, -_near);
Vec3<T> d( _right, _bottom, -_near);
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), -_near );
p[5].set( Vec3<T>(0, 0,-1), _far );
}
template<class T>
void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M)
{
//
// Plane order: Top, Right, Bottom, Left, Near, Far.
// Normals point outwards.
//
Vec3<T> a = Vec3<T>( _left, _bottom, -_near) * M;
Vec3<T> b = Vec3<T>( _left, _top, -_near) * M;
Vec3<T> c = Vec3<T>( _right, _top, -_near) * M;
Vec3<T> d = Vec3<T>( _right, _bottom, -_near) * M;
if (! _orthographic)
{
double s = _far / double(_near);
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, -_far) * M;
Vec3<T> f = Vec3<T>( farLeft, farTop, -_far) * M;
Vec3<T> g = Vec3<T>( farRight, farTop, -_far) * 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, -_far) * M;
Vec3<T> f = Vec3<T>( _left, _top, -_far) * M;
Vec3<T> g = Vec3<T>( _right, _top, -_far) * M;
Vec3<T> h = Vec3<T>( _right, _bottom, -_far) * 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;
} // namespace Imath
#endif
-181
View File
@@ -1,181 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#include "ImathFun.h"
namespace Imath {
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.i > 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.i > 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;
}
} // namespace Imath
-267
View File
@@ -1,267 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHFUN_H
#define INCLUDED_IMATHFUN_H
//-----------------------------------------------------------------------------
//
// Miscellaneous utility functions
//
//-----------------------------------------------------------------------------
#include "ImathLimits.h"
#include "ImathInt64.h"
namespace Imath {
template <class T>
inline T
abs (T a)
{
return (a > 0) ? a : -a;
}
template <class T>
inline int
sign (T a)
{
return (a > 0)? 1 : ((a < 0) ? -1 : 0);
}
template <class T, class Q>
inline T
lerp (T a, T b, Q t)
{
return (T) (a + (b - a) * 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::sign (a - b);
}
template <class T>
inline int
cmpt (T a, T b, T t)
{
return (Imath::abs (a - b) <= t)? 0 : cmp (a, b);
}
template <class T>
inline bool
iszero (T a, T t)
{
return (Imath::abs (a) <= t) ? 1 : 0;
}
template <class T1, class T2, class T3>
inline bool
equal (T1 a, T2 b, T3 t)
{
return Imath::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.
//
//----------------------------------------------------------
float succf (float f);
float predf (float f);
double succd (double d);
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;
}
} // namespace Imath
#endif
-159
View File
@@ -1,159 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHGL_H
#define INCLUDED_IMATHGL_H
#include <GL/gl.h>
#include "ImathVec.h"
#include "ImathMatrix.h"
#include "IexMathExc.h"
#include "ImathFun.h"
inline void glVertex ( const Imath::V3f &v ) { glVertex3f(v.x,v.y,v.z); }
inline void glVertex ( const Imath::V2f &v ) { glVertex2f(v.x,v.y); }
inline void glNormal ( const Imath::V3f &n ) { glNormal3f(n.x,n.y,n.z); }
inline void glColor ( const Imath::V3f &c ) { glColor3f(c.x,c.y,c.z); }
inline void glTranslate ( const Imath::V3f &t ) { glTranslatef(t.x,t.y,t.z); }
inline void glTexCoord( const Imath::V2f &t )
{
glTexCoord2f(t.x,t.y);
}
inline void glDisableTexture()
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
}
namespace {
const float GL_FLOAT_MAX = 1.8e+19; // sqrt (FLT_MAX)
inline bool
badFloat (float f)
{
return !Imath::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX;
}
} // namespace
inline void
throwBadMatrix (const Imath::M44f& m)
{
if (badFloat (m[0][0]) ||
badFloat (m[0][1]) ||
badFloat (m[0][2]) ||
badFloat (m[0][3]) ||
badFloat (m[1][0]) ||
badFloat (m[1][1]) ||
badFloat (m[1][2]) ||
badFloat (m[1][3]) ||
badFloat (m[2][0]) ||
badFloat (m[2][1]) ||
badFloat (m[2][2]) ||
badFloat (m[2][3]) ||
badFloat (m[3][0]) ||
badFloat (m[3][1]) ||
badFloat (m[3][2]) ||
badFloat (m[3][3]))
throw Iex::OverflowExc ("GL matrix overflow");
}
inline void
glMultMatrix( const Imath::M44f& m )
{
throwBadMatrix (m);
glMultMatrixf( (GLfloat*)m[0] );
}
inline void
glMultMatrix( const Imath::M44f* m )
{
throwBadMatrix (*m);
glMultMatrixf( (GLfloat*)(*m)[0] );
}
inline void
glLoadMatrix( const Imath::M44f& m )
{
throwBadMatrix (m);
glLoadMatrixf( (GLfloat*)m[0] );
}
inline void
glLoadMatrix( const Imath::M44f* m )
{
throwBadMatrix (*m);
glLoadMatrixf( (GLfloat*)(*m)[0] );
}
namespace Imath {
//
// Class objects that push/pop the GL state. These objects assist with
// proper cleanup of the state when exceptions are thrown.
//
class GLPushMatrix {
public:
GLPushMatrix () { glPushMatrix(); }
~GLPushMatrix() { glPopMatrix(); }
};
class GLPushAttrib {
public:
GLPushAttrib (GLbitfield mask) { glPushAttrib (mask); }
~GLPushAttrib() { glPopAttrib(); }
};
class GLBegin {
public:
GLBegin (GLenum mode) { glBegin (mode); }
~GLBegin() { glEnd(); }
};
} // namespace Imath
#endif
-54
View File
@@ -1,54 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHGLU_H
#define INCLUDED_IMATHGLU_H
#include <GL/gl.h>
#include <GL/glu.h>
#include "ImathVec.h"
inline
void
gluLookAt(const Imath::V3f &pos, const Imath::V3f &interest, const Imath::V3f &up)
{
gluLookAt(pos.x, pos.y, pos.z,
interest.x, interest.y, interest.z,
up.x, up.y, up.z);
}
#endif
-66
View File
@@ -1,66 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHHALFLIMITS_H
#define INCLUDED_IMATHHALFLIMITS_H
//--------------------------------------------------
//
// Imath-style limits for class half.
//
//--------------------------------------------------
#include "ImathLimits.h"
#include "half.h"
namespace Imath {
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;}
};
} // namespace Imath
#endif
-61
View File
@@ -1,61 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, 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 <limits.h>
namespace Imath {
#if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300
typedef unsigned __int64 Int64;
#elif ULONG_MAX == 18446744073709551615LU
typedef long unsigned int Int64;
#else
typedef long long unsigned int Int64;
#endif
} // namespace Imath
#endif
-224
View File
@@ -1,224 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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"
namespace Imath {
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;
}
} // namespace Imath
#endif
-265
View File
@@ -1,265 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHLIMITS_H
#define INCLUDED_IMATHLIMITS_H
//----------------------------------------------------------------
//
// Limitations of the basic C++ numerical data types
//
//----------------------------------------------------------------
#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
namespace Imath {
//-----------------------------------------------------------------
//
// 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
//
// 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;}
};
} // namespace Imath
#endif
-184
View File
@@ -1,184 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHLINE_H
#define INCLUDED_IMATHLINE_H
//-------------------------------------
//
// A 3D line class template
//
//-------------------------------------
#include "ImathVec.h"
#include "ImathLimits.h"
#include "ImathMatrix.h"
namespace Imath {
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 );
}
} // namespace Imath
#endif
-287
View File
@@ -1,287 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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"
namespace Imath {
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;
}
} // namespace Imath
#endif
-208
View File
@@ -1,208 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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 <math.h>
namespace Imath {
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);
}
} // namespace Imath
#endif
File diff suppressed because it is too large Load Diff
-73
View File
@@ -1,73 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Implementation of non-template items declared in ImathMatrixAlgo.h
//
//----------------------------------------------------------------------------
#include "ImathMatrixAlgo.h"
#if defined(OPENEXR_DLL)
#define EXPORT_CONST __declspec(dllexport)
#else
#define EXPORT_CONST const
#endif
namespace Imath {
EXPORT_CONST M33f identity33f ( 1, 0, 0,
0, 1, 0,
0, 0, 1);
EXPORT_CONST M33d identity33d ( 1, 0, 0,
0, 1, 0,
0, 0, 1);
EXPORT_CONST M44f identity44f ( 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
EXPORT_CONST M44d identity44d ( 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
} // namespace Imath
File diff suppressed because it is too large Load Diff
-256
View File
@@ -1,256 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHPLANE_H
#define INCLUDED_IMATHPLANE_H
//----------------------------------------------------------------------
//
// template class Plane3
//
// The Imath::Plane3<> class represents a half space, so the
// normal may point either towards or away from origin. The
// plane P can be represented by Imath::Plane3 as either p or -p
// corresponding to the two half-spaces on either side of the
// plane. Any function which computes a distance will return
// either negative or positive values for the distance indicating
// which half-space the point is in. Note that reflection, and
// intersection functions will operate as expected.
//
//----------------------------------------------------------------------
#include "ImathVec.h"
#include "ImathLine.h"
namespace Imath {
template <class T>
class Plane3
{
public:
Vec3<T> normal;
T distance;
Plane3() {}
Plane3(const Vec3<T> &normal, T distance);
Plane3(const Vec3<T> &point, const Vec3<T> &normal);
Plane3(const Vec3<T> &point1,
const Vec3<T> &point2,
const Vec3<T> &point3);
//----------------------
// Various set methods
//----------------------
void set(const Vec3<T> &normal,
T distance);
void set(const Vec3<T> &point,
const Vec3<T> &normal);
void set(const Vec3<T> &point1,
const Vec3<T> &point2,
const Vec3<T> &point3 );
//----------------------
// Utilities
//----------------------
bool intersect(const Line3<T> &line,
Vec3<T> &intersection) const;
bool intersectT(const Line3<T> &line,
T &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);
}
} // namespace Imath
#endif
-92
View File
@@ -1,92 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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>
#if defined _WIN32 || defined _WIN64
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#endif
//-----------------------------------------------------------------------------
//
// Fixes for the "restrict" keyword. These #ifdef's for detecting
// compiler versions courtesy of Boost's select_compiler_config.hpp;
// here is the copyright notice for that file:
//
// (C) Copyright Boost.org 2001. Permission to copy, use, modify, sell and
// and distribute this software is granted provided this copyright notice
// appears in all copies. This software is provided "as is" without express
// or implied warranty, and with no claim as to its suitability for any
// purpose.
//
// Some compilers support "restrict", in which case we do nothing.
// Other compilers support some variant of it (e.g. "__restrict").
// If we don't know anything about the compiler, we define "restrict"
// to be a no-op.
//
//-----------------------------------------------------------------------------
#if defined __GNUC__
#if !defined(restrict)
#define restrict __restrict
#endif
#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
// supports restrict, do nothing.
#elif defined __sgi
// supports restrict, do nothing.
#else
#define restrict
#endif
#endif // INCLUDED_IMATHPLATFORM_H
-728
View File
@@ -1,728 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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 <iostream>
namespace Imath {
#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;
template<class T>
Quat<T> slerp (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>
class Quat
{
public:
T r; // real part
Vec3<T> v; // imaginary vector
//-----------------------------------------------------
// Constructors - default constructor is identity quat
//-----------------------------------------------------
Quat() : r(1), v(0,0,0) {}
template <class S>
Quat( const Quat<S>& q) : r(q.r), v(q.v) {}
Quat( T s, T i, T j, T k ) : r(s), v(i,j,k) {}
Quat( T s, Vec3<T> d ) : r(s), v(d) {}
static Quat<T> identity() { return Quat<T>(); }
//------------------------------------------------
// Basic Algebra - Operators and Methods
// The operator return values are *NOT* normalized
//
// operator^ is 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>&);
const Quat<T>& operator*= (const Quat<T>&);
const Quat<T>& operator*= (T);
const Quat<T>& operator/= (const Quat<T>&);
const Quat<T>& operator/= (T);
const Quat<T>& operator+= (const Quat<T>&);
const Quat<T>& operator-= (const Quat<T>&);
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
//-----------------------
// 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);
};
//--------------------
// Convenient typedefs
//--------------------
typedef Quat<float> Quatf;
typedef Quat<double> Quatd;
//---------------
// Implementation
//---------------
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>
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 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> 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.0*Math<T>::acos(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, 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 half way 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.0 * (v.y * v.y + v.z * v.z),
2.0 * (v.x * v.y + v.z * r),
2.0 * (v.z * v.x - v.y * r),
2.0 * (v.x * v.y - v.z * r),
1. - 2.0 * (v.z * v.z + v.x * v.x),
2.0 * (v.y * v.z + v.x * r),
2.0 * (v.z * v.x + v.y * r),
2.0 * (v.y * v.z - v.x * r),
1. - 2.0 * (v.y * v.y + v.x * v.x));
}
template<class T>
Matrix44<T> Quat<T>::toMatrix44() const
{
return Matrix44<T>(1. - 2.0 * (v.y * v.y + v.z * v.z),
2.0 * (v.x * v.y + v.z * r),
2.0 * (v.z * v.x - v.y * r),
0.,
2.0 * (v.x * v.y - v.z * r),
1. - 2.0 * (v.z * v.z + v.x * v.x),
2.0 * (v.y * v.z + v.x * r),
0.,
2.0 * (v.z * v.x + v.y * r),
2.0 * (v.y * v.z - v.x * r),
1. - 2.0 * (v.y * v.y + v.x * v.x),
0.,
0.,
0.,
0.,
1.0 );
}
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)
{
// (S1+V1) (S2+V2) = S1 S2 - V1.V2 + S1 V2 + V1 S2 + V1 x V2
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 ); // conjugate: (S+V)* = S-V
}
template<class T>
inline Quat<T> operator- (const Quat<T>& q)
{
return Quat<T>( -q.r, -q.v );
}
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#pragma warning(default:4244)
#endif
} // namespace Imath
#endif
-168
View File
@@ -1,168 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Routines that generate pseudo-random numbers compatible
// with the standard erand48(), nrand48(), etc. functions.
//
//-----------------------------------------------------------------------------
#include "ImathRandom.h"
#include "ImathInt64.h"
namespace Imath {
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] = x >> 32;
state[1] = x >> 16;
state[0] = 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 set to
// zero. This results in bit patterns between 0x3ff0000000000000
// and 0x3ffffffffffffff0, which correspond to uniformly distributed
// floating-point values between 1.0 and 1.9999999999999964.
// Subtracting 1.0 from those values produces numbers between 0.0
// and 0.9999999999999964.
//
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);
return u.d - 1;
}
double
drand48 ()
{
return Imath::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::nrand48 (staticState);
}
void
srand48 (long int seed)
{
staticState[2] = seed >> 16;
staticState[1] = seed;
staticState[0] = 0x330e;
}
} // namespace Imath
-404
View File
@@ -1,404 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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 <stdlib.h>
#include <math.h>
namespace Imath {
//-----------------------------------------------
// Fast random-number generator that generates
// a uniformly distributed sequence with a period
// length of 2^32.
//-----------------------------------------------
class 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
//---------------------------------
double erand48 (unsigned short state[3]);
double drand48 ();
long int nrand48 (unsigned short state[3]);
long int lrand48 ();
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 ()
{
next ();
return ((int) (_state & 0xffffff)) * ((float) (1.0F / 0x1000000));
}
inline float
Rand32::nextf (float rangeMin, float rangeMax)
{
return rangeMin + nextf() * (rangeMax - rangeMin);
}
inline void
Rand48::init (unsigned long int seed)
{
seed = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
_state[0] = (unsigned short int) (seed);
_state[1] = (unsigned short int) (seed >> 16);
_state[2] = (unsigned short int) (seed);
}
inline
Rand48::Rand48 (unsigned long int seed)
{
init (seed);
}
inline bool
Rand48::nextb ()
{
return Imath::nrand48 (_state) & 1;
}
inline long int
Rand48::nexti ()
{
return Imath::nrand48 (_state);
}
inline double
Rand48::nextf ()
{
return Imath::erand48 (_state);
}
inline double
Rand48::nextf (double rangeMin, double rangeMax)
{
return rangeMin + nextf() * (rangeMax - rangeMin);
}
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);
}
} // namespace Imath
#endif
-217
View File
@@ -1,217 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHROOTS_H
#define INCLUDED_IMATHROOTS_H
//---------------------------------------------------------------------
//
// Functions to solve linear, quadratic or cubic equations
//
//---------------------------------------------------------------------
#include <complex>
namespace Imath {
//--------------------------------------------------------------------------
// 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 = sqrt (D);
x[0] = (-b + s) / (2 * a);
x[1] = (-b - s) / (2 * a);
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);
}
}
} // namespace Imath
#endif
-54
View File
@@ -1,54 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Specializations of the Shear6<T> template.
//
//----------------------------------------------------------------------------
#include "ImathShear.h"
namespace Imath {
// empty
} // namespace Imath
-659
View File
@@ -1,659 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHSHEAR_H
#define INCLUDED_IMATHSHEAR_H
//----------------------------------------------------
//
// Shear6 class template.
//
//----------------------------------------------------
#include "ImathExc.h"
#include "ImathLimits.h"
#include "ImathMath.h"
#include "ImathVec.h"
#include <iostream>
namespace Imath {
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::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::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);
}
} // namespace Imath
#endif
-177
View File
@@ -1,177 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_IMATHSPHERE_H
#define INCLUDED_IMATHSPHERE_H
//-------------------------------------
//
// A 3D sphere class template
//
//-------------------------------------
#include "ImathVec.h"
#include "ImathBox.h"
#include "ImathLine.h"
namespace Imath {
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 = 2.0 * (line.dir ^ v);
T C = (v ^ v) - (radius * radius);
// compute discriminant
// if negative, there is no intersection
T discr = B*B - 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) * 0.5;
if (t < 0.0)
{
// no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A (A = 1)
t = (-B + sqroot) * 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;
}
}
} //namespace Imath
#endif
-380
View File
@@ -1,380 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Specializations of the Vec2<T> and Vec3<T> templates.
//
//----------------------------------------------------------------------------
#include "ImathVec.h"
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
// suppress exception specification warnings
#pragma warning(disable:4290)
#endif
namespace Imath {
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;
}
}
// Vec2<short>
template <>
short
Vec2<short>::length () const
{
float lenF = Math<float>::sqrt (dot (*this));
short lenS = (short) (lenF + 0.5f);
return lenS;
}
template <>
const Vec2<short> &
Vec2<short>::normalize ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
const Vec2<short> &
Vec2<short>::normalizeExc () throw (Iex::MathExc)
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<short>(*this);
return *this;
}
template <>
const Vec2<short> &
Vec2<short>::normalizeNonNull ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
Vec2<short>
Vec2<short>::normalized () const
{
Vec2<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
Vec2<short>
Vec2<short>::normalizedExc () const throw (Iex::MathExc)
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec2<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
Vec2<short>
Vec2<short>::normalizedNonNull () const
{
Vec2<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
// Vec2<int>
template <>
int
Vec2<int>::length () const
{
float lenF = Math<float>::sqrt (dot (*this));
int lenI = (int) (lenF + 0.5f);
return lenI;
}
template <>
const Vec2<int> &
Vec2<int>::normalize ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
const Vec2<int> &
Vec2<int>::normalizeExc () throw (Iex::MathExc)
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<int>(*this);
return *this;
}
template <>
const Vec2<int> &
Vec2<int>::normalizeNonNull ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
Vec2<int>
Vec2<int>::normalized () const
{
Vec2<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
Vec2<int>
Vec2<int>::normalizedExc () const throw (Iex::MathExc)
{
if ((x == 0) && (y == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec2<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
Vec2<int>
Vec2<int>::normalizedNonNull () const
{
Vec2<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
// Vec3<short>
template <>
short
Vec3<short>::length () const
{
float lenF = Math<float>::sqrt (dot (*this));
short lenS = (short) (lenF + 0.5f);
return lenS;
}
template <>
const Vec3<short> &
Vec3<short>::normalize ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
const Vec3<short> &
Vec3<short>::normalizeExc () throw (Iex::MathExc)
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<short>(*this);
return *this;
}
template <>
const Vec3<short> &
Vec3<short>::normalizeNonNull ()
{
normalizeOrThrow<short>(*this);
return *this;
}
template <>
Vec3<short>
Vec3<short>::normalized () const
{
Vec3<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
Vec3<short>
Vec3<short>::normalizedExc () const throw (Iex::MathExc)
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec3<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
template <>
Vec3<short>
Vec3<short>::normalizedNonNull () const
{
Vec3<short> v(*this);
normalizeOrThrow<short>(v);
return v;
}
// Vec3<int>
template <>
int
Vec3<int>::length () const
{
float lenF = Math<float>::sqrt (dot (*this));
int lenI = (int) (lenF + 0.5f);
return lenI;
}
template <>
const Vec3<int> &
Vec3<int>::normalize ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
const Vec3<int> &
Vec3<int>::normalizeExc () throw (Iex::MathExc)
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
normalizeOrThrow<int>(*this);
return *this;
}
template <>
const Vec3<int> &
Vec3<int>::normalizeNonNull ()
{
normalizeOrThrow<int>(*this);
return *this;
}
template <>
Vec3<int>
Vec3<int>::normalized () const
{
Vec3<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
Vec3<int>
Vec3<int>::normalizedExc () const throw (Iex::MathExc)
{
if ((x == 0) && (y == 0) && (z == 0))
throw NullVecExc ("Cannot normalize null vector.");
Vec3<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
template <>
Vec3<int>
Vec3<int>::normalizedNonNull () const
{
Vec3<int> v(*this);
normalizeOrThrow<int>(v);
return v;
}
} // namespace Imath
File diff suppressed because it is too large Load Diff
-146
View File
@@ -1,146 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// 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_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"
namespace Imath {
//--------------------------------------------------------------
// Find the projection of vector t onto vector s (Vec2 and Vec3)
//--------------------------------------------------------------
template <class Vec> Vec project (const Vec &s, const Vec &t);
//----------------------------------------------
// Find a vector which is perpendicular to s and
// in the same plane as s and t (Vec2 and Vec3)
//----------------------------------------------
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 and Vec3)
//-----------------------------------------------
template <class Vec> Vec reflect (const Vec &s, const Vec &t);
//----------------------------------------------------------------------
// Find the vertex of triangle (v0, v1, v2), which is closest to point p
// (Vec2 and Vec3).
//----------------------------------------------------------------------
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;
}
} // namespace Imath
#endif

Some files were not shown because too many files have changed in this diff Show More