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
|
||||
|
||||
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
|
||||
|
10
hittable.h
10
hittable.h
@ -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
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;
|
||||
};
|
||||
|
||||
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
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 <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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user