#ifndef GEOH #define GEOH #include #include "ray.h" using namespace std; struct hit_record { float t; vec3 p; vec3 nv; vec3 kd; float wr; float wt; }; class hitable { //geometry parent class public: virtual bool hit(const ray &r, float tmin, float tmax, hit_record *rec) const = 0; }; class sphere : public hitable { public: sphere() {} sphere(vec3 c, float r, vec3 _kd = vec3(1.0, 1.0, 1.0), float w_ri = 0.0f, float w_ti = 0.0f) : center(c), radius(r), kd(_kd), w_r(w_ri), w_t(w_ti){}; bool hit(const ray &r, float tmin, float tmax, hit_record *rec) const; vec3 center; float radius; vec3 kd; float w_r; //reflected float w_t; //transmitted }; bool sphere::hit(const ray &r, float tmin, float tmax, hit_record *rec) const { float a, b, c, t; a = dot(r.D, r.D); b = 2 * (dot(r.D, (r.O - this->center))); c = dot(r.O - this->center, r.O - this->center) - this->radius * this->radius; if (((b * b) - (4 * a * c)) > 0) { if ((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin && (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) { t = min((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)), (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a))); } else if ((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) { t = (((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)); } else if ((((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) { t = (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)); } else { return false; } } else { return false; } if (t > tmax || t < tmin) { return false; } if (rec->t > t) { rec->t = t; rec->p = r.point_at_parameter(t); rec->nv = unit_vector(r.point_at_parameter(t) - this->center); rec->kd = this->kd; rec->wr = this->w_r; rec->wt = this->w_t; //cout << t << " " << rec->p << " " << rec->nv << endl; } return true; } vec3 reflect(const vec3 &d, const vec3 &nv) { return d - (2 * dot(d, nv) * nv); return vec3(0, 0, 0); } template float clamp(T bot, T top, T targ) { if (targ > top) { return top; } if (targ < bot) { return bot; } return targ; } vec3 refract(const vec3 &i, const vec3 &n, float eta) { vec3 I = unit_vector(i); vec3 N = unit_vector(n); //cout << I << " " << N << " " << dot(N, I) << endl; eta = 1 / eta; if (dot(N, I) > 0) { N = -1 * N; eta = 1 / eta; } float k = 1.0f - eta * eta * (1.0 - dot(N, I) * dot(N, I)); //cout << k << endl; if (k < 0.0) { return i - (2 * dot(i, n) * n); } //cout << eta * I - (eta * dot(N, I) + sqrt(k)) * N << endl; return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } #endif