Add Hittable_list

This commit is contained in:
Faerbit 2020-06-04 00:15:32 +02:00
parent bc63a68061
commit 881141a912
6 changed files with 86 additions and 21 deletions

View File

@ -2,7 +2,7 @@ CXX = g++
CXXFLAGS = -Wall -Wextra -O2 -std=c++14
DEPS = vec3.h color.h ray.h hittable.h sphere.h
DEPS = util.h vec3.h color.h ray.h hittable.h hittable_list.h sphere.h
OBJ = wtracer.o
TARGET = wtracer

View File

@ -7,11 +7,17 @@ struct hit_record {
Point3 p;
Vec3 normal;
double t;
bool front_face;
inline void set_face_normal(const Ray& r, const Vec3& outward_normal) {
front_face = dot(r.direction(), outward_normal) < 0;
normal = front_face ? outward_normal : -outward_normal;
}
};
class Hittable {
public:
virtual bool hit(cosnt Ray &r, double t_min, double t_max, hit_record &rec) const = 0;
}
virtual bool hit(const Ray &r, double tmin, double tmax, hit_record &rec) const = 0;
};
#endif // HITTABLE_H

39
hittable_list.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef HITTABLE_LIST_H
#define HITTABLE_LIST_H
#include <memory>
#include <vector>
#include "hittable.h"
class Hittable_list : public Hittable {
public:
Hittable_list() {}
Hittable_list(std::shared_ptr<Hittable> object) { add(object); }
void clear() { objects.clear(); }
void add(std::shared_ptr<Hittable> object) { objects.push_back(object); }
virtual bool hit(const Ray &r, double tmin, double tmax, hit_record &rec) const;
private:
std::vector<std::shared_ptr<Hittable>> objects;
};
bool Hittable_list::hit(const Ray &r, double tmin, double tmax, hit_record &rec) const {
hit_record temp_rec;
bool hit_anything = false;
auto closest_so_far = tmax;
for (const auto& object : objects) {
if (object->hit(r, tmin, closest_so_far, temp_rec)) {
hit_anything = true;
closest_so_far = temp_rec.t;
rec = temp_rec;
}
}
return hit_anything;
}
#endif // HITTABLE_LIST_H

View File

@ -18,27 +18,29 @@ private:
double radius;
};
bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) {
bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const {
Vec3 oc = r.origin() - center;
auto a = r.direction().length_squared();
auto half_b = dot(oc, r.direction());
auto c = oc.length_squared() - radius * radius;
auto discriminant = half_b*half_b - a*c;
if (discriminant < 0) {
if (discriminant > 0) {
auto root = std::sqrt(discriminant);
auto temp = (-half_b - root) / a;
if (temp < t_max && temp > t_min) {
if (temp < tmax && temp > tmin) {
rec.t = temp;
rec.p = r.at(rec.t);
rec.normal = (rec.p - center) / radius;
return true
Vec3 outward_normal = (rec.p - center) / radius;
rec.set_face_normal(r, outward_normal);
return true;
}
temp (-half_b + root) / a;
if (temp < t_max && temp > t_min) {
temp = (-half_b + root) / a;
if (temp < tmax && temp > tmin) {
rec.t = temp;
rec.p = r.at(rec.t);
rec.normal = (rec.p - center) / radius;
return true
Vec3 outward_normal = (rec.p - center) / radius;
rec.set_face_normal(r, outward_normal);
return true;
}
}
return false;

13
util.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef UTIL_H
#define UTIL_H
#include <limits>
const double infinity = std::numeric_limits<double>::infinity();
const double pi = 3.1415926535897932385;
inline double degrees_to_radians(double degrees) {
return degrees * pi / 180;
}
#endif // UTIL_H

View File

@ -1,19 +1,20 @@
#include <iostream>
#include <cmath>
#include "color.h"
#include "vec3.h"
#include "ray.h"
#include "util.h"
Color ray_color(const Ray& r) {
auto sphere_center = Point3(0, 0, -1);
auto t = hit_sphere(sphere_center, 0.5, r);
if (t > 0.0) {
Vec3 n = unit_vector(r.at(t) - sphere_center);
return 0.5 * Color(n.x()+1, n.y()+1, n.z()+1);
#include "hittable_list.h"
#include "sphere.h"
Color ray_color(const Ray& r, const Hittable& world) {
hit_record rec;
if (world.hit(r, 0, infinity, rec)) {
return 0.5 * (rec.normal + Color(1,1,1));
}
Vec3 unit_direction = unit_vector(r.direction());
t = 0.5 * (unit_direction.y() + 1.0);
auto t = 0.5 * (unit_direction.y() + 1.0);
return (1.0 - t) * Color(1.0, 1.0, 1.0) + t * Color(0.5, 0.7, 1.0);
}
@ -33,13 +34,17 @@ int main() {
auto vertical = Vec3(0, viewport_height, 0);
auto lower_left_corner = origin - horizontal/2 - vertical/2 - Vec3(0, 0, focal_length);
Hittable_list world;
world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5));
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100));
for (int j = image_height - 1; j >= 0; --j) {
std::cerr << "\rScanlines remaining: " << j << " " << std::flush;
for (int i = 0; i < image_width; ++i) {
auto u = double(i) / (image_width - 1);
auto v = double(j) / (image_height - 1);
Ray r(origin, lower_left_corner + u*horizontal + v*vertical - origin);
Color pixel_color = ray_color(r);
Color pixel_color = ray_color(r, world);
write_color(std::cout, pixel_color);
}
}