Skip to content

Commit

Permalink
Updated Imath with the latest internal changes:
Browse files Browse the repository at this point in the history
+ near() and far() in ImathFrustum are now updated to be nearPlane() and
  farPlane() to prevent conflicts with #defines on windows.  The hither()
  and yon() functions remain but can be considered deprecated.

+ ImathBox now supports infinite functions analogous to the empty functions
  (isInfinite(), makeInfinite()), and the ImathBoxAlgo transform code has
  been updated accordingly.

+ ImathBoxAlgo has an additional transform() overload that takes the result
  as the last argument.

+ ImathMatrix now has matrix minor and detriminant functions.

+ ImathMatrixAlgo now has outerProduct(), addOffset() and computeLocalFrame()
  functions.
  • Loading branch information
nickrasmussen committed Apr 8, 2011
1 parent a61f091 commit 1d922d7
Show file tree
Hide file tree
Showing 14 changed files with 1,447 additions and 168 deletions.
63 changes: 63 additions & 0 deletions IlmBase/Imath/ImathBox.h
Expand Up @@ -101,6 +101,7 @@ class Box
void makeEmpty ();
void extendBy (const T &point);
void extendBy (const Box<T> &box);
void makeInfinite ();

//---------------------------------------------------
// Query functions - these compute results each time
Expand All @@ -119,6 +120,7 @@ class Box

bool isEmpty () const;
bool hasVolume () const;
bool isInfinite () const;
};


Expand Down Expand Up @@ -186,6 +188,13 @@ inline void Box<T>::makeEmpty()
max = T(T::baseTypeMin());
}

template <class T>
inline void Box<T>::makeInfinite()
{
min = T(T::baseTypeMin());
max = T(T::baseTypeMax());
}


template <class T>
inline void
Expand Down Expand Up @@ -277,6 +286,19 @@ Box<T>::isEmpty() const
return false;
}

template <class T>
inline bool
Box<T>::isInfinite() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax())
return false;
}

return true;
}


template <class T>
inline bool
Expand Down Expand Up @@ -350,6 +372,7 @@ class Box<Vec2<T> >
void makeEmpty();
void extendBy (const Vec2<T> &point);
void extendBy (const Box<Vec2<T> > &box);
void makeInfinite();

//---------------------------------------------------
// Query functions - these compute results each time
Expand All @@ -368,6 +391,7 @@ class Box<Vec2<T> >

bool isEmpty() const;
bool hasVolume() const;
bool isInfinite() const;
};


Expand Down Expand Up @@ -420,6 +444,13 @@ inline void Box<Vec2<T> >::makeEmpty()
max = Vec2<T>(Vec2<T>::baseTypeMin());
}

template <class T>
inline void Box<Vec2<T> >::makeInfinite()
{
min = Vec2<T>(Vec2<T>::baseTypeMin());
max = Vec2<T>(Vec2<T>::baseTypeMax());
}


template <class T>
inline void
Expand Down Expand Up @@ -511,6 +542,17 @@ Box<Vec2<T> >::isEmpty() const
return false;
}

template <class T>
inline bool
Box<Vec2<T> > ::isInfinite() const
{
if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
min[1] != limits<T>::min() || max[1] != limits<T>::max())
return false;

return true;
}


template <class T>
inline bool
Expand Down Expand Up @@ -572,6 +614,7 @@ class Box<Vec3<T> >
void makeEmpty();
void extendBy (const Vec3<T> &point);
void extendBy (const Box<Vec3<T> > &box);
void makeInfinite ();

//---------------------------------------------------
// Query functions - these compute results each time
Expand All @@ -590,6 +633,7 @@ class Box<Vec3<T> >

bool isEmpty() const;
bool hasVolume() const;
bool isInfinite() const;
};


Expand Down Expand Up @@ -643,6 +687,13 @@ inline void Box<Vec3<T> >::makeEmpty()
max = Vec3<T>(Vec3<T>::baseTypeMin());
}

template <class T>
inline void Box<Vec3<T> >::makeInfinite()
{
min = Vec3<T>(Vec3<T>::baseTypeMin());
max = Vec3<T>(Vec3<T>::baseTypeMax());
}


template <class T>
inline void
Expand Down Expand Up @@ -749,6 +800,18 @@ Box<Vec3<T> >::isEmpty() const
return false;
}

