00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "bbox.h"
00025 #include "ray.h"
00026
00027 namespace lux
00028 {
00029
00030
00031 BBox Union(const BBox &b, const Point &p) {
00032 BBox ret = b;
00033 ret.pMin.x = min(b.pMin.x, p.x);
00034 ret.pMin.y = min(b.pMin.y, p.y);
00035 ret.pMin.z = min(b.pMin.z, p.z);
00036 ret.pMax.x = max(b.pMax.x, p.x);
00037 ret.pMax.y = max(b.pMax.y, p.y);
00038 ret.pMax.z = max(b.pMax.z, p.z);
00039 return ret;
00040 }
00041 BBox Union(const BBox &b, const BBox &b2) {
00042 BBox ret;
00043 ret.pMin.x = min(b.pMin.x, b2.pMin.x);
00044 ret.pMin.y = min(b.pMin.y, b2.pMin.y);
00045 ret.pMin.z = min(b.pMin.z, b2.pMin.z);
00046 ret.pMax.x = max(b.pMax.x, b2.pMax.x);
00047 ret.pMax.y = max(b.pMax.y, b2.pMax.y);
00048 ret.pMax.z = max(b.pMax.z, b2.pMax.z);
00049 return ret;
00050 }
00051
00052 void BBox::BoundingSphere(Point *c, float *rad) const {
00053 *c = .5f * pMin + .5f * pMax;
00054 *rad = Inside(*c) ? Distance(*c, pMax) : 0.f;
00055 }
00056
00057 #if defined(WIN32) && !defined(__CYGWIN__)
00058 #pragma float_control(push)
00059 #pragma float_control(precise, on)
00060 #endif
00061 bool BBox::IntersectP(const Ray &ray, float *hitt0,
00062 float *hitt1) const {
00063 float t0 = ray.mint, t1 = ray.maxt;
00064 for (int i = 0; i < 3; ++i) {
00065
00066 float invRayDir = 1.f / ray.d[i];
00067 float tNear = (pMin[i] - ray.o[i]) * invRayDir;
00068 float tFar = (pMax[i] - ray.o[i]) * invRayDir;
00069
00070 if (tNear > tFar) swap(tNear, tFar);
00071 t0 = tNear > t0 ? tNear : t0;
00072 t1 = tFar < t1 ? tFar : t1;
00073 if (t0 > t1) return false;
00074 }
00075 if (hitt0) *hitt0 = t0;
00076 if (hitt1) *hitt1 = t1;
00077 return true;
00078 }
00079 #if defined(WIN32) && !defined(__CYGWIN__)
00080 #pragma float_control(pop)
00081 #endif
00082
00083 }