Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5001ec5070 |
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 forloop 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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
void testArithmetic ();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
void testBitPatterns ();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
void testClassification ();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
void testNormalizedConversionError ();
|
||||
void testDenormalizedConversionError ();
|
||||
void testRoundingError ();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
void testFunction ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
void testLimits ();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
void testSize ();
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
See the README file for instructions on how to build IlmBase from
|
||||
source.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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 ¶meter) 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user