template <class T>
inline bool
Box<Vec3<T> >::isInfinite() const
{
if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
min[1] != limits<T>::min() || max[1] != limits<T>::max() ||
min[2] != limits<T>::min() || max[2] != limits<T>::max())
return false;

return true;
}


template <class T>
inline bool
Expand Down
157 changes: 151 additions & 6 deletions IlmBase/Imath/ImathBoxAlgo.h
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Copyright (c) 2002-2010, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
Expand Down Expand Up @@ -54,7 +54,13 @@
//
// Vec3<T> closestPointInBox(const Vec3<T>&, const Box<Vec3<T>>& )
//
// void transform(Box<Vec3<T>>&, const Matrix44<T>&)
// Box< Vec3<S> > transform(const Box<Vec3<S>>&, const Matrix44<T>&)
// Box< Vec3<S> > affineTransform(const Box<Vec3<S>>&, const Matrix44<T>&)
//
// void transform(const Box<Vec3<S>>&, const Matrix44<T>&, Box<V3ec3<S>>&)
// void affineTransform(const Box<Vec3<S>>&,
// const Matrix44<T>&,
// Box<V3ec3<S>>&)
//
// bool findEntryAndExitPoints(const Line<T> &line,
// const Box< Vec3<T> > &box,
Expand Down Expand Up @@ -167,10 +173,11 @@ transform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
//

//
// A transformed empty box is still empty
// A transformed empty box is still empty, and a transformed infinite box
// is still infinite
//

if (box.isEmpty())
if (box.isEmpty() || box.isInfinite())
return box;

//
Expand Down Expand Up @@ -234,6 +241,86 @@ transform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
return newBox;
}

template <class S, class T>
void
transform (const Box< Vec3<S> > &box,
const Matrix44<T> &m,
Box< Vec3<S> > &result)
{
//
// Transform a 3D box by a matrix, and compute a new box that
// tightly encloses the transformed box.
//
// If m is an affine transform, then we use James Arvo's fast
// method as described in "Graphics Gems", Academic Press, 1990,
// pp. 548-550.
//

//
// A transformed empty box is still empty, and a transformed infinite
// box is still infinite
//

if (box.isEmpty() || box.isInfinite())
{
return;
}

//
// If the last column of m is (0 0 0 1) then m is an affine
// transform, and we use the fast Graphics Gems trick.
//

if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1)
{
for (int i = 0; i < 3; i++)
{
result.min[i] = result.max[i] = (S) m[3][i];

for (int 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)
{
result.min[i] += a;
result.max[i] += b;
}
else
{
result.min[i] += b;
result.max[i] += a;
}
}
}

return;
}

//
// M is a projection matrix. Do things the naive way:
// Transform the eight corners of the box, and find an
// axis-parallel box that encloses the transformed corners.
//

Vec3<S> points[8];

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];

for (int i = 0; i < 8; i++)
result.extendBy (points[i] * m);
}


template <class S, class T>
Box< Vec3<S> >
Expand All @@ -248,10 +335,10 @@ affineTransform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
// fast method.
//

if (box.isEmpty())
if (box.isEmpty() || box.isInfinite())
{
//
// A transformed empty box is still empty
// A transformed empty or infinite box is still empty or infinite
//

return box;
Expand Down Expand Up @@ -286,6 +373,64 @@ affineTransform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
return newBox;
}

template <class S, class T>
void
affineTransform (const Box< Vec3<S> > &box,
const Matrix44<T> &m,
Box<Vec3<S> > &result)
{
//
// Transform a 3D box by a matrix whose rightmost column
// is (0 0 0 1), and compute a new box that tightly encloses
// the transformed box.
//
// As in the transform() function, above, we use James Arvo's
// fast method.
//

if (box.isEmpty())
{
//
// A transformed empty box is still empty
//
result.makeEmpty();
return;
}

if (box.isInfinite())
{
//
// A transformed infinite box is still infinite
//
result.makeInfinite();
return;
}

for (int i = 0; i < 3; i++)
{
result.min[i] = result.max[i] = (S) m[3][i];

for (int 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)
{
result.min[i] += a;
result.max[i] += b;
}
else
{
result.min[i] += b;
result.max[i] += a;
}
}
}
}


template <class T>
bool
Expand Down

0 comments on commit 1d922d7

Please sign in to comment.