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

2 years ago
#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