nuclear@1: #include "ray.h" nuclear@1: #include "vector.h" nuclear@1: nuclear@1: scalar_t Ray::env_ior = 1.0; nuclear@1: nuclear@1: Ray::Ray() { nuclear@1: ior = env_ior; nuclear@1: energy = 1.0; nuclear@1: time = 0; nuclear@1: iter = 0; nuclear@1: } nuclear@1: nuclear@1: Ray::Ray(const Vector3 &origin, const Vector3 &dir) { nuclear@1: this->origin = origin; nuclear@1: this->dir = dir; nuclear@1: ior = env_ior; nuclear@1: energy = 1.0; nuclear@1: time = 0; nuclear@1: iter = 0; nuclear@1: } nuclear@1: nuclear@1: void Ray::transform(const Matrix4x4 &xform) { nuclear@1: Matrix4x4 upper; nuclear@1: Vector3 dir; nuclear@1: nuclear@1: upper = xform; nuclear@1: upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; nuclear@1: upper[3][3] = 1.0; nuclear@1: nuclear@1: dir = (this->dir - origin).transformed(upper); nuclear@1: origin.transform(xform); nuclear@1: this->dir = dir + origin; nuclear@1: } nuclear@1: nuclear@1: Ray Ray::transformed(const Matrix4x4 &xform) const { nuclear@1: Ray foo = *this; nuclear@1: foo.transform(xform); nuclear@1: return foo; nuclear@1: } nuclear@1: nuclear@1: void Ray::enter(scalar_t new_ior) { nuclear@1: ior = new_ior; nuclear@1: ior_stack.push(ior); nuclear@1: } nuclear@1: nuclear@1: void Ray::leave() { nuclear@1: if(ior_stack.empty()) { nuclear@1: //std::cerr << "empty ior stack?\n"; nuclear@1: return; nuclear@1: } nuclear@1: ior_stack.pop(); nuclear@1: ior = ior_stack.empty() ? env_ior : ior_stack.top(); nuclear@1: } nuclear@1: nuclear@1: scalar_t Ray::calc_ior(bool entering, scalar_t mat_ior) const nuclear@1: { nuclear@1: scalar_t from_ior = this->ior; nuclear@1: nuclear@1: if(entering) { nuclear@1: return from_ior / mat_ior; nuclear@1: } nuclear@1: nuclear@1: Ray tmp = *this; nuclear@1: tmp.leave(); nuclear@1: return from_ior / tmp.ior; nuclear@1: }