// // Created by Keuin on 2022/4/11. // #ifndef RT_RAY_H #define RT_RAY_H #include "vec.h" #include "bitmap.h" // A ray is a half-line, starts from a 3d point, along the direction of a unit vector, to the infinity template class ray3 { vec3 source_; vec3 direction_; // unit vector vec3d decay_; // How much power remaining public: ~ray3() = default; ray3() = delete; ray3(const ray3 &other) = default; ray3 &operator=(const ray3 &other) { source_ = other.source_; direction_ = other.direction_; decay_ = other.decay_; return *this; } ray3(const vec3 &source, const vec3 &direction) : source_(source), direction_(direction.unit_vec()), decay_{vec3d::one()} {} // Get the source point from where the ray emits. vec3 source() const { return source_; } void source(const vec3 &s) { source_ = s; } // Get the unit vector along the ray's direction. vec3 direction() const { return direction_; } // d should be a unit vector void direction(const vec3 &d) { assert(fabs(d.mod2() - 1.0) < 1e-6); direction_ = d; } // Compute the point this ray reaches at the time `t`. template vec3 at(U t) const { return source_ + direction_ * t; } // Get the final color we got at the ray's origin, by tracing back along with the ray's path. // Currently, here is only a simple power decay accumulation. template pixel hit(const pixel &color) const { return decay_ * color; } void decay(const vec3d &a) { decay_ = decay_.scale(a); } vec3d decay() const { return decay_; } // Get a ray starts from zero and directs to undefined direction. static ray3 null() { return ray3{vec3::zero(), vec3::zero()}; } }; using ray3d = ray3; #endif //RT_RAY_H