Add Hittable_list
This commit is contained in:
parent
bc63a68061
commit
881141a912
2
Makefile
2
Makefile
@ -2,7 +2,7 @@ CXX = g++
|
|||||||
|
|
||||||
CXXFLAGS = -Wall -Wextra -O2 -std=c++14
|
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
|
OBJ = wtracer.o
|
||||||
|
|
||||||
TARGET = wtracer
|
TARGET = wtracer
|
||||||
|
10
hittable.h
10
hittable.h
@ -7,11 +7,17 @@ struct hit_record {
|
|||||||
Point3 p;
|
Point3 p;
|
||||||
Vec3 normal;
|
Vec3 normal;
|
||||||
double t;
|
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 {
|
class Hittable {
|
||||||
public:
|
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
|
#endif // HITTABLE_H
|
||||||
|
39
hittable_list.h
Normal file
39
hittable_list.h
Normal 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
|
20
sphere.h
20
sphere.h
@ -18,27 +18,29 @@ private:
|
|||||||
double radius;
|
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;
|
Vec3 oc = r.origin() - center;
|
||||||
auto a = r.direction().length_squared();
|
auto a = r.direction().length_squared();
|
||||||
auto half_b = dot(oc, r.direction());
|
auto half_b = dot(oc, r.direction());
|
||||||
auto c = oc.length_squared() - radius * radius;
|
auto c = oc.length_squared() - radius * radius;
|
||||||
auto discriminant = half_b*half_b - a*c;
|
auto discriminant = half_b*half_b - a*c;
|
||||||
if (discriminant < 0) {
|
if (discriminant > 0) {
|
||||||
auto root = std::sqrt(discriminant);
|
auto root = std::sqrt(discriminant);
|
||||||
auto temp = (-half_b - root) / a;
|
auto temp = (-half_b - root) / a;
|
||||||
if (temp < t_max && temp > t_min) {
|
if (temp < tmax && temp > tmin) {
|
||||||
rec.t = temp;
|
rec.t = temp;
|
||||||
rec.p = r.at(rec.t);
|
rec.p = r.at(rec.t);
|
||||||
rec.normal = (rec.p - center) / radius;
|
Vec3 outward_normal = (rec.p - center) / radius;
|
||||||
return true
|
rec.set_face_normal(r, outward_normal);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
temp (-half_b + root) / a;
|
temp = (-half_b + root) / a;
|
||||||
if (temp < t_max && temp > t_min) {
|
if (temp < tmax && temp > tmin) {
|
||||||
rec.t = temp;
|
rec.t = temp;
|
||||||
rec.p = r.at(rec.t);
|
rec.p = r.at(rec.t);
|
||||||
rec.normal = (rec.p - center) / radius;
|
Vec3 outward_normal = (rec.p - center) / radius;
|
||||||
return true
|
rec.set_face_normal(r, outward_normal);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
13
util.h
Normal file
13
util.h
Normal 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
|
23
wtracer.cpp
23
wtracer.cpp
@ -1,19 +1,20 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
Color ray_color(const Ray& r) {
|
#include "hittable_list.h"
|
||||||
auto sphere_center = Point3(0, 0, -1);
|
#include "sphere.h"
|
||||||
auto t = hit_sphere(sphere_center, 0.5, r);
|
|
||||||
if (t > 0.0) {
|
Color ray_color(const Ray& r, const Hittable& world) {
|
||||||
Vec3 n = unit_vector(r.at(t) - sphere_center);
|
hit_record rec;
|
||||||
return 0.5 * Color(n.x()+1, n.y()+1, n.z()+1);
|
if (world.hit(r, 0, infinity, rec)) {
|
||||||
|
return 0.5 * (rec.normal + Color(1,1,1));
|
||||||
}
|
}
|
||||||
Vec3 unit_direction = unit_vector(r.direction());
|
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);
|
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 vertical = Vec3(0, viewport_height, 0);
|
||||||
auto lower_left_corner = origin - horizontal/2 - vertical/2 - Vec3(0, 0, focal_length);
|
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) {
|
for (int j = image_height - 1; j >= 0; --j) {
|
||||||
std::cerr << "\rScanlines remaining: " << j << " " << std::flush;
|
std::cerr << "\rScanlines remaining: " << j << " " << std::flush;
|
||||||
for (int i = 0; i < image_width; ++i) {
|
for (int i = 0; i < image_width; ++i) {
|
||||||
auto u = double(i) / (image_width - 1);
|
auto u = double(i) / (image_width - 1);
|
||||||
auto v = double(j) / (image_height - 1);
|
auto v = double(j) / (image_height - 1);
|
||||||
Ray r(origin, lower_left_corner + u*horizontal + v*vertical - origin);
|
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);
|
write_color(std::cout, pixel_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user