nuclear@0: #include "box.h" nuclear@0: nuclear@0: Box::Box() nuclear@0: : min(-0.5, -0.5, -0.5), max(0.5, 0.5, 0.5) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: Box::Box(const Vector3 &min_arg, const Vector3 &max_arg) nuclear@0: : min(min_arg), max(max_arg) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: bool Box::intersect(const Ray &inray, HitPoint *pt) const nuclear@0: { nuclear@0: Ray ray = inray.transformed(inv_xform); nuclear@0: nuclear@0: Vector3 param[2] = {min, max}; nuclear@0: Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z); nuclear@0: int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0}; nuclear@0: nuclear@0: float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x; nuclear@0: float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x; nuclear@0: float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y; nuclear@0: float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y; nuclear@0: nuclear@0: pt->normal = Vector3(ray.origin.x > 0.0 ? 1 : -1, 0, 0); nuclear@0: nuclear@0: if(tmin > tymax || tymin > tmax) { nuclear@0: return false; nuclear@0: } nuclear@0: if(tymin > tmin) { nuclear@0: pt->normal = Vector3(0, ray.origin.y > 0.0 ? 1 : -1, 0); nuclear@0: tmin = tymin; nuclear@0: } nuclear@0: if(tymax < tmax) { nuclear@0: tmax = tymax; nuclear@0: } nuclear@0: nuclear@0: float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z; nuclear@0: float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z; nuclear@0: nuclear@0: if(tmin > tzmax || tzmin > tmax) { nuclear@0: return false; nuclear@0: } nuclear@0: if(tzmin > tmin) { nuclear@0: pt->normal = Vector3(0, 0, ray.origin.z > 0.0 ? 1 : -1); nuclear@0: tmin = tzmin; nuclear@0: } nuclear@0: if(tzmax < tmax) { nuclear@0: tmax = tzmax; nuclear@0: } nuclear@0: nuclear@0: float t = tmin < 1e-4 ? tmax : tmin; nuclear@0: if(t >= 1e-4) { nuclear@0: pt->obj = this; nuclear@0: pt->dist = t; nuclear@0: pt->pos = ray.origin + ray.dir * t; nuclear@0: pt->pos.transform(xform); nuclear@0: pt->normal.transform(dir_xform); nuclear@0: return true; nuclear@0: } nuclear@0: return false; nuclear@0: }