34 #ifndef OPENVDB_MATH_FRUSTUM_HAS_BEEN_INCLUDED
35 #define OPENVDB_MATH_FRUSTUM_HAS_BEEN_INCLUDED
62 template<
typename Real>
80 mFace[0]=other.mFace[0];
81 mFace[1]=other.mFace[1];
82 mFace[2]=other.mFace[2];
83 mFace[3]=other.mFace[3];
84 mFace[4]=other.mFace[4];
85 mFace[5]=other.mFace[5];
123 initFromCamera(position, direction, up, left, zNear, zFar);
137 Vector center_near = 0.25*(ll + lr + ul + ur);
138 Vector up = 0.5 * (ul + ur ) - center_near;
139 Vector left = 0.5 * (ul + ll) - center_near;
147 Vector center_far = 0.25*(ll + lr + ul + ur);
149 Vector direction = center_far - center_near;
154 Real zFar = zNear + depth;
156 Vector position = translation - zNear*direction;
158 initFromCamera(position, direction, up, left, zNear, zFar);
164 void rescaleLerp(
const Point &unit_min,
const Point &unit_max)
166 assert(this->isValid());
169 tmp = mFace[0].
lerpPoints(mFace[1], unit_min[2]);
170 mFace[1] = mFace[1].
lerpPoints(mFace[0],1-unit_max[2]);
184 tmp = mFace[2].
lerp(mFace[3],unit_min[0]);
187 mFace[3] = mFace[2].lerp(mFace[3],unit_max[0]);
192 tmp = mFace[5].
lerp(mFace[4],unit_max[1]);
195 mFace[5] = mFace[5].lerp(mFace[4],unit_min[1]);
202 void rescaleSlerp(
const Point &unit_min,
const Point &unit_max)
204 assert(this->isValid());
207 tmp = mFace[0].
lerpPoints(mFace[1], unit_min[2]);
208 mFace[1] = mFace[1].
lerpPoints(mFace[0],1-unit_max[2]);
220 tmp = mFace[2].
slerp(mFace[3],unit_min[0]);
223 mFace[3] = mFace[2].slerp(mFace[3],unit_max[0]);
228 tmp = mFace[5].
slerp(mFace[4],unit_max[1]);
231 mFace[5] = mFace[5].slerp(mFace[4],unit_min[1]);
237 return mFace[0]==other.mFace[0] && mFace[1]==other.mFace[1]
238 && mFace[2]==other.mFace[2] && mFace[3]==other.mFace[3]
239 && mFace[4]==other.mFace[4] && mFace[5]==other.mFace[5];
244 return !(*
this == other);
249 inline bool isInside(
const Point &pt)
const
251 return mFace[0].isInside(pt) && mFace[1].isInside(pt)
252 && mFace[2].isInside(pt) && mFace[3].isInside(pt)
253 && mFace[4].isInside(pt) && mFace[5].isInside(pt);
258 inline bool isOutside(
const Point &pt)
const
260 return mFace[0].isOutside(pt) || mFace[1].isOutside(pt)
261 || mFace[2].isOutside(pt) || mFace[3].isOutside(pt)
262 || mFace[4].isOutside(pt) || mFace[5].isOutside(pt);
268 inline bool isValid()
const
270 return mFace[0].isValid() && mFace[1].isValid()
271 && mFace[2].isValid() && mFace[3].isValid()
272 && mFace[4].isValid() && mFace[5].isValid();
298 case 0 :
return "front";
break;
299 case 1 :
return "back ";
break;
300 case 2 :
return "left ";
break;
301 case 3 :
return "right";
break;
302 case 4 :
return "upper";
break;
303 case 5 :
return "lower";
break;
328 for (
int p=0; p<6; ++p) {
330 const Real dist = mFace[p].getNorm().dot(ray.
getOrigin())-mFace[p].getDist();
332 if (dist > 0)
return 0;
334 const Real t = -dist / angl ;
336 if ( t > t1 )
return 0;
339 if ( t < t0 )
return 0;
349 return hits>0 ? hits : -1;
357 return this->intersects(ray,t0,t1)!=0;
364 return this->intersects(ray,t0,t1)==-1;
375 const Point P[7]={transform.
indexToWorld(Vector(0,0,0)),
383 mFace[0]=PlaneType(P[0],P[1],P[2]);
384 if (mFace[0].getNorm().dot(P[4]-P[0]) >= 0) {
387 mFace[2]=PlaneType(P[0],P[4],P[2]);
388 mFace[3]=PlaneType(P[1],P[3],P[5]);
389 mFace[4]=PlaneType(P[2],P[6],P[3]);
390 mFace[5]=PlaneType(P[0],P[1],P[4]);
393 mFace[2]=PlaneType(P[0],P[2],P[4]);
394 mFace[3]=PlaneType(P[1],P[5],P[3]);
395 mFace[4]=PlaneType(P[2],P[3],P[6]);
396 mFace[5]=PlaneType(P[0],P[4],P[1]);
398 mFace[1].set(P[4],-mFace[0].getNorm());
401 void initFromCamera(
const Point &position,
402 const Vector &direction,
409 const Vector center = direction*zNear;
412 const Vector base[4]={center - up - left,
417 const Vector pos1 = position + base[1];
418 const Vector pos2 = position + base[2];
420 mFace[0].set(pos2,-direction);
421 mFace[1].set(position+direction*zFar,direction);
423 typedef typename PlaneType::Normalize NormalizedPlane;
424 mFace[2].set(pos1, base[3].cross(base[1]), NormalizedPlane());
425 mFace[3].set(pos2, base[0].cross(base[2]), NormalizedPlane());
427 mFace[4].set(pos2, base[2].cross(base[3]), NormalizedPlane());
428 mFace[5].set(pos1, base[1].cross(base[0]), NormalizedPlane());
435 template <
typename Real>
436 inline std::ostream &operator<<(std::ostream &os, const Frustum<Real> &f) {
437 for (
int i=0; i<6; ++i) os <<
"Frustum " << f.getFaceName(i)
438 <<
" face: " << f.getPlane(i) << std::endl;
452 Coord tmpMin, tmpMax;
461 Mat4d tmpW2C, tmpC2S, tmpS2C, tmpWorldToLocal;
462 Mat4d tmpS2U, tmpXYLocalToUnit, tmpZLocalToUnit;
469 is.
read(reinterpret_cast<char*>(&tmpW2C),
471 is.read(reinterpret_cast<char*>(&mC2W),
473 is.read(reinterpret_cast<char*>(&tmpC2S),
475 is.read(reinterpret_cast<char*>(&tmpS2C),
477 is.read(reinterpret_cast<char*>(&tmpWorldToLocal),
479 is.read(reinterpret_cast<char*>(&mLocalToWorld),
482 is.read(reinterpret_cast<char*>(&tmpWindow[0]),
sizeof(
Real));
483 is.read(reinterpret_cast<char*>(&tmpWindow[1]),
sizeof(
Real));
484 is.read(reinterpret_cast<char*>(&tmpWindow[2]),
sizeof(
Real));
485 is.read(reinterpret_cast<char*>(&tmpWindow[3]),
sizeof(
Real));
486 is.read(reinterpret_cast<char*>(&tmpWindow[4]),
sizeof(
Real));
487 is.read(reinterpret_cast<char*>(&tmpWindow[5]),
sizeof(
Real));
489 is.read(reinterpret_cast<char*>(&tmpPadding),
sizeof(
Real));
491 is.read(reinterpret_cast<char*>(&tmpS2U),
493 is.read(reinterpret_cast<char*>(&mXYUnitToLocal),
495 is.read(reinterpret_cast<char*>(&tmpXYLocalToUnit),
497 is.read(reinterpret_cast<char*>(&mZUnitToLocal),
499 is.read(reinterpret_cast<char*>(&tmpZLocalToUnit),
503 mNearPlane = tmpWindow[4];
504 mFarPlane = tmpWindow[5];
508 mFrNearOrigin = unitToLocalFrustum(
Vec3R(0,0,0));
509 mFrFarOrigin = unitToLocalFrustum(
Vec3R(0,0,1));
511 Vec3d frNearXTip = unitToLocalFrustum(
Vec3R(1,0,0));
512 Vec3d frNearYTip = unitToLocalFrustum(
Vec3R(0,1,0));
513 mFrNearXBasis = frNearXTip - mFrNearOrigin;
514 mFrNearYBasis = frNearYTip - mFrNearOrigin;
516 Vec3R frFarXTip = unitToLocalFrustum(
Vec3R(1,0,1));
517 Vec3R frFarYTip = unitToLocalFrustum(
Vec3R(0,1,1));
518 mFrFarXBasis = frFarXTip - mFrFarOrigin;
519 mFrFarYBasis = frFarYTip - mFrFarOrigin;
527 double getDepth()
const {
return (mFarPlane - mNearPlane); }
530 return getNearPlaneWidth() / getFarPlaneWidth();
534 double nearPlaneWidth = (unitToWorld(
Vec3d(0,0,0)) - unitToWorld(
Vec3d(1,0,0))).length();
535 return nearPlaneWidth;
539 double farPlaneWidth = (unitToWorld(
Vec3d(0,0,1)) - unitToWorld(
Vec3d(1,0,1))).length();
540 return farPlaneWidth;
558 Vec3d nearLS = ( U[0] * mFrNearXBasis ) + ( U[1] * mFrNearYBasis ) + mFrNearOrigin;
559 Vec3d farLS = ( U[0] * mFrFarXBasis ) + ( U[1] * mFrFarYBasis ) + mFrFarOrigin;
562 return U[2] * farLS + ( 1.0 - U[2] ) * nearLS;
565 Vec3d unitToLocalFrustum(
const Vec3d& u)
const {
566 Vec3d fzu = mZUnitToLocal.transformH(u);
569 return mXYUnitToLocal.transformH(fu);
575 Mat4d mC2W, mLocalToWorld, mXYUnitToLocal, mZUnitToLocal;
577 Vec3d mFrNearXBasis, mFrNearYBasis, mFrFarXBasis, mFrFarYBasis;
578 Vec3d mFrNearOrigin, mFrFarOrigin;
579 double mNearPlane, mFarPlane;
588 #endif // OPENVDB_MATH_FRUSTUM_HAS_BEEN_INCLUDED