-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlanar.cpp
More file actions
135 lines (118 loc) · 4.75 KB
/
Planar.cpp
File metadata and controls
135 lines (118 loc) · 4.75 KB
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
/**
* \author Marie DARRIGOL & Anthony LEONARD & Ophélie PELLOUX-PRAYER & Olivier SOLDANO
* \project Ray-Tracing
* \file Planar.cpp
* \brief Constructors, intersect method and bump computing for the Planar class
*/
#include "Planar.h"
#include "Color.h"
// Will create a planar at 0, 0, 0 with a side of 2
Planar::Planar() {
this->position = Vec3(0, 0, 0);
this->halfWidth = Vec3(1, 0, 0);
this->halfHeight = Vec3(0, 1, 0);
this->n = (this->halfWidth^this->halfHeight).unit();
}
// Constructor with all the parameters for the position and size
Planar::Planar(Vec3 &pos, Vec3 &w, Vec3 &h) {
this->position = pos;
this->halfWidth = w;
this->halfHeight = h;
this->n = (this->halfWidth^this->halfHeight).unit();
}
// Constructor will all the parameters
Planar::Planar(Vec3 &pos, Vec3 &w, Vec3 &h, Material &m) : SceneObject(pos, m){
this->halfWidth = w;
this->halfHeight = h;
this->n = (this->halfWidth^this->halfHeight).unit();
}
pair<bool, Vec3> Planar::intersect(Ray &ray){
// declare the impact point
Vec3 impact_point = ray.getOrigin();
// normalize the vector (n is already normalized)
Vec3 l0 = ray.getOrigin();
Vec3 l = ray.getDirection();
// calcul the denominator
float denom = l * n;
// if the ray and the normal vector of the planar isn't parallel
if (denom > 1e-6) {
// calcul t for determinate if the ray intersect the planar
float t = ((position - l0) * n) / denom;
// calcul the impact point
impact_point = l0 + l * t;
// verif if the impact point is in the square
if (impact_point.getX() < maxCoordinates().getX() && impact_point.getX() > minCoordinates().getX()
&& impact_point.getY() < maxCoordinates().getY() && impact_point.getY() > minCoordinates().getY()
/*&& impact_point.getZ() <= maxCoordinates().getZ() && impact_point.getZ() >= minCoordinates().getZ()*/){
return pair<bool, Vec3>(t >= 0, impact_point);
}
else{
return pair<bool, Vec3>(false, impact_point);
}
}
return pair<bool, Vec3>(false, impact_point);
}
Vec3 Planar::minCoordinates() {
// determine greater x
float x = halfWidth.getX() > halfHeight.getX() ? halfWidth.getX() : halfHeight.getX();
// determine greater y
float y = halfWidth.getY() > halfHeight.getY() ? halfWidth.getY() : halfHeight.getY();
// determine greater z
float z = halfWidth.getZ() > halfHeight.getZ() ? halfWidth.getZ() : halfHeight.getZ();
return Vec3(position.getX() - x, position.getY() - y, position.getZ() - z);
}
Vec3 Planar::maxCoordinates() {
// determine greater x
float x = halfWidth.getX() > halfHeight.getX() ? halfWidth.getX() : halfHeight.getX();
// determine greater y
float y = halfWidth.getY() > halfHeight.getY() ? halfWidth.getY() : halfHeight.getY();
// determine greater z
float z = halfWidth.getZ() > halfHeight.getZ() ? halfWidth.getZ() : halfHeight.getZ();
return Vec3(position.getX() + x, position.getY() + y, position.getZ() + z);
}
/*
Used to compute the normal on the impact point to make the surface "bump"
Impact point given in the scene base
If the impacted planar has a bump map, will get the color value of this point on the map
Then, will compute and return the normal depending on the color found
Else, will return the normal of the planar
*/
Vec3 Planar::computeBump(const Vec3& impact) const {
Vec3 res = Vec3() - this->n;
if (this->material.has_bump_map()) {
Vec3 impactPositionOnObject = impact - this->position;
unsigned int mapWidth = this->material.get_bump_map_width();
unsigned int mapHeight = this->material.get_bump_map_height();
unsigned int halfMapWidth = mapWidth / 2;
unsigned int halfMapHeight = mapHeight / 2;
unsigned int x, y;
// We get the x and y that have been projected on the width and the height of the planar
float xNorm = impactPositionOnObject * this->halfWidth / this->halfWidth.length();
float yNorm = impactPositionOnObject * this->halfHeight / this->halfWidth.length();
// We get the coef to make the map at the scale of the object
float coefWidth = halfMapWidth / this->halfWidth.length();
float coefHeight = halfMapHeight / this->halfHeight.length();
// We compute the delta x and y (in pixels)
float dx = xNorm * coefWidth;
float dy = yNorm * coefHeight;
// We compute the x and y coordinates in float
float xf = dx + halfMapWidth;
float yf = dy + halfMapHeight;
// We convert from float to int
x = (unsigned int) xf;
y = (unsigned int) yf;
// Finally, we get the color at the pixel using the previous coordinates
Color c = Color();
if (x >= mapWidth) {
c = this->material.get_pixel_at((mapWidth-1) + mapWidth*y);
}else if(y >= mapHeight){
c = this->material.get_pixel_at(x + mapWidth*(mapHeight-1));
}else{
c = this->material.get_pixel_at(x + mapWidth*y);
}
res.setX(res.getX() * c.getX());
res.setY(res.getY() * c.getY());
res.setZ(res.getZ() * c.getZ());
}
return res;
}