-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchocable.h
154 lines (109 loc) · 4.11 KB
/
chocable.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
#ifndef CHOCABLE_H
#define CHOCABLE_H
#include "rtweekend.h"
#include "aabb.h"
class material; //no se para que se usa, pero supuestamente el puntero que se usa mas abajo apunta a una clase.
struct registro_choque{
punto3 p;
vec3 normal;
shared_ptr<material> material_ptr;
double t;
double u;
double v;
bool cara_frontal;
inline void set_cara_y_normal(const rayo& r, const vec3& normal_saliente){
// es true cuando el rayo y la normal estan del mismo lado
cara_frontal = producto_punto(r.direccion(),normal_saliente) < 0;
// si estan del mismo lado, la normal es igual a la saliente, sino es la contraria
normal = cara_frontal ? normal_saliente : -normal_saliente;
}
};
class chocable {
public:
virtual bool choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const = 0;
virtual bool caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const = 0;
};
class trasladar : public chocable{
public:
trasladar(shared_ptr<chocable> objeto, const vec3& desplazamiento):
ptr(objeto),offset(desplazamiento){}
virtual bool choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const override;
virtual bool caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const override;
public:
shared_ptr<chocable> ptr;
vec3 offset;
};
bool trasladar::choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const{
rayo rayo_desplazado(r.origen()-offset,r.direccion(),r.tiempo());
if(!ptr->choca(rayo_desplazado,t_min,t_max,registro))
return false;
registro.p+=offset;
registro.set_cara_y_normal(rayo_desplazado,registro.normal);
return true;
}
bool trasladar::caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const{
if(!ptr->caja_delimitadora(tiempo0,tiempo1,caja_saliente))
return false;
caja_saliente = aabb(caja_saliente.min()+offset, caja_saliente.max()+offset);
return true;
}
class rotar_y : public chocable{
public:
rotar_y(shared_ptr<chocable> objeto, double angulo);
virtual bool choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const override;
virtual bool caja_delimitadora(double tiempo0, double tiempo1, aabb& caja_saliente) const override{
caja_saliente = caja_delim;
return tiene_caja;
}
inline punto3 aux_rotar_y(const punto3& original) const{
return punto3(cos_tita*original.x()+sen_tita*original.z(), original.y(), -sen_tita*original.x()+cos_tita*original.z());
}
inline punto3 aux_rotar_y2(const punto3& original) const{
return punto3(cos_tita*original.x()-sen_tita*original.z(), original.y(), sen_tita*original.x()+cos_tita*original.z());
}
public:
shared_ptr<chocable> ptr;
double sen_tita;
double cos_tita;
bool tiene_caja;
aabb caja_delim;
};
rotar_y::rotar_y(shared_ptr<chocable> objeto, double angulo) : ptr(objeto){
auto radianes = grados_a_radianes(angulo);
sen_tita = sin(radianes);
cos_tita = cos(radianes);
tiene_caja = ptr->caja_delimitadora(0,1,caja_delim);
punto3 min(infinito,infinito,infinito);
punto3 max(-infinito,-infinito,-infinito);
for(int i=0; i<2; i++){
for(int j=0; j<2; j++){
for(int k=0; k<2; k++){
auto x = i*caja_delim.max().x() + (1-i)*caja_delim.min().x();
auto y = j*caja_delim.max().y() + (1-j)*caja_delim.min().y();
auto z = k*caja_delim.max().z() + (1-k)*caja_delim.min().z();
// auto nuevo_x = cos_tita*x+sen_tita*z;
// auto nuevo_z = -sen_tita*x+cos_tita*z;
// vec3 tester(nuevo_x,y,nuevo_z);
vec3 tester = aux_rotar_y(punto3(x,y,z));
for(int c = 0; c<3; c++){
min[c] = fmin(min[c],tester[c]);
max[c] = fmax(max[c],tester[c]);
}
}
}
}
caja_delim = aabb(min,max);
}
bool rotar_y::choca(const rayo& r, double t_min, double t_max, registro_choque& registro) const {
punto3 origen = aux_rotar_y2(r.origen());
punto3 direccion = aux_rotar_y2(r.direccion());
rayo rayo_rotado(origen,direccion,r.tiempo());
if(!ptr->choca(rayo_rotado,t_min,t_max,registro))
return false;
auto p = aux_rotar_y(registro.p);
auto normal = aux_rotar_y(registro.normal);
registro.p = p;
registro.set_cara_y_normal(rayo_rotado,normal);
return true;
}
#endif