rev |
line source |
nuclear@0
|
1 #include <math.h>
|
nuclear@0
|
2 #include "cam.h"
|
nuclear@0
|
3
|
nuclear@0
|
4 #if defined(__APPLE__) && defined(__MACH__)
|
nuclear@0
|
5 #include <OpenGL/gl.h>
|
nuclear@0
|
6 #else
|
nuclear@0
|
7 #include <GL/gl.h>
|
nuclear@0
|
8 #endif
|
nuclear@0
|
9
|
nuclear@0
|
10 #define DR (M_PI / 180.0)
|
nuclear@0
|
11 #define DEG_TO_RAD(x) ((x) * DR)
|
nuclear@0
|
12
|
nuclear@0
|
13 typedef struct vec3 {
|
nuclear@0
|
14 float x, y, z;
|
nuclear@0
|
15 } vec3_t;
|
nuclear@0
|
16
|
nuclear@0
|
17 /* viewing parameters */
|
nuclear@0
|
18 #define DEF_THETA 0
|
nuclear@0
|
19 #define DEF_PHI 0
|
nuclear@0
|
20 #define DEF_DIST 0
|
nuclear@0
|
21 #define DEF_X 0
|
nuclear@0
|
22 #define DEF_Y 0
|
nuclear@0
|
23 #define DEF_Z 0
|
nuclear@0
|
24
|
nuclear@0
|
25 static float cam_theta = DEF_THETA, cam_phi = DEF_PHI;
|
nuclear@0
|
26 static float cam_dist = DEF_DIST;
|
nuclear@0
|
27 static vec3_t cam_pos = {DEF_X, DEF_Y, DEF_Z};
|
nuclear@0
|
28
|
nuclear@0
|
29 /* projection parameters */
|
nuclear@0
|
30 #define DEF_VFOV 45.0
|
nuclear@0
|
31 #define DEF_ASPECT 1.3333333
|
nuclear@0
|
32 #define DEF_NEAR 1.0
|
nuclear@0
|
33 #define DEF_FAR 1000.0
|
nuclear@0
|
34
|
nuclear@0
|
35 static float vfov = DEF_VFOV;
|
nuclear@0
|
36 static float aspect = DEF_ASPECT;
|
nuclear@0
|
37 static float nearclip = DEF_NEAR, farclip = DEF_FAR;
|
nuclear@0
|
38
|
nuclear@0
|
39 /* stereo parameters */
|
nuclear@0
|
40 #define DEF_EYE_SEP 0.1
|
nuclear@0
|
41 #define DEF_FOCUS_DIST 1.0
|
nuclear@0
|
42
|
nuclear@0
|
43 static float eye_sep = DEF_EYE_SEP;
|
nuclear@0
|
44 static float focus_dist = DEF_FOCUS_DIST;
|
nuclear@0
|
45
|
nuclear@0
|
46 static float pan_speed = 0.001;
|
nuclear@0
|
47 static float rot_speed = 0.5;
|
nuclear@0
|
48 static float zoom_speed = 0.1;
|
nuclear@0
|
49
|
nuclear@0
|
50 static float vmin_deg = -90.0, vmax_deg = 90.0;
|
nuclear@0
|
51
|
nuclear@0
|
52 void cam_reset(void)
|
nuclear@0
|
53 {
|
nuclear@0
|
54 cam_reset_view();
|
nuclear@0
|
55 cam_reset_proj();
|
nuclear@0
|
56 cam_reset_stereo();
|
nuclear@0
|
57 }
|
nuclear@0
|
58
|
nuclear@0
|
59 void cam_reset_view(void)
|
nuclear@0
|
60 {
|
nuclear@0
|
61 cam_theta = DEF_THETA;
|
nuclear@0
|
62 cam_phi = DEF_PHI;
|
nuclear@0
|
63 cam_dist = DEF_DIST;
|
nuclear@0
|
64 cam_pos.x = DEF_X;
|
nuclear@0
|
65 cam_pos.y = DEF_Y;
|
nuclear@0
|
66 cam_pos.z = DEF_Z;
|
nuclear@0
|
67 }
|
nuclear@0
|
68
|
nuclear@0
|
69 void cam_reset_proj(void)
|
nuclear@0
|
70 {
|
nuclear@0
|
71 vfov = DEF_VFOV;
|
nuclear@0
|
72 aspect = DEF_ASPECT;
|
nuclear@0
|
73 nearclip = DEF_NEAR;
|
nuclear@0
|
74 farclip = DEF_FAR;
|
nuclear@0
|
75 }
|
nuclear@0
|
76
|
nuclear@0
|
77 void cam_reset_stereo(void)
|
nuclear@0
|
78 {
|
nuclear@0
|
79 eye_sep = DEF_EYE_SEP;
|
nuclear@0
|
80 focus_dist = DEF_FOCUS_DIST;
|
nuclear@0
|
81 }
|
nuclear@0
|
82
|
nuclear@0
|
83 void cam_set_vrange(float min_deg, float max_deg)
|
nuclear@0
|
84 {
|
nuclear@0
|
85 vmin_deg = min_deg;
|
nuclear@0
|
86 vmax_deg = max_deg;
|
nuclear@0
|
87 }
|
nuclear@0
|
88
|
nuclear@0
|
89 void cam_move(float x, float y, float z)
|
nuclear@0
|
90 {
|
nuclear@0
|
91 cam_pos.x += x;
|
nuclear@0
|
92 cam_pos.y += y;
|
nuclear@0
|
93 cam_pos.z += z;
|
nuclear@0
|
94 }
|
nuclear@0
|
95
|
nuclear@0
|
96 void cam_rotate(float theta, float phi)
|
nuclear@0
|
97 {
|
nuclear@0
|
98 cam_phi += phi;
|
nuclear@0
|
99 cam_theta += theta;
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102 void cam_dolly(float dist)
|
nuclear@0
|
103 {
|
nuclear@0
|
104 cam_dist += dist;
|
nuclear@0
|
105 }
|
nuclear@0
|
106
|
nuclear@0
|
107 void cam_inp_pan_speed(float speed)
|
nuclear@0
|
108 {
|
nuclear@0
|
109 pan_speed = speed;
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@0
|
112 void cam_inp_rotate_speed(float speed)
|
nuclear@0
|
113 {
|
nuclear@0
|
114 rot_speed = speed;
|
nuclear@0
|
115 }
|
nuclear@0
|
116
|
nuclear@0
|
117 void cam_inp_zoom_speed(float speed)
|
nuclear@0
|
118 {
|
nuclear@0
|
119 zoom_speed = speed;
|
nuclear@0
|
120 }
|
nuclear@0
|
121
|
nuclear@0
|
122
|
nuclear@0
|
123 void cam_inp_pan(int dx, int dy)
|
nuclear@0
|
124 {
|
nuclear@0
|
125 float dxf = dx * pan_speed;
|
nuclear@0
|
126 float dyf = dy * pan_speed;
|
nuclear@0
|
127 float angle = -DEG_TO_RAD(cam_theta);
|
nuclear@0
|
128
|
nuclear@0
|
129 cam_pos.x += cos(angle) * dxf + sin(angle) * dyf;
|
nuclear@0
|
130 cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf;
|
nuclear@0
|
131 }
|
nuclear@0
|
132
|
nuclear@0
|
133 void cam_inp_height(int dh)
|
nuclear@0
|
134 {
|
nuclear@0
|
135 cam_pos.y += dh * pan_speed;
|
nuclear@0
|
136 }
|
nuclear@0
|
137
|
nuclear@0
|
138 void cam_inp_rotate(int dx, int dy)
|
nuclear@0
|
139 {
|
nuclear@0
|
140 cam_theta += dx * rot_speed;
|
nuclear@0
|
141 cam_phi += dy * rot_speed;
|
nuclear@0
|
142
|
nuclear@0
|
143 if(cam_phi < vmin_deg) cam_phi = vmin_deg;
|
nuclear@0
|
144 if(cam_phi > vmax_deg) cam_phi = vmax_deg;
|
nuclear@0
|
145 }
|
nuclear@0
|
146
|
nuclear@0
|
147 void cam_inp_zoom(int dz)
|
nuclear@0
|
148 {
|
nuclear@0
|
149 cam_dist += dz * zoom_speed;
|
nuclear@0
|
150 if(cam_dist < 0.001) {
|
nuclear@0
|
151 cam_dist = 0.001;
|
nuclear@0
|
152 }
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@0
|
155 void cam_clip(float n, float f)
|
nuclear@0
|
156 {
|
nuclear@0
|
157 nearclip = n;
|
nuclear@0
|
158 farclip = f;
|
nuclear@0
|
159 }
|
nuclear@0
|
160
|
nuclear@0
|
161 void cam_fov(float f)
|
nuclear@0
|
162 {
|
nuclear@0
|
163 vfov = f;
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 void cam_aspect(float a)
|
nuclear@0
|
167 {
|
nuclear@0
|
168 aspect = a;
|
nuclear@0
|
169 }
|
nuclear@0
|
170
|
nuclear@0
|
171 void cam_separation(float s)
|
nuclear@0
|
172 {
|
nuclear@0
|
173 eye_sep = s;
|
nuclear@0
|
174 }
|
nuclear@0
|
175
|
nuclear@0
|
176 void cam_focus_dist(float d)
|
nuclear@0
|
177 {
|
nuclear@0
|
178 focus_dist = d;
|
nuclear@0
|
179
|
nuclear@0
|
180 cam_separation(d / 30.0);
|
nuclear@0
|
181 }
|
nuclear@0
|
182
|
nuclear@0
|
183 void cam_view_matrix(void)
|
nuclear@0
|
184 {
|
nuclear@0
|
185 cam_stereo_view_matrix(CAM_CENTER);
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@0
|
188 void cam_stereo_view_matrix(int eye)
|
nuclear@0
|
189 {
|
nuclear@0
|
190 static const float offs_sign[] = {0.0f, 0.5f, -0.5f}; /* center, left, right */
|
nuclear@0
|
191 float offs = eye_sep * offs_sign[eye];
|
nuclear@0
|
192
|
nuclear@0
|
193 glTranslatef(offs, 0, 0);
|
nuclear@0
|
194
|
nuclear@0
|
195 glTranslatef(0, 0, -cam_dist);
|
nuclear@0
|
196 glRotatef(cam_phi, 1, 0, 0);
|
nuclear@0
|
197 glRotatef(cam_theta, 0, 1, 0);
|
nuclear@0
|
198 glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
|
nuclear@0
|
199 }
|
nuclear@0
|
200
|
nuclear@0
|
201 void cam_proj_matrix(void)
|
nuclear@0
|
202 {
|
nuclear@0
|
203 cam_stereo_proj_matrix(CAM_CENTER);
|
nuclear@0
|
204 }
|
nuclear@0
|
205
|
nuclear@0
|
206 void cam_stereo_proj_matrix(int eye)
|
nuclear@0
|
207 {
|
nuclear@0
|
208 float vfov_rad = M_PI * vfov / 180.0;
|
nuclear@0
|
209 float top = nearclip * tan(vfov_rad * 0.5);
|
nuclear@0
|
210 float right = top * aspect;
|
nuclear@0
|
211
|
nuclear@0
|
212 static const float offs_sign[] = {0.0f, 1.0, -1.0}; /* center, left, right */
|
nuclear@0
|
213 float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist);
|
nuclear@0
|
214
|
nuclear@0
|
215 glFrustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip);
|
nuclear@0
|
216 }
|