📄 imathboxalgo.h
字号:
/////////////////////////////////////////////////////////////////////////////// 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> &ray, // Vec3<T> intersectionPoint)//// bool intersects(const Box<Vec3<T>> &box, const Line3<T> &ray)////---------------------------------------------------------------------------#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){ // // 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 // if (box.isEmpty()) return box; // // 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) { Box< Vec3<S> > newBox; for (int i = 0; i < 3; i++) { newBox.min[i] = newBox.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) { newBox.min[i] += a; newBox.max[i] += b; } else { newBox.min[i] += b; newBox.max[i] += a; } } } return newBox; } // // 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]; 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -