cce7daf9
Pavel Govyadinov
added glObj.h to ...
|
1
2
3
|
#include <stim/math/vector.h>
#include <stim/math/quaternion.h>
#include <stim/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
{
|
308a743c
David Mayerich
fixed class compa...
|
14
15
16
|
vec3<float> d; //direction that the camera is pointing
vec3<float> p; //position of the camera
vec3<float> 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()
{
|
308a743c
David Mayerich
fixed class compa...
|
23
|
vec3<float> 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:
|
308a743c
David Mayerich
fixed class compa...
|
30
|
void setPosition(vec3<float> pos)
|
7006df5f
David Mayerich
reformat of direc...
|
31
32
33
|
{
p = pos;
}
|
308a743c
David Mayerich
fixed class compa...
|
34
|
void setPosition(float x, float y, float z){setPosition(vec3<float>(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;}
|
308a743c
David Mayerich
fixed class compa...
|
39
|
void LookAt(vec3<float> 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();
}
|
308a743c
David Mayerich
fixed class compa...
|
50
51
52
|
void LookAt(float px, float py, float pz){LookAt(vec3<float>(px, py, pz));}
void LookAt(vec3<float> pos, vec3<float> new_up){up = new_up; LookAt(pos);}
void LookAt(float px, float py, float pz, float ux, float uy, float uz){LookAt(vec3<float>(px, py, pz), vec3<float>(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
|
308a743c
David Mayerich
fixed class compa...
|
56
57
|
vec3<float> f = p + focus*d;
vec3<float> T = vec3<float>(lx, ly, lz) - f;
|
7006df5f
David Mayerich
reformat of direc...
|
58
59
60
|
p = p + T;
}
|
308a743c
David Mayerich
fixed class compa...
|
61
|
void Dolly(vec3<float> direction)
|
7006df5f
David Mayerich
reformat of direc...
|
62
63
64
|
{
p = p+direction;
}
|
308a743c
David Mayerich
fixed class compa...
|
65
|
void Dolly(float x, float y, float z){Dolly(vec3<float>(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
|
308a743c
David Mayerich
fixed class compa...
|
83
|
vec3<float> 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
|
308a743c
David Mayerich
fixed class compa...
|
121
|
vec3<float> focal_point = p + focus*d;
|
7006df5f
David Mayerich
reformat of direc...
|
122
123
|
//center the coordinate system on the focal point
|
308a743c
David Mayerich
fixed class compa...
|
124
|
vec3<float> centered = p - (focal_point - vec3<float>(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]);
|
308a743c
David Mayerich
fixed class compa...
|
129
|
centered = vec3<float>(0, 0, 0) + qx.toMatrix3()*(centered - vec3<float>(0, 0, 0));
|
7006df5f
David Mayerich
reformat of direc...
|
130
131
|
//get a side vector for theta_y rotation
|
308a743c
David Mayerich
fixed class compa...
|
132
|
vec3<float> side = up.cross((vec3<float>(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]);
|
308a743c
David Mayerich
fixed class compa...
|
136
|
centered = vec3<float>(0, 0, 0) + qy.toMatrix3()*(centered - vec3<float>(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
|
308a743c
David Mayerich
fixed class compa...
|
142
|
p = centered + (focal_point - vec3<float>(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)
{
|
308a743c
David Mayerich
fixed class compa...
|
154
155
|
vec3<float> V = up.norm();
vec3<float> U = up.cross(d).norm();
|
7006df5f
David Mayerich
reformat of direc...
|
156
157
158
159
160
|
p = p + (V * v) + (U * u);
}
//accessor methods
|
308a743c
David Mayerich
fixed class compa...
|
161
162
163
164
|
vec3<float> getPosition(){return p;}
vec3<float> getUp(){return up;}
vec3<float> getDirection(){return d;}
vec3<float> getLookAt(){return p + focus*d;}
|
7006df5f
David Mayerich
reformat of direc...
|
165
166
167
|
float getFOV(){return fov;}
//output the camera settings
|
5eeaf941
Pavel Govyadinov
changer to the ba...
|
168
|
void print(std::ostream& output)
|
7006df5f
David Mayerich
reformat of direc...
|
169
|
{
|
27b826a8
David Mayerich
added a spherical...
|
170
|
output<<"Position: "<<p.str()<<std::endl;
|
7006df5f
David Mayerich
reformat of direc...
|
171
172
173
174
|
}
friend std::ostream& operator<<(std::ostream& out, const camera& c)
{
|
27b826a8
David Mayerich
added a spherical...
|
175
176
177
|
out<<"Position: "<<c.p.str()<<std::endl;
out<<"Direction: "<<c.d.str()<<std::endl;
out<<"Up: "<<c.up.str()<<std::endl;
|
7006df5f
David Mayerich
reformat of direc...
|
178
179
180
181
182
183
184
|
out<<"Focal Distance: "<<c.focus<<std::endl;
return out;
}
//constructor
camera()
{
|
308a743c
David Mayerich
fixed class compa...
|
185
186
187
|
p = vec3<float>(0, 0, 0);
d = vec3<float>(0, 0, 1);
up = vec3<float>(0, 1, 0);
|
7006df5f
David Mayerich
reformat of direc...
|
188
|
focus = 1;
|
983b730b
David Mayerich
texture updates
|
189
|
fov = 60;
|
7006df5f
David Mayerich
reformat of direc...
|
190
191
|
}
|
9c97e126
David Mayerich
added an axis-ali...
|
192
193
194
195
196
197
198
|
/// Outputs the camera information as a string
std::string str(){
std::stringstream ss;
ss<<p.str()<<"----->"<<(p + d * focus).str();
return ss.str();
}
|
7006df5f
David Mayerich
reformat of direc...
|
199
200
201
202
203
204
205
|
};
}
#endif
|