You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.9 KiB
101 lines
2.9 KiB
#ifndef GEOH
|
|
#define GEOH
|
|
#include <cmath>
|
|
|
|
#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 <typename T>
|
|
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 |