Blame Imath/ImathBoxAlgo.h

Packit 8dc392
///////////////////////////////////////////////////////////////////////////
Packit 8dc392
//
Packit 8dc392
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
Packit 8dc392
// Digital Ltd. LLC
Packit 8dc392
// 
Packit 8dc392
// All rights reserved.
Packit 8dc392
// 
Packit 8dc392
// Redistribution and use in source and binary forms, with or without
Packit 8dc392
// modification, are permitted provided that the following conditions are
Packit 8dc392
// met:
Packit 8dc392
// *       Redistributions of source code must retain the above copyright
Packit 8dc392
// notice, this list of conditions and the following disclaimer.
Packit 8dc392
// *       Redistributions in binary form must reproduce the above
Packit 8dc392
// copyright notice, this list of conditions and the following disclaimer
Packit 8dc392
// in the documentation and/or other materials provided with the
Packit 8dc392
// distribution.
Packit 8dc392
// *       Neither the name of Industrial Light & Magic nor the names of
Packit 8dc392
// its contributors may be used to endorse or promote products derived
Packit 8dc392
// from this software without specific prior written permission. 
Packit 8dc392
// 
Packit 8dc392
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 8dc392
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 8dc392
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 8dc392
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 8dc392
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 8dc392
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 8dc392
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 8dc392
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 8dc392
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 8dc392
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 8dc392
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 8dc392
//
Packit 8dc392
///////////////////////////////////////////////////////////////////////////
Packit 8dc392
Packit 8dc392
Packit 8dc392
Packit 8dc392
#ifndef INCLUDED_IMATHBOXALGO_H
Packit 8dc392
#define INCLUDED_IMATHBOXALGO_H
Packit 8dc392
Packit 8dc392
Packit 8dc392
//---------------------------------------------------------------------------
Packit 8dc392
//
Packit 8dc392
//	This file contains algorithms applied to or in conjunction
Packit 8dc392
//	with bounding boxes (Imath::Box). These algorithms require
Packit 8dc392
//	more headers to compile. The assumption made is that these
Packit 8dc392
//	functions are called much less often than the basic box
Packit 8dc392
//	functions or these functions require more support classes.
Packit 8dc392
//
Packit 8dc392
//	Contains:
Packit 8dc392
//
Packit 8dc392
//	T clip<T>(const T& in, const Box<T>& box)
Packit 8dc392
//
Packit 8dc392
//	Vec3<T> closestPointOnBox(const Vec3<T>&, const Box<Vec3<T>>& )
Packit 8dc392
//
Packit 8dc392
//	Vec3<T> closestPointInBox(const Vec3<T>&, const Box<Vec3<T>>& )
Packit 8dc392
//
Packit 8dc392
//	Box< Vec3<S> > transform(const Box<Vec3<S>>&, const Matrix44<T>&)
Packit 8dc392
//	Box< Vec3<S> > affineTransform(const Box<Vec3<S>>&, const Matrix44<T>&)
Packit 8dc392
//
Packit 8dc392
//	void transform(const Box<Vec3<S>>&, const Matrix44<T>&, Box<V3ec3<S>>&)
Packit 8dc392
//	void affineTransform(const Box<Vec3<S>>&,
Packit 8dc392
//                           const Matrix44<T>&,
Packit 8dc392
//                           Box<V3ec3<S>>&)
Packit 8dc392
//
Packit 8dc392
//	bool findEntryAndExitPoints(const Line<T> &line,
Packit 8dc392
//				    const Box< Vec3<T> > &box,
Packit 8dc392
//				    Vec3<T> &enterPoint,
Packit 8dc392
//				    Vec3<T> &exitPoint)
Packit 8dc392
//
Packit 8dc392
//	bool intersects(const Box<Vec3<T>> &box, 
Packit 8dc392
//			const Line3<T> &ray, 
Packit 8dc392
//			Vec3<T> intersectionPoint)
Packit 8dc392
//
Packit 8dc392
//	bool intersects(const Box<Vec3<T>> &box, const Line3<T> &ray)
Packit 8dc392
//
Packit 8dc392
//---------------------------------------------------------------------------
Packit 8dc392
Packit 8dc392
#include "ImathBox.h"
Packit 8dc392
#include "ImathMatrix.h"
Packit 8dc392
#include "ImathLineAlgo.h"
Packit 8dc392
#include "ImathPlane.h"
Packit 8dc392
#include "ImathNamespace.h"
Packit 8dc392
Packit 8dc392
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
Packit 8dc392
Packit 8dc392
Packit 8dc392
template <class T>
Packit 8dc392
inline T
Packit 8dc392
clip (const T &p, const Box<T> &box)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Clip the coordinates of a point, p, against a box.
Packit 8dc392
    // The result, q, is the closest point to p that is inside the box.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    T q;
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < int (box.min.dimensions()); i++)
Packit 8dc392
    {
Packit 8dc392
	if (p[i] < box.min[i])
Packit 8dc392
	    q[i] = box.min[i];
Packit 8dc392
	else if (p[i] > box.max[i])
Packit 8dc392
	    q[i] = box.max[i];
Packit 8dc392
	else
Packit 8dc392
	    q[i] = p[i];
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    return q;
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template <class T>
Packit 8dc392
inline T
Packit 8dc392
closestPointInBox (const T &p, const Box<T> &box)
Packit 8dc392
{
Packit 8dc392
    return clip (p, box);
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template <class T>
Packit 8dc392
Vec3<T>
Packit 8dc392
closestPointOnBox (const Vec3<T> &p, const Box< Vec3<T> > &box)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Find the point, q, on the surface of
Packit 8dc392
    // the box, that is closest to point p.
Packit 8dc392
    //
Packit 8dc392
    // If the box is empty, return p.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (box.isEmpty())
Packit 8dc392
	return p;
Packit 8dc392
Packit 8dc392
    Vec3<T> q = closestPointInBox (p, box);
Packit 8dc392
Packit 8dc392
    if (q == p)
Packit 8dc392
    {
Packit 8dc392
	Vec3<T> d1 = p - box.min;
Packit 8dc392
	Vec3<T> d2 = box.max - p;
Packit 8dc392
Packit 8dc392
	Vec3<T> d ((d1.x < d2.x)? d1.x: d2.x,
Packit 8dc392
		   (d1.y < d2.y)? d1.y: d2.y,
Packit 8dc392
		   (d1.z < d2.z)? d1.z: d2.z);
Packit 8dc392
Packit 8dc392
	if (d.x < d.y && d.x < d.z)
Packit 8dc392
	{
Packit 8dc392
	    q.x = (d1.x < d2.x)? box.min.x: box.max.x;
Packit 8dc392
	}
Packit 8dc392
	else if (d.y < d.z)
Packit 8dc392
	{
Packit 8dc392
	    q.y = (d1.y < d2.y)? box.min.y: box.max.y;
Packit 8dc392
	}
Packit 8dc392
	else
Packit 8dc392
	{
Packit 8dc392
	    q.z = (d1.z < d2.z)? box.min.z: box.max.z;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    return q;
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template <class S, class T>
Packit 8dc392
Box< Vec3<S> >
Packit 8dc392
transform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Transform a 3D box by a matrix, and compute a new box that
Packit 8dc392
    // tightly encloses the transformed box.
Packit 8dc392
    //
Packit 8dc392
    // If m is an affine transform, then we use James Arvo's fast
Packit 8dc392
    // method as described in "Graphics Gems", Academic Press, 1990,
Packit 8dc392
    // pp. 548-550.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // A transformed empty box is still empty, and a transformed infinite box
Packit 8dc392
    // is still infinite
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (box.isEmpty() || box.isInfinite())
Packit 8dc392
	return box;
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // If the last column of m is (0 0 0 1) then m is an affine
Packit 8dc392
    // transform, and we use the fast Graphics Gems trick.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1)
Packit 8dc392
    {
Packit 8dc392
	Box< Vec3<S> > newBox;
Packit 8dc392
Packit 8dc392
	for (int i = 0; i < 3; i++) 
Packit 8dc392
        {
Packit 8dc392
	    newBox.min[i] = newBox.max[i] = (S) m[3][i];
Packit 8dc392
Packit 8dc392
	    for (int j = 0; j < 3; j++) 
Packit 8dc392
            {
Packit 8dc392
		S a, b;
Packit 8dc392
Packit 8dc392
		a = (S) m[j][i] * box.min[j];
Packit 8dc392
		b = (S) m[j][i] * box.max[j];
Packit 8dc392
Packit 8dc392
		if (a < b) 
Packit 8dc392
                {
Packit 8dc392
		    newBox.min[i] += a;
Packit 8dc392
		    newBox.max[i] += b;
Packit 8dc392
		}
Packit 8dc392
		else 
Packit 8dc392
                {
Packit 8dc392
		    newBox.min[i] += b;
Packit 8dc392
		    newBox.max[i] += a;
Packit 8dc392
		}
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	return newBox;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // M is a projection matrix.  Do things the naive way:
Packit 8dc392
    // Transform the eight corners of the box, and find an
Packit 8dc392
    // axis-parallel box that encloses the transformed corners.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    Vec3<S> points[8];
Packit 8dc392
Packit 8dc392
    points[0][0] = points[1][0] = points[2][0] = points[3][0] = box.min[0];
Packit 8dc392
    points[4][0] = points[5][0] = points[6][0] = points[7][0] = box.max[0];
Packit 8dc392
Packit 8dc392
    points[0][1] = points[1][1] = points[4][1] = points[5][1] = box.min[1];
Packit 8dc392
    points[2][1] = points[3][1] = points[6][1] = points[7][1] = box.max[1];
Packit 8dc392
Packit 8dc392
    points[0][2] = points[2][2] = points[4][2] = points[6][2] = box.min[2];
Packit 8dc392
    points[1][2] = points[3][2] = points[5][2] = points[7][2] = box.max[2];
Packit 8dc392
Packit 8dc392
    Box< Vec3<S> > newBox;
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 8; i++) 
Packit 8dc392
	newBox.extendBy (points[i] * m);
Packit 8dc392
Packit 8dc392
    return newBox;
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
template <class S, class T>
Packit 8dc392
void
Packit 8dc392
transform (const Box< Vec3<S> > &box,
Packit 8dc392
           const Matrix44<T>    &m,
Packit 8dc392
           Box< Vec3<S> >       &result)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Transform a 3D box by a matrix, and compute a new box that
Packit 8dc392
    // tightly encloses the transformed box.
Packit 8dc392
    //
Packit 8dc392
    // If m is an affine transform, then we use James Arvo's fast
Packit 8dc392
    // method as described in "Graphics Gems", Academic Press, 1990,
Packit 8dc392
    // pp. 548-550.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // A transformed empty box is still empty, and a transformed infinite
Packit 8dc392
    // box is still infinite
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (box.isEmpty() || box.isInfinite())
Packit 8dc392
    {
Packit 8dc392
	return;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // If the last column of m is (0 0 0 1) then m is an affine
Packit 8dc392
    // transform, and we use the fast Graphics Gems trick.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1)
Packit 8dc392
    {
Packit 8dc392
	for (int i = 0; i < 3; i++) 
Packit 8dc392
        {
Packit 8dc392
	    result.min[i] = result.max[i] = (S) m[3][i];
Packit 8dc392
Packit 8dc392
	    for (int j = 0; j < 3; j++) 
Packit 8dc392
            {
Packit 8dc392
		S a, b;
Packit 8dc392
Packit 8dc392
		a = (S) m[j][i] * box.min[j];
Packit 8dc392
		b = (S) m[j][i] * box.max[j];
Packit 8dc392
Packit 8dc392
		if (a < b) 
Packit 8dc392
                {
Packit 8dc392
		    result.min[i] += a;
Packit 8dc392
		    result.max[i] += b;
Packit 8dc392
		}
Packit 8dc392
		else 
Packit 8dc392
                {
Packit 8dc392
		    result.min[i] += b;
Packit 8dc392
		    result.max[i] += a;
Packit 8dc392
		}
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	return;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // M is a projection matrix.  Do things the naive way:
Packit 8dc392
    // Transform the eight corners of the box, and find an
Packit 8dc392
    // axis-parallel box that encloses the transformed corners.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    Vec3<S> points[8];
Packit 8dc392
Packit 8dc392
    points[0][0] = points[1][0] = points[2][0] = points[3][0] = box.min[0];
Packit 8dc392
    points[4][0] = points[5][0] = points[6][0] = points[7][0] = box.max[0];
Packit 8dc392
Packit 8dc392
    points[0][1] = points[1][1] = points[4][1] = points[5][1] = box.min[1];
Packit 8dc392
    points[2][1] = points[3][1] = points[6][1] = points[7][1] = box.max[1];
Packit 8dc392
Packit 8dc392
    points[0][2] = points[2][2] = points[4][2] = points[6][2] = box.min[2];
Packit 8dc392
    points[1][2] = points[3][2] = points[5][2] = points[7][2] = box.max[2];
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 8; i++) 
Packit 8dc392
	result.extendBy (points[i] * m);
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template <class S, class T>
Packit 8dc392
Box< Vec3<S> >
Packit 8dc392
affineTransform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Transform a 3D box by a matrix whose rightmost column
Packit 8dc392
    // is (0 0 0 1), and compute a new box that tightly encloses
Packit 8dc392
    // the transformed box.
Packit 8dc392
    //
Packit 8dc392
    // As in the transform() function, above, we use James Arvo's
Packit 8dc392
    // fast method.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (box.isEmpty() || box.isInfinite())
Packit 8dc392
    {
Packit 8dc392
	//
Packit 8dc392
	// A transformed empty or infinite box is still empty or infinite
Packit 8dc392
	//
Packit 8dc392
Packit 8dc392
	return box;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    Box< Vec3<S> > newBox;
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 3; i++) 
Packit 8dc392
    {
Packit 8dc392
	newBox.min[i] = newBox.max[i] = (S) m[3][i];
Packit 8dc392
Packit 8dc392
	for (int j = 0; j < 3; j++) 
Packit 8dc392
	{
Packit 8dc392
	    S a, b;
Packit 8dc392
Packit 8dc392
	    a = (S) m[j][i] * box.min[j];
Packit 8dc392
	    b = (S) m[j][i] * box.max[j];
Packit 8dc392
Packit 8dc392
	    if (a < b) 
Packit 8dc392
	    {
Packit 8dc392
		newBox.min[i] += a;
Packit 8dc392
		newBox.max[i] += b;
Packit 8dc392
	    }
Packit 8dc392
	    else 
Packit 8dc392
	    {
Packit 8dc392
		newBox.min[i] += b;
Packit 8dc392
		newBox.max[i] += a;
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    return newBox;
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
template <class S, class T>
Packit 8dc392
void
Packit 8dc392
affineTransform (const Box< Vec3<S> > &box,
Packit 8dc392
                 const Matrix44<T>    &m,
Packit 8dc392
                 Box<Vec3<S> >        &result)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Transform a 3D box by a matrix whose rightmost column
Packit 8dc392
    // is (0 0 0 1), and compute a new box that tightly encloses
Packit 8dc392
    // the transformed box.
Packit 8dc392
    //
Packit 8dc392
    // As in the transform() function, above, we use James Arvo's
Packit 8dc392
    // fast method.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (box.isEmpty())
Packit 8dc392
    {
Packit 8dc392
	//
Packit 8dc392
	// A transformed empty box is still empty
Packit 8dc392
	//
Packit 8dc392
        result.makeEmpty();
Packit 8dc392
	return;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    if (box.isInfinite())
Packit 8dc392
    {
Packit 8dc392
	//
Packit 8dc392
	// A transformed infinite box is still infinite
Packit 8dc392
	//
Packit 8dc392
        result.makeInfinite();
Packit 8dc392
	return;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 3; i++) 
Packit 8dc392
    {
Packit 8dc392
	result.min[i] = result.max[i] = (S) m[3][i];
Packit 8dc392
Packit 8dc392
	for (int j = 0; j < 3; j++) 
Packit 8dc392
	{
Packit 8dc392
	    S a, b;
Packit 8dc392
Packit 8dc392
	    a = (S) m[j][i] * box.min[j];
Packit 8dc392
	    b = (S) m[j][i] * box.max[j];
Packit 8dc392
Packit 8dc392
	    if (a < b) 
Packit 8dc392
	    {
Packit 8dc392
		result.min[i] += a;
Packit 8dc392
		result.max[i] += b;
Packit 8dc392
	    }
Packit 8dc392
	    else 
Packit 8dc392
	    {
Packit 8dc392
		result.min[i] += b;
Packit 8dc392
		result.max[i] += a;
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template <class T>
Packit 8dc392
bool
Packit 8dc392
findEntryAndExitPoints (const Line3<T> &r,
Packit 8dc392
			const Box<Vec3<T> > &b,
Packit 8dc392
			Vec3<T> &entry,
Packit 8dc392
			Vec3<T> &exit)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Compute the points where a ray, r, enters and exits a box, b:
Packit 8dc392
    //
Packit 8dc392
    // findEntryAndExitPoints() returns
Packit 8dc392
    //
Packit 8dc392
    //     - true if the ray starts inside the box or if the
Packit 8dc392
    //       ray starts outside and intersects the box
Packit 8dc392
    //
Packit 8dc392
    //	   - false otherwise (that is, if the ray does not
Packit 8dc392
    //       intersect the box)
Packit 8dc392
    //
Packit 8dc392
    // The entry and exit points are
Packit 8dc392
    //
Packit 8dc392
    //     - points on two of the faces of the box when
Packit 8dc392
    //       findEntryAndExitPoints() returns true
Packit 8dc392
    //       (The entry end exit points may be on either
Packit 8dc392
    //       side of the ray's origin)
Packit 8dc392
    //
Packit 8dc392
    //     - undefined when findEntryAndExitPoints()
Packit 8dc392
    //       returns false
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (b.isEmpty())
Packit 8dc392
    {
Packit 8dc392
	//
Packit 8dc392
	// No ray intersects an empty box
Packit 8dc392
	//
Packit 8dc392
Packit 8dc392
	return false;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // The following description assumes that the ray's origin is outside
Packit 8dc392
    // the box, but the code below works even if the origin is inside the
Packit 8dc392
    // box:
Packit 8dc392
    //
Packit 8dc392
    // Between one and three "frontfacing" sides of the box are oriented
Packit 8dc392
    // towards the ray's origin, and between one and three "backfacing"
Packit 8dc392
    // sides are oriented away from the ray's origin.
Packit 8dc392
    // We intersect the ray with the planes that contain the sides of the
Packit 8dc392
    // box, and compare the distances between the ray's origin and the
Packit 8dc392
    // ray-plane intersections.  The ray intersects the box if the most
Packit 8dc392
    // distant frontfacing intersection is nearer than the nearest
Packit 8dc392
    // backfacing intersection.  If the ray does intersect the box, then
Packit 8dc392
    // the most distant frontfacing ray-plane intersection is the entry
Packit 8dc392
    // point and the nearest backfacing ray-plane intersection is the
Packit 8dc392
    // exit point.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    const T TMAX = limits<T>::max();
Packit 8dc392
Packit 8dc392
    T tFrontMax = -TMAX;
Packit 8dc392
    T tBackMin = TMAX;
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Minimum and maximum X sides.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (r.dir.x >= 0)
Packit 8dc392
    {
Packit 8dc392
	T d1 = b.max.x - r.pos.x;
Packit 8dc392
	T d2 = b.min.x - r.pos.x;
Packit 8dc392
Packit 8dc392
	if (r.dir.x > 1 ||
Packit 8dc392
	    (abs (d1) < TMAX * r.dir.x &&
Packit 8dc392
	     abs (d2) < TMAX * r.dir.x))
Packit 8dc392
	{
Packit 8dc392
	    T t1 = d1 / r.dir.x;
Packit 8dc392
	    T t2 = d2 / r.dir.x;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t1)
Packit 8dc392
	    {
Packit 8dc392
		tBackMin = t1;
Packit 8dc392
Packit 8dc392
		exit.x = b.max.x; 
Packit 8dc392
		exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t2)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t2;
Packit 8dc392
Packit 8dc392
		entry.x = b.min.x; 
Packit 8dc392
		entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
	else if (r.pos.x < b.min.x || r.pos.x > b.max.x)
Packit 8dc392
	{
Packit 8dc392
	    return false;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else // r.dir.x < 0
Packit 8dc392
    {
Packit 8dc392
	T d1 = b.min.x - r.pos.x;
Packit 8dc392
	T d2 = b.max.x - r.pos.x;
Packit 8dc392
Packit 8dc392
	if (r.dir.x < -1 ||
Packit 8dc392
	    (abs (d1) < -TMAX * r.dir.x &&
Packit 8dc392
	     abs (d2) < -TMAX * r.dir.x))
Packit 8dc392
	{
Packit 8dc392
	    T t1 = d1 / r.dir.x;
Packit 8dc392
	    T t2 = d2 / r.dir.x;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t1)
Packit 8dc392
	    {
Packit 8dc392
		tBackMin = t1;
Packit 8dc392
Packit 8dc392
		exit.x = b.min.x; 
Packit 8dc392
		exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t2)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t2;
Packit 8dc392
Packit 8dc392
		entry.x = b.max.x; 
Packit 8dc392
		entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
	else if (r.pos.x < b.min.x || r.pos.x > b.max.x)
Packit 8dc392
	{
Packit 8dc392
	    return false;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Minimum and maximum Y sides.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (r.dir.y >= 0)
Packit 8dc392
    {
Packit 8dc392
	T d1 = b.max.y - r.pos.y;
Packit 8dc392
	T d2 = b.min.y - r.pos.y;
Packit 8dc392
Packit 8dc392
	if (r.dir.y > 1 ||
Packit 8dc392
	    (abs (d1) < TMAX * r.dir.y &&
Packit 8dc392
	     abs (d2) < TMAX * r.dir.y))
Packit 8dc392
	{
Packit 8dc392
	    T t1 = d1 / r.dir.y;
Packit 8dc392
	    T t2 = d2 / r.dir.y;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t1)
Packit 8dc392
	    {
Packit 8dc392
		tBackMin = t1;
Packit 8dc392
Packit 8dc392
		exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		exit.y = b.max.y; 
Packit 8dc392
		exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t2)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t2;
Packit 8dc392
Packit 8dc392
		entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		entry.y = b.min.y; 
Packit 8dc392
		entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
	else if (r.pos.y < b.min.y || r.pos.y > b.max.y)
Packit 8dc392
	{
Packit 8dc392
	    return false;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else // r.dir.y < 0
Packit 8dc392
    {
Packit 8dc392
	T d1 = b.min.y - r.pos.y;
Packit 8dc392
	T d2 = b.max.y - r.pos.y;
Packit 8dc392
Packit 8dc392
	if (r.dir.y < -1 ||
Packit 8dc392
	    (abs (d1) < -TMAX * r.dir.y &&
Packit 8dc392
	     abs (d2) < -TMAX * r.dir.y))
Packit 8dc392
	{
Packit 8dc392
	    T t1 = d1 / r.dir.y;
Packit 8dc392
	    T t2 = d2 / r.dir.y;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t1)
Packit 8dc392
	    {
Packit 8dc392
		tBackMin = t1;
Packit 8dc392
Packit 8dc392
		exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		exit.y = b.min.y; 
Packit 8dc392
		exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t2)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t2;
Packit 8dc392
Packit 8dc392
		entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		entry.y = b.max.y; 
Packit 8dc392
		entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
	else if (r.pos.y < b.min.y || r.pos.y > b.max.y)
Packit 8dc392
	{
Packit 8dc392
	    return false;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Minimum and maximum Z sides.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (r.dir.z >= 0)
Packit 8dc392
    {
Packit 8dc392
	T d1 = b.max.z - r.pos.z;
Packit 8dc392
	T d2 = b.min.z - r.pos.z;
Packit 8dc392
Packit 8dc392
	if (r.dir.z > 1 ||
Packit 8dc392
	    (abs (d1) < TMAX * r.dir.z &&
Packit 8dc392
	     abs (d2) < TMAX * r.dir.z))
Packit 8dc392
	{
Packit 8dc392
	    T t1 = d1 / r.dir.z;
Packit 8dc392
	    T t2 = d2 / r.dir.z;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t1)
Packit 8dc392
	    {
Packit 8dc392
		tBackMin = t1;
Packit 8dc392
Packit 8dc392
		exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		exit.z = b.max.z; 
Packit 8dc392
	    }
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t2)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t2;
Packit 8dc392
Packit 8dc392
		entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		entry.z = b.min.z; 
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
	else if (r.pos.z < b.min.z || r.pos.z > b.max.z)
Packit 8dc392
	{
Packit 8dc392
	    return false;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else // r.dir.z < 0
Packit 8dc392
    {
Packit 8dc392
	T d1 = b.min.z - r.pos.z;
Packit 8dc392
	T d2 = b.max.z - r.pos.z;
Packit 8dc392
Packit 8dc392
	if (r.dir.z < -1 ||
Packit 8dc392
	    (abs (d1) < -TMAX * r.dir.z &&
Packit 8dc392
	     abs (d2) < -TMAX * r.dir.z))
Packit 8dc392
	{
Packit 8dc392
	    T t1 = d1 / r.dir.z;
Packit 8dc392
	    T t2 = d2 / r.dir.z;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t1)
Packit 8dc392
	    {
Packit 8dc392
		tBackMin = t1;
Packit 8dc392
Packit 8dc392
		exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		exit.z = b.min.z; 
Packit 8dc392
	    }
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t2)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t2;
Packit 8dc392
Packit 8dc392
		entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		entry.z = b.max.z; 
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
	else if (r.pos.z < b.min.z || r.pos.z > b.max.z)
Packit 8dc392
	{
Packit 8dc392
	    return false;
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    return tFrontMax <= tBackMin;
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template<class T>
Packit 8dc392
bool
Packit 8dc392
intersects (const Box< Vec3<T> > &b, const Line3<T> &r, Vec3<T> &ip)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Intersect a ray, r, with a box, b, and compute the intersection
Packit 8dc392
    // point, ip:
Packit 8dc392
    //
Packit 8dc392
    // intersect() returns
Packit 8dc392
    //
Packit 8dc392
    //     - true if the ray starts inside the box or if the
Packit 8dc392
    //       ray starts outside and intersects the box
Packit 8dc392
    //
Packit 8dc392
    //     - false if the ray starts outside the box and intersects it,
Packit 8dc392
    //       but the intersection is behind the ray's origin.
Packit 8dc392
    //
Packit 8dc392
    //     - false if the ray starts outside and does not intersect it
Packit 8dc392
    //
Packit 8dc392
    // The intersection point is
Packit 8dc392
    //
Packit 8dc392
    //     - the ray's origin if the ray starts inside the box
Packit 8dc392
    //
Packit 8dc392
    //     - a point on one of the faces of the box if the ray
Packit 8dc392
    //       starts outside the box
Packit 8dc392
    //
Packit 8dc392
    //     - undefined when intersect() returns false
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (b.isEmpty())
Packit 8dc392
    {
Packit 8dc392
	//
Packit 8dc392
	// No ray intersects an empty box
Packit 8dc392
	//
Packit 8dc392
Packit 8dc392
	return false;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    if (b.intersects (r.pos))
Packit 8dc392
    {
Packit 8dc392
	//
Packit 8dc392
	// The ray starts inside the box
Packit 8dc392
	//
Packit 8dc392
Packit 8dc392
	ip = r.pos;
Packit 8dc392
	return true;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // The ray starts outside the box.  Between one and three "frontfacing"
Packit 8dc392
    // sides of the box are oriented towards the ray, and between one and
Packit 8dc392
    // three "backfacing" sides are oriented away from the ray.
Packit 8dc392
    // We intersect the ray with the planes that contain the sides of the
Packit 8dc392
    // box, and compare the distances between ray's origin and the ray-plane
Packit 8dc392
    // intersections.
Packit 8dc392
    // The ray intersects the box if the most distant frontfacing intersection
Packit 8dc392
    // is nearer than the nearest backfacing intersection.  If the ray does
Packit 8dc392
    // intersect the box, then the most distant frontfacing ray-plane
Packit 8dc392
    // intersection is the ray-box intersection.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    const T TMAX = limits<T>::max();
Packit 8dc392
Packit 8dc392
    T tFrontMax = -1;
Packit 8dc392
    T tBackMin = TMAX;
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Minimum and maximum X sides.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (r.dir.x > 0)
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.x > b.max.x)
Packit 8dc392
	    return false;
Packit 8dc392
Packit 8dc392
	T d = b.max.x - r.pos.x;
Packit 8dc392
Packit 8dc392
	if (r.dir.x > 1 || d < TMAX * r.dir.x)
Packit 8dc392
	{
Packit 8dc392
	    T t = d / r.dir.x;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t)
Packit 8dc392
		tBackMin = t;
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	if (r.pos.x <= b.min.x)
Packit 8dc392
	{
Packit 8dc392
	    T d = b.min.x - r.pos.x;
Packit 8dc392
	    T t = (r.dir.x > 1 || d < TMAX * r.dir.x)? d / r.dir.x: TMAX;
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t;
Packit 8dc392
Packit 8dc392
		ip.x = b.min.x; 
Packit 8dc392
		ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else if (r.dir.x < 0)
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.x < b.min.x)
Packit 8dc392
	    return false;
Packit 8dc392
Packit 8dc392
	T d = b.min.x - r.pos.x;
Packit 8dc392
Packit 8dc392
	if (r.dir.x < -1 || d > TMAX * r.dir.x)
Packit 8dc392
	{
Packit 8dc392
	    T t = d / r.dir.x;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t)
Packit 8dc392
		tBackMin = t;
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	if (r.pos.x >= b.max.x)
Packit 8dc392
	{
Packit 8dc392
	    T d = b.max.x - r.pos.x;
Packit 8dc392
	    T t = (r.dir.x < -1 || d > TMAX * r.dir.x)? d / r.dir.x: TMAX;
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t;
Packit 8dc392
Packit 8dc392
		ip.x = b.max.x; 
Packit 8dc392
		ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else // r.dir.x == 0
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.x < b.min.x || r.pos.x > b.max.x)
Packit 8dc392
	    return false;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Minimum and maximum Y sides.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (r.dir.y > 0)
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.y > b.max.y)
Packit 8dc392
	    return false;
Packit 8dc392
Packit 8dc392
	T d = b.max.y - r.pos.y;
Packit 8dc392
Packit 8dc392
	if (r.dir.y > 1 || d < TMAX * r.dir.y)
Packit 8dc392
	{
Packit 8dc392
	    T t = d / r.dir.y;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t)
Packit 8dc392
		tBackMin = t;
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	if (r.pos.y <= b.min.y)
Packit 8dc392
	{
Packit 8dc392
	    T d = b.min.y - r.pos.y;
Packit 8dc392
	    T t = (r.dir.y > 1 || d < TMAX * r.dir.y)? d / r.dir.y: TMAX;
Packit 8dc392
Packit 8dc392
	    if (tFrontMax < t)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t;
Packit 8dc392
Packit 8dc392
		ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		ip.y = b.min.y; 
Packit 8dc392
		ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else if (r.dir.y < 0)
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.y < b.min.y)
Packit 8dc392
	    return false;
Packit 8dc392
Packit 8dc392
	T d = b.min.y - r.pos.y;
Packit 8dc392
Packit 8dc392
	if (r.dir.y < -1 || d > TMAX * r.dir.y)
Packit 8dc392
	{
Packit 8dc392
	    T t = d / r.dir.y;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t)
Packit 8dc392
		tBackMin = t;
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	if (r.pos.y >= b.max.y)
Packit 8dc392
	{
Packit 8dc392
	    T d = b.max.y - r.pos.y;
Packit 8dc392
	    T t = (r.dir.y < -1 || d > TMAX * r.dir.y)? d / r.dir.y: TMAX;
Packit 8dc392
	    
Packit 8dc392
	    if (tFrontMax < t)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t;
Packit 8dc392
Packit 8dc392
		ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		ip.y = b.max.y; 
Packit 8dc392
		ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else // r.dir.y == 0
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.y < b.min.y || r.pos.y > b.max.y)
Packit 8dc392
	    return false;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Minimum and maximum Z sides.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    if (r.dir.z > 0)
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.z > b.max.z)
Packit 8dc392
	    return false;
Packit 8dc392
Packit 8dc392
	T d = b.max.z - r.pos.z;
Packit 8dc392
Packit 8dc392
	if (r.dir.z > 1 || d < TMAX * r.dir.z)
Packit 8dc392
	{
Packit 8dc392
	    T t = d / r.dir.z;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t)
Packit 8dc392
		tBackMin = t;
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	if (r.pos.z <= b.min.z)
Packit 8dc392
	{
Packit 8dc392
	    T d = b.min.z - r.pos.z;
Packit 8dc392
	    T t = (r.dir.z > 1 || d < TMAX * r.dir.z)? d / r.dir.z: TMAX;
Packit 8dc392
	    
Packit 8dc392
	    if (tFrontMax < t)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t;
Packit 8dc392
Packit 8dc392
		ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		ip.z = b.min.z; 
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else if (r.dir.z < 0)
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.z < b.min.z)
Packit 8dc392
	    return false;
Packit 8dc392
Packit 8dc392
	T d = b.min.z - r.pos.z;
Packit 8dc392
Packit 8dc392
	if (r.dir.z < -1 || d > TMAX * r.dir.z)
Packit 8dc392
	{
Packit 8dc392
	    T t = d / r.dir.z;
Packit 8dc392
Packit 8dc392
	    if (tBackMin > t)
Packit 8dc392
		tBackMin = t;
Packit 8dc392
	}
Packit 8dc392
Packit 8dc392
	if (r.pos.z >= b.max.z)
Packit 8dc392
	{
Packit 8dc392
	    T d = b.max.z - r.pos.z;
Packit 8dc392
	    T t = (r.dir.z < -1 || d > TMAX * r.dir.z)? d / r.dir.z: TMAX;
Packit 8dc392
	    
Packit 8dc392
	    if (tFrontMax < t)
Packit 8dc392
	    {
Packit 8dc392
		tFrontMax = t;
Packit 8dc392
Packit 8dc392
		ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
Packit 8dc392
		ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
Packit 8dc392
		ip.z = b.max.z; 
Packit 8dc392
	    }
Packit 8dc392
	}
Packit 8dc392
    }
Packit 8dc392
    else // r.dir.z == 0
Packit 8dc392
    {
Packit 8dc392
	if (r.pos.z < b.min.z || r.pos.z > b.max.z)
Packit 8dc392
	    return false;
Packit 8dc392
    }
Packit 8dc392
Packit 8dc392
    return tFrontMax <= tBackMin;
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
template<class T>
Packit 8dc392
bool
Packit 8dc392
intersects (const Box< Vec3<T> > &box, const Line3<T> &ray)
Packit 8dc392
{
Packit 8dc392
    Vec3<T> ignored;
Packit 8dc392
    return intersects (box, ray, ignored);
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
Packit 8dc392
Packit 8dc392
#endif // INCLUDED_IMATHBOXALGO_H