-
Notifications
You must be signed in to change notification settings - Fork 0
/
aarect.h
157 lines (113 loc) · 4.48 KB
/
aarect.h
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef AARECT_H
#define AARECT_H
#include "rtweekend.h"
#include "chocable.h"
class rectangulo_xy : public chocable{
public:
rectangulo_xy(){}
rectangulo_xy(double _x0, double _x1, double _y0, double _y1, double _k, shared_ptr<material> mat):
x0(_x0),x1(_x1),y0(_y0),y1(_y1),k(_k),mp(mat){}
virtual bool choca(const rayo& r, double t_min, double t_max, registro_choque& rec) const override;
virtual bool caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const override {
caja_saliente = aabb(punto3(x0,y0,k-0.0001),punto3(x1,y1,k+0.0001));
return true;
}
public:
double x0,x1,y0,y1,k;
shared_ptr<material> mp;
};
class rectangulo_xz : public chocable{
public:
rectangulo_xz(){}
rectangulo_xz(double _x0, double _x1, double _z0, double _z1, double _k, shared_ptr<material> mat):
x0(_x0),x1(_x1),z0(_z0),z1(_z1),k(_k),mp(mat){}
virtual bool choca(const rayo& r, double t_min, double t_max, registro_choque& rec) const override;
virtual bool caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const override {
caja_saliente = aabb(punto3(x0,k-0.0001,z0),punto3(x1,k+0.0001,z1));
return true;
}
public:
double x0,x1,z0,z1,k;
shared_ptr<material> mp;
};
class rectangulo_yz : public chocable{
public:
rectangulo_yz(){}
rectangulo_yz(double _y0, double _y1, double _z0, double _z1, double _k, shared_ptr<material> mat):
y0(_y0),y1(_y1),z0(_z0),z1(_z1),k(_k),mp(mat){}
virtual bool choca(const rayo& r, double t_min, double t_max, registro_choque& rec) const override;
virtual bool caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const override {
caja_saliente = aabb(punto3(k-0.0001,y0,z0),punto3(k+0.0001,y1,z1));
return true;
}
public:
double y0,y1,z0,z1,k;
shared_ptr<material> mp;
};
bool rectangulo_xy::choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const {
/*
Un rayo puede escribirse como P(t) = A + t*b donde A es un punto y b es la direccion
Resolviendo solo para la componente en z queda
z = Az + t*bz
la interseccion con nuestro plano es para z = k entonces
k = Az + t*bz
t = (k - Az)/bz
usamos este t para hallar la solucion para las componentes x e y
x = Ax + t*bx
y = Ay + t*by
el rayo toca el rectangulo si los x e y hallados pertenecen al rectangulo
*/
auto t = (k-r.origen().z()) / r.direccion().z();
if(t < t_min || t > t_max)
return false;
auto x = r.origen().x() + t*r.direccion().x();
auto y = r.origen().y() + t*r.direccion().y();
if(x<x0 || x>x1 || y<y0 || y>y1)
return false;
//normaliza las coordenadas para la textura
registro.u = (x-x0)/(x1-x0);
registro.v = (y-y0)/(y1-y0);
registro.t = t;
auto normal_saliente = vec3(0,0,1);
registro.set_cara_y_normal(r,normal_saliente);
registro.material_ptr = mp;
registro.p = r.en(t);
return true;
}
bool rectangulo_xz::choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const {
auto t = (k-r.origen().y()) / r.direccion().y();
if(t < t_min || t > t_max)
return false;
auto x = r.origen().x() + t*r.direccion().x();
auto z = r.origen().z() + t*r.direccion().z();
if(x<x0 || x>x1 || z<z0 || z>z1)
return false;
//normaliza las coordenadas para la textura
registro.u = (x-x0)/(x1-x0);
registro.v = (z-z0)/(z1-z0);
registro.t = t;
auto normal_saliente = vec3(0,1,0);
registro.set_cara_y_normal(r,normal_saliente);
registro.material_ptr = mp;
registro.p = r.en(t);
return true;
}
bool rectangulo_yz::choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const {
auto t = (k-r.origen().x()) / r.direccion().x();
if(t < t_min || t > t_max)
return false;
auto y = r.origen().y() + t*r.direccion().y();
auto z = r.origen().z() + t*r.direccion().z();
if(y<y0 || y>y1 || z<z0 || z>z1)
return false;
//normaliza las coordenadas para la textura
registro.u = (y-y0)/(y1-y0);
registro.v = (z-z0)/(z1-z0);
registro.t = t;
auto normal_saliente = vec3(1,0,0);
registro.set_cara_y_normal(r,normal_saliente);
registro.material_ptr = mp;
registro.p = r.en(t);
return true;
}
#endif