Adding a abstractions like a world list
This commit is contained in:
parent
f39ff66c94
commit
1b78b8815f
20
src/hittable.h
Normal file
20
src/hittable.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "ray.h"
|
||||
|
||||
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(const ray& r, double t_min, double t_max, hit_record& rc) const = 0;
|
||||
};
|
41
src/hittable_list.h
Normal file
41
src/hittable_list.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "hittable.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using std::shared_ptr;
|
||||
using std::make_shared;
|
||||
|
||||
class hittable_list : public hittable{
|
||||
public:
|
||||
hittable_list() {}
|
||||
hittable_list(shared_ptr<hittable> object) {objects.push_back(object);}
|
||||
|
||||
void clear(){objects.clear();}
|
||||
void add(shared_ptr<hittable> object){objects.push_back(object);}
|
||||
|
||||
virtual bool hit (const ray& r, double t_min, double t_max, hit_record& rec) const override;
|
||||
|
||||
public:
|
||||
std::vector<shared_ptr<hittable>> objects;
|
||||
};
|
||||
|
||||
|
||||
bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
|
||||
hit_record temp_rec;
|
||||
bool hit_anything = false;
|
||||
auto closest_so_far = t_max;
|
||||
|
||||
for(const auto& object : objects){
|
||||
if(object->hit(r, t_min,closest_so_far, temp_rec)){
|
||||
hit_anything = true;
|
||||
closest_so_far = temp_rec.t;
|
||||
rec = temp_rec;
|
||||
}
|
||||
}
|
||||
|
||||
return hit_anything;
|
||||
}
|
||||
|
@ -1,30 +1,19 @@
|
||||
#include "rtweekend.h"
|
||||
|
||||
#include "color.h"
|
||||
#include "ray.h"
|
||||
#include "vector3.h"
|
||||
#include "hittable_list.h"
|
||||
#include "sphere.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
double hit_sphere (const point3& center, double radius, const ray& r) {
|
||||
vec3 oc = r.origin() - center;
|
||||
auto a = dot(r.direction(), r.direction());
|
||||
auto b = 2.0 * dot(oc, r.direction());
|
||||
auto c = dot(oc, oc) - radius*radius;
|
||||
auto discriminant = b*b - 4*a*c;
|
||||
if ( discriminant < 0) {
|
||||
return -1.0;
|
||||
}else{
|
||||
return (-b - sqrt(discriminant) ) / (2.0*a);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
color ray_color(const ray& r){
|
||||
auto t = hit_sphere(point3(0,0,-1), 0.5, r);
|
||||
if(t > 0.0){
|
||||
vec3 N = unit_vector(r.at(t) - vec3(0,0,-1));
|
||||
return 0.5*color(N.x()+1, N.y()+1, N.z()+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);
|
||||
}
|
||||
|
||||
@ -36,6 +25,11 @@ int main ()
|
||||
const int image_width = 400;
|
||||
const int image_height = static_cast<int>(image_width /aspect_ratio);
|
||||
|
||||
// World
|
||||
hittable_list world;
|
||||
world.add(make_shared<sphere>(point3(0,0,-1), 0.5));
|
||||
world.add(make_shared<sphere>(point3(0,-100.5,-1), 100));
|
||||
|
||||
|
||||
// Camera
|
||||
auto viewport_height = 2.0;
|
||||
@ -57,7 +51,7 @@ int main ()
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
25
src/rtweekend.h
Normal file
25
src/rtweekend.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
// Usings
|
||||
using std::shared_ptr;
|
||||
using std::make_shared;
|
||||
using std::sqrt;
|
||||
|
||||
|
||||
// Constants
|
||||
const double infinity = std::numeric_limits<double>::infinity();
|
||||
const double pi = 3.1415926535897932385;
|
||||
|
||||
// Utility functions
|
||||
inline double degrees_to_radians(double degrees){
|
||||
return degrees * pi / 180.0;
|
||||
}
|
||||
|
||||
// Common Headers
|
||||
#include "ray.h"
|
||||
#include "vector3.h"
|
||||
|
43
src/sphere.h
Normal file
43
src/sphere.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "hittable.h"
|
||||
#include "vector3.h"
|
||||
|
||||
class sphere : public hittable{
|
||||
public:
|
||||
sphere(){}
|
||||
sphere(point3 cen, double r): center(cen), radius(r){};
|
||||
|
||||
virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const override;
|
||||
|
||||
public:
|
||||
point3 center;
|
||||
double radius;
|
||||
};
|
||||
|
||||
|
||||
bool sphere::hit(const ray& r, double t_min, double t_max, 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) return false;
|
||||
auto sqrtd = sqrt(discriminant);
|
||||
|
||||
// Find the nearest root that lies in the acceptable range
|
||||
auto root = (-half_b - sqrtd) /a;
|
||||
if(root < t_min || t_max < root){
|
||||
root = (-half_b + sqrtd) /a;
|
||||
if (root < t_min || t_max < root)
|
||||
return false;
|
||||
}
|
||||
|
||||
rec.t = root;
|
||||
rec.p = r.at(rec.t);
|
||||
vec3 outward_normal = (rec.p - center) /radius;
|
||||
rec.set_face_normal(r, outward_normal);
|
||||
|
||||
return true;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user