-
Notifications
You must be signed in to change notification settings - Fork 0
/
camera.cpp
121 lines (96 loc) · 3.17 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <iostream>
#include <cmath>
#include "camera.h"
Camera::Camera(double fov)
: Entity() {
this->fov = fov;
}
void Camera::renderMesh(Mesh *m, Surface *s) {
Graphics g (s);
Vect4 *transVerts = new Vect4[m->verts.size()]; //Temporary storage for transformed vertices
Mat4 temp = Mat4::IdentityMat();
double sf = 1;
Vect4 tempLighting = Vect4::unit(Vect4(1, 1, 2));
int *lightVals = new int[m->faces.size()];
temp = m->forwardMat();
//Temporary shift!!
temp = Mat4::mult(Mat4::TranslateMat(Vect4(0,0,-15)), temp);
temp = Mat4::mult(Mat4::ProjectPersp(), temp);
//Transform points
for(int i = 0; i < m->verts.size(); i++) {
transVerts[i] = temp.mult(m->verts[i]);
}
//Grab light values
for(int i = 0; i < m->faces.size(); i++) {
Vect4 v1 = transVerts[m->faces[i].v1];
Vect4 v2 = transVerts[m->faces[i].v2];
Vect4 v3 = transVerts[m->faces[i].v3];
if(isBackface(v1, v2, v3))
;//continue;//g.setColor(255, 0, 0);//continue;
double light = Vect4::dot(tempLighting, Vect4::unit(Vect4::cross(v2 - v1, v3 - v1)));
if(light > 0) {
lightVals[i] = light * 255;
} else {
lightVals[i] = 0;
}
}
//Normalize w (only for x and y)
for(int i = 0; i < m->verts.size(); i++) {
transVerts[i].coord[0] /= transVerts[i].coord[3];
transVerts[i].coord[1] /= transVerts[i].coord[3];
if(transVerts[i].coord[3] < 0.01 && transVerts[i].coord[3] > -0.01) {
//std::cerr << i << " " << transVerts[i].coord[3] << " woop\n";
}
}
//Figure out mapping of points to screen
//mapsize is how wide half the screen should be
//In world units
double mapsize = tan(d2r(fov / 2));
double pixScale = s->width / (2 * mapsize); //How wide is a unit in pixels
double offX = s->width / 2;
double offY = s->height / 2;
//Transform to screen coords
for(int i = 0; i < m->verts.size(); i++) {
transVerts[i].coord[0] = transVerts[i].coord[0] * pixScale + offX;
transVerts[i].coord[1] = transVerts[i].coord[1] * pixScale + offY;
}
//Draw Triangles
for(int i = 0; i < m->faces.size(); i++) {
Vect4 v1 = transVerts[m->faces[i].v1];
Vect4 v2 = transVerts[m->faces[i].v2];
Vect4 v3 = transVerts[m->faces[i].v3];
if(isBackface(v1, v2, v3))
continue;//g.setColor(255, 0, 0);//continue;
double l = lightVals[i];
g.setColor(l,l,l);
g.fillTri(
PointZ ((int)v1[0], (int)v1[1], v1[2]),
PointZ ((int)v2[0], (int)v2[1], v2[2]),
PointZ ((int)v3[0], (int)v3[1], v3[2]));
}
//Draw wireframe faces with transformed vertices
/*
g.setColor(0,0,0);
for(int i = 0; i < m->faces.size(); i++) {
Vect4 v1 = transVerts[m->faces[i].v1];
Vect4 v2 = transVerts[m->faces[i].v2];
Vect4 v3 = transVerts[m->faces[i].v3];
g.drawLineZ((int)v1[0], (int)v1[1], v1[2], (int)v2[0], (int)v2[1], v2[2]);
g.drawLineZ((int)v2[0], (int)v2[1], v2[2], (int)v3[0], (int)v3[1], v3[2]);
g.drawLineZ((int)v3[0], (int)v3[1], v3[2], (int)v1[0], (int)v1[1], v1[2]);
}
*/
delete transVerts;
delete lightVals;
}
void Camera::renderMeshes(World *w, Surface *s) {
for(int i = 0; i < w->meshes.size(); i++) {
//Skip nulls
if(!w->meshes[i])
continue;
renderMesh(w->meshes[i], s);
}
}
bool Camera::isBackface(Vect4 v1, Vect4 v2, Vect4 v3) {
return Vect4::crossZ(v2 - v1, v3 - v1) <= 0;
}