metasurf

view examples/metaballs/src/cam.c @ 11:430d8dde62aa

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