9650806e
Pavel Govyadinov
Modified Camera.h...
|
1
2
3
|
#include "../math/vector.h"
#include "../math/quaternion.h"
#include "../math/matrix.h"
|
7006df5f
David Mayerich
reformat of direc...
|
4
5
6
|
#include <ostream>
|
8a86bd56
David Mayerich
changed rts names...
|
7
8
|
#ifndef STIM_CAMERA_H
#define STIM_CAMERA_H
|
7006df5f
David Mayerich
reformat of direc...
|
9
|
|
8a86bd56
David Mayerich
changed rts names...
|
10
|
namespace stim{
|
7006df5f
David Mayerich
reformat of direc...
|
11
12
13
|
class camera
{
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
14
15
16
|
vec<float, 3> d; //direction that the camera is pointing
vec<float, 3> p; //position of the camera
vec<float, 3> up; //"up" direction
|
7006df5f
David Mayerich
reformat of direc...
|
17
18
19
20
21
22
|
float focus; //focal length of the camera
float fov;
//private function makes sure that the up vector is orthogonal to the direction vector and both are normalized
void stabalize()
{
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
23
|
vec<float, 3> side = up.cross(d);
|
7006df5f
David Mayerich
reformat of direc...
|
24
25
26
27
28
29
|
up = d.cross(side);
up = up.norm();
d = d.norm();
}
public:
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
30
|
void setPosition(vec<float, 3> pos)
|
7006df5f
David Mayerich
reformat of direc...
|
31
32
33
|
{
p = pos;
}
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
34
|
void setPosition(float x, float y, float z){setPosition(vec<float, 3>(x, y, z));}
|
7006df5f
David Mayerich
reformat of direc...
|
35
36
37
38
|
void setFocalDistance(float distance){focus = distance;}
void setFOV(float field_of_view){fov = field_of_view;}
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
39
|
void LookAt(vec<float, 3> pos)
|
7006df5f
David Mayerich
reformat of direc...
|
40
41
42
43
44
45
46
47
48
49
|
{
//find the new direction
d = pos - p;
//find the distance from the look-at point to the current position
focus = d.len();
//stabalize the camera
stabalize();
}
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
50
51
52
|
void LookAt(float px, float py, float pz){LookAt(vec<float, 3>(px, py, pz));}
void LookAt(vec<float, 3> pos, vec<float, 3> new_up){up = new_up; LookAt(pos);}
void LookAt(float px, float py, float pz, float ux, float uy, float uz){LookAt(vec<float, 3>(px, py, pz), vec<float, 3>(ux, uy, uz));}
|
7006df5f
David Mayerich
reformat of direc...
|
53
54
55
|
void LookAtDolly(float lx, float ly, float lz)
{
//find the current focus point
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
56
57
|
vec<float, 3> f = p + focus*d;
vec<float, 3> T = vec<float, 3>(lx, ly, lz) - f;
|
7006df5f
David Mayerich
reformat of direc...
|
58
59
60
|
p = p + T;
}
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
61
|
void Dolly(vec<float, 3> direction)
|
7006df5f
David Mayerich
reformat of direc...
|
62
63
64
|
{
p = p+direction;
}
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
65
|
void Dolly(float x, float y, float z){Dolly(vec<float, 3>(x, y, z));}
|
7006df5f
David Mayerich
reformat of direc...
|
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
void Push(float delta)
{
if(delta > focus)
delta = focus;
focus -= delta;
Dolly(d*delta);
}
void Pan(float theta_x, float theta_y, float theta_z)
{
//x rotation is around the up axis
quaternion<float> qx;
qx.CreateRotation(theta_x, up[0], up[1], up[2]);
//y rotation is around the side axis
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
83
|
vec<float, 3> side = up.cross(d);
|
7006df5f
David Mayerich
reformat of direc...
|
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
|
quaternion<float> qy;
qy.CreateRotation(theta_y, side[0], side[1], side[2]);
//z rotation is around the direction vector
quaternion<float> qz;
qz.CreateRotation(theta_z, d[0], d[1], d[2]);
//combine the rotations in x, y, z order
quaternion<float> final = qz*qy*qx;
//get the rotation matrix
matrix<float, 3> rot_matrix = final.toMatrix3();
//apply the rotation
d = rot_matrix*d;
up = rot_matrix*up;
//stabalize the camera
stabalize();
}
void Pan(float theta_x){Pan(theta_x, 0, 0);}
void Tilt(float theta_y){Pan(0, theta_y, 0);}
void Twist(float theta_z){Pan(0, 0, theta_z);}
void Zoom(float delta)
{
fov -= delta;
if(fov < 0.5)
fov = 0.5;
if(fov > 180)
fov = 180;
}
void OrbitFocus(float theta_x, float theta_y)
{
//find the focal point
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
121
|
vec<float, 3> focal_point = p + focus*d;
|
7006df5f
David Mayerich
reformat of direc...
|
122
123
|
//center the coordinate system on the focal point
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
124
|
vec<float, 3> centered = p - (focal_point - vec<float, 3>(0, 0, 0));
|
7006df5f
David Mayerich
reformat of direc...
|
125
126
127
128
|
//create the x rotation (around the up vector)
quaternion<float> qx;
qx.CreateRotation(theta_x, up[0], up[1], up[2]);
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
129
|
centered = vec<float, 3>(0, 0, 0) + qx.toMatrix3()*(centered - vec<float, 3>(0, 0, 0));
|
7006df5f
David Mayerich
reformat of direc...
|
130
131
|
//get a side vector for theta_y rotation
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
132
|
vec<float, 3> side = up.cross((vec<float, 3>(0, 0, 0) - centered).norm());
|
7006df5f
David Mayerich
reformat of direc...
|
133
134
135
|
quaternion<float> qy;
qy.CreateRotation(theta_y, side[0], side[1], side[2]);
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
136
|
centered = vec<float, 3>(0, 0, 0) + qy.toMatrix3()*(centered - vec<float, 3>(0, 0, 0));
|
7006df5f
David Mayerich
reformat of direc...
|
137
138
139
140
141
|
//perform the rotation on the centered camera position
//centered = final.toMatrix()*centered;
//re-position the camera
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
142
|
p = centered + (focal_point - vec<float, 3>(0, 0, 0));
|
7006df5f
David Mayerich
reformat of direc...
|
143
144
145
146
147
148
149
150
151
152
153
|
//make sure we are looking at the focal point
LookAt(focal_point);
//stabalize the camera
stabalize();
}
void Slide(float u, float v)
{
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
154
155
|
vec<float, 3> V = up.norm();
vec<float, 3> U = up.cross(d).norm();
|
7006df5f
David Mayerich
reformat of direc...
|
156
157
158
159
160
|
p = p + (V * v) + (U * u);
}
//accessor methods
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
161
162
163
164
|
vec<float, 3> getPosition(){return p;}
vec<float, 3> getUp(){return up;}
vec<float, 3> getDirection(){return d;}
vec<float, 3> getLookAt(){return p + focus*d;}
|
7006df5f
David Mayerich
reformat of direc...
|
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
float getFOV(){return fov;}
//output the camera settings
const void print(std::ostream& output)
{
output<<"Position: "<<p<<std::endl;
}
friend std::ostream& operator<<(std::ostream& out, const camera& c)
{
out<<"Position: "<<c.p<<std::endl;
out<<"Direction: "<<c.d<<std::endl;
out<<"Up: "<<c.up<<std::endl;
out<<"Focal Distance: "<<c.focus<<std::endl;
return out;
}
//constructor
camera()
{
|
9650806e
Pavel Govyadinov
Modified Camera.h...
|
185
186
187
|
p = vec<float, 3>(0, 0, 0);
d = vec<float, 3>(0, 0, 1);
up = vec<float, 3>(0, 1, 0);
|
7006df5f
David Mayerich
reformat of direc...
|
188
189
190
191
192
193
194
195
196
197
|
focus = 1;
}
};
}
#endif
|