-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cc
127 lines (96 loc) · 3.78 KB
/
main.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include "rtweekend.h"
#include "camera.h"
#include "color.h"
#include "hittable_list.h"
#include "sphere.h"
#include "triangle.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stlfuns.h>
using namespace raytrace;
double hit_sphere(const point3& center, double radius, const ray& r) {
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 -1.0;
} else {
return (-half_b - sqrt(discriminant) ) / a;
}
}
color ray_color(const ray& r, const hittable& world) {
hit_record rec;
if (world.hit(r, interval(0, infinity), rec)) {
return 0.5 * (rec.normal + color(1,1,1));
}
vec3 unit_direction = unit_vector(r.direction());
auto a = 0.5*(unit_direction.y() + 1.0);
return (1.0-a)*color(1.0, 1.0, 1.0) + a*color(0.5, 0.7, 1.0);
}
std::vector<std::shared_ptr<triangle>> read_stl() {
const std::string stl_filename = "../stl-parse/test-files/femur_binary.stl";
auto S = Stl::readStlFileBinary(stl_filename);
std::vector<std::shared_ptr<triangle>> stl_tris(S.n_triangles);
constexpr double scale = 1.0;
const vec3 offset = vec3(0.0, 0.0, -1.5);
for (uint32_t i = 0; i < S.n_triangles; ++i) {
auto v0 = scale * (vec3(S.tris[i].vertices[0].P[0], S.tris[i].vertices[0].P[1], S.tris[i].vertices[0].P[2])
+ offset);
auto v1 = scale * (vec3(S.tris[i].vertices[1].P[0], S.tris[i].vertices[1].P[1], S.tris[i].vertices[1].P[2])
+ offset);
auto v2 = scale * (vec3(S.tris[i].vertices[2].P[0], S.tris[i].vertices[2].P[1], S.tris[i].vertices[2].P[2])
+ offset);
stl_tris[i] = std::make_shared<triangle>(v0,v1,v2);
}
return stl_tris;
}
int main(){
// Image
constexpr auto aspect_ratio = 16.0/9.0;
constexpr int image_width = 400;
constexpr int image_height = static_cast<int>(image_width / aspect_ratio);
constexpr int n_channels = 3;
constexpr int samples_per_pixel = 100;
char image[image_width * image_height * n_channels];
std::ofstream outfile;
// World
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));
#ifdef USE_FEMUR
auto tri_vec = read_stl();
for (auto &t : tri_vec) {
world.add(t);
}
#endif
// Camera
camera cam;
outfile.open("image.ppm");
outfile << "P3\n" << image_width << ' ' << image_height << "\n255\n";
for(int j=0;j<image_height;++j){
std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush;
auto t = (j + random_double()) / (image_height - 1);
for(int i=0;i<image_width;++i){
color pixel_color(0,0,0);
for (int sample = 0; sample < samples_per_pixel; ++sample) {
auto s = (i + random_double()) / (image_width - 1);
ray r = cam.get_ray(s,t);
pixel_color += ray_color(r,world);
}
write_color(outfile, pixel_color, samples_per_pixel);
image[(j*image_width*n_channels) + (n_channels*i) + 0] = static_cast<char>(255.999 * (pixel_color.x() / samples_per_pixel));
image[(j*image_width*n_channels) + (n_channels*i) + 1] = static_cast<char>(255.999 * (pixel_color.y() / samples_per_pixel));
image[(j*image_width*n_channels) + (n_channels*i) + 2] = static_cast<char>(255.999 * (pixel_color.z() / samples_per_pixel));
}
}
auto err = stbi_write_png("image.png",image_width,image_height,n_channels,image,(image_width * n_channels));
outfile.close();
std::clog << "\rDone \n";
return 0;
}