-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcamera.cpp
99 lines (80 loc) · 2.63 KB
/
camera.cpp
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
/**
* camera.cpp
*
* By Sebastian Raaphorst, 2018.
*/
//#include <omp.h>
#include "camera.h"
#include "canvas.h"
#include "common.h"
#include "constmath.h"
#include "ray.h"
#include "vec.h"
#include "world.h"
using namespace raytracer::impl;
namespace raytracer {
Camera::Camera(size_t hsize, size_t vsize, double fov, const Transformation &transformation) :
hsize{hsize}, vsize{vsize}, fov{fov}, transformation{transformation} {
const auto half_view = const_tan(fov / 2);
const auto aspect = (double) hsize / vsize;
if (aspect >= 1) {
half_width = half_view;
half_height = half_view / aspect;
} else {
half_width = half_view * aspect;
half_height = half_view;
}
pixel_size = (half_width * 2) / hsize;
}
bool Camera::operator==(const Camera &other) const noexcept {
return hsize == other.hsize
&& vsize == other.vsize
&& ALMOST_EQUALS(fov, other.fov)
&& transformation == other.transformation;
}
size_t Camera::getHSize() const noexcept {
return hsize;
}
size_t Camera::getVSize() const noexcept {
return vsize;
}
double Camera::getFOV() const noexcept {
return fov;
}
const Transformation &Camera::getTransformation() const noexcept {
return transformation;
}
double Camera::getHalfWidth() const noexcept {
return half_width;
}
double Camera::getHalfHeight() const noexcept {
return half_height;
}
double Camera::getPixelSize() const noexcept {
return pixel_size;
}
const Ray Camera::ray_for_pixel(double px, double py) const noexcept {
const auto xoffset = (px + 0.5) * pixel_size;
const auto yoffset = (py + 0.5) * pixel_size;
const auto world_x = half_width - xoffset;
const auto world_y = half_height - yoffset;
const auto inv = transformation.invert();
const auto pixel = inv * make_point(world_x, world_y, -1);
const auto origin = inv * make_point(0, 0, 0);
const auto direction = (pixel - origin).normalize();
return Ray{origin, direction};
}
const Canvas Camera::render(const World &w) const noexcept {
auto image = Canvas{hsize, vsize};
//#pragma omp parallel for
for (size_t y = 0; y < vsize; ++y) {
//#pragma omp parallel for
for (size_t x = 0; x < hsize; ++x) {
const auto ray = ray_for_pixel(x, y);
const auto colour = w.colourAt(ray);
image[x][y] = colour;
}
}
return image;
}
}