istereo2

annotate src/cam.c @ 8:661bf09db398

- replaced Quartz timer with cross-platform timer code - protected goatkit builtin theme function from being optimized out
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 24 Sep 2015 07:09:37 +0300
parents
children
rev   line source
nuclear@2 1 /*
nuclear@2 2 Stereoscopic tunnel for iOS.
nuclear@2 3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
nuclear@2 4
nuclear@2 5 This program is free software: you can redistribute it and/or modify
nuclear@2 6 it under the terms of the GNU General Public License as published by
nuclear@2 7 the Free Software Foundation, either version 3 of the License, or
nuclear@2 8 (at your option) any later version.
nuclear@2 9
nuclear@2 10 This program is distributed in the hope that it will be useful,
nuclear@2 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@2 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@2 13 GNU General Public License for more details.
nuclear@2 14
nuclear@2 15 You should have received a copy of the GNU General Public License
nuclear@2 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@2 17 */
nuclear@2 18
nuclear@2 19 #include <math.h>
nuclear@2 20 #include "opengl.h"
nuclear@2 21 #include "cam.h"
nuclear@2 22 #include "sanegl.h"
nuclear@2 23
nuclear@2 24 #define DEG_TO_RAD(x) (M_PI * (x) / 180.0)
nuclear@2 25
nuclear@2 26 typedef struct vec3 {
nuclear@2 27 float x, y, z;
nuclear@2 28 } vec3_t;
nuclear@2 29
nuclear@2 30 /* viewing parameters */
nuclear@2 31 #define DEF_THETA 0
nuclear@2 32 #define DEF_PHI 0
nuclear@2 33 #define DEF_DIST 0
nuclear@2 34 #define DEF_X 0
nuclear@2 35 #define DEF_Y 0
nuclear@2 36 #define DEF_Z 0
nuclear@2 37
nuclear@2 38 static float cam_theta = DEF_THETA, cam_phi = DEF_PHI;
nuclear@2 39 static float cam_dist = DEF_DIST;
nuclear@2 40 static vec3_t cam_pos = {DEF_X, DEF_Y, DEF_Z};
nuclear@2 41 static float cam_speed = 1.0;
nuclear@2 42
nuclear@2 43 /* projection parameters */
nuclear@2 44 #define DEF_VFOV 45.0
nuclear@2 45 #define DEF_ASPECT 1.3333333
nuclear@2 46 #define DEF_NEAR 1.0
nuclear@2 47 #define DEF_FAR 1000.0
nuclear@2 48
nuclear@2 49 static float vfov = DEF_VFOV;
nuclear@2 50 static float aspect = DEF_ASPECT;
nuclear@2 51 static float nearclip = DEF_NEAR, farclip = DEF_FAR;
nuclear@2 52
nuclear@2 53 /* stereo parameters */
nuclear@2 54 #define DEF_EYE_SEP 0.1
nuclear@2 55 #define DEF_FOCUS_DIST 1.0
nuclear@2 56
nuclear@2 57 static float eye_sep = DEF_EYE_SEP;
nuclear@2 58 static float focus_dist = DEF_FOCUS_DIST;
nuclear@2 59
nuclear@2 60
nuclear@2 61 static float rot_speed = 0.5;
nuclear@2 62 static float zoom_speed = 0.1;
nuclear@2 63
nuclear@2 64 void cam_reset(void)
nuclear@2 65 {
nuclear@2 66 cam_reset_view();
nuclear@2 67 cam_reset_proj();
nuclear@2 68 cam_reset_stereo();
nuclear@2 69 }
nuclear@2 70
nuclear@2 71 void cam_reset_view(void)
nuclear@2 72 {
nuclear@2 73 cam_theta = DEF_THETA;
nuclear@2 74 cam_phi = DEF_PHI;
nuclear@2 75 cam_dist = DEF_DIST;
nuclear@2 76 cam_pos.x = DEF_X;
nuclear@2 77 cam_pos.y = DEF_Y;
nuclear@2 78 cam_pos.z = DEF_Z;
nuclear@2 79 }
nuclear@2 80
nuclear@2 81 void cam_reset_proj(void)
nuclear@2 82 {
nuclear@2 83 vfov = DEF_VFOV;
nuclear@2 84 aspect = DEF_ASPECT;
nuclear@2 85 nearclip = DEF_NEAR;
nuclear@2 86 farclip = DEF_FAR;
nuclear@2 87 }
nuclear@2 88
nuclear@2 89 void cam_reset_stereo(void)
nuclear@2 90 {
nuclear@2 91 eye_sep = DEF_EYE_SEP;
nuclear@2 92 focus_dist = DEF_FOCUS_DIST;
nuclear@2 93 }
nuclear@2 94
nuclear@2 95 void cam_pan(int dx, int dy)
nuclear@2 96 {
nuclear@2 97 float dxf = dx * cam_speed;
nuclear@2 98 float dyf = dy * cam_speed;
nuclear@2 99 float angle = -DEG_TO_RAD(cam_theta);
nuclear@2 100
nuclear@2 101 cam_pos.x += cos(angle) * dxf + sin(angle) * dyf;
nuclear@2 102 cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf;
nuclear@2 103 }
nuclear@2 104
nuclear@2 105 void cam_height(int dh)
nuclear@2 106 {
nuclear@2 107 cam_pos.y += dh * cam_speed;
nuclear@2 108 }
nuclear@2 109
nuclear@2 110 void cam_rotate(int dx, int dy)
nuclear@2 111 {
nuclear@2 112 cam_theta += dx * rot_speed;
nuclear@2 113 cam_phi += dy * rot_speed;
nuclear@2 114
nuclear@2 115 if(cam_phi < -90) cam_phi = -90;
nuclear@2 116 if(cam_phi > 90) cam_phi = 90;
nuclear@2 117 }
nuclear@2 118
nuclear@2 119 void cam_zoom(int dz)
nuclear@2 120 {
nuclear@2 121 cam_dist += dz * zoom_speed;
nuclear@2 122 if(cam_dist < 0.001) {
nuclear@2 123 cam_dist = 0.001;
nuclear@2 124 }
nuclear@2 125 }
nuclear@2 126
nuclear@2 127 void cam_clip(float n, float f)
nuclear@2 128 {
nuclear@2 129 nearclip = n;
nuclear@2 130 farclip = f;
nuclear@2 131 }
nuclear@2 132
nuclear@2 133 void cam_fov(float f)
nuclear@2 134 {
nuclear@2 135 vfov = f;
nuclear@2 136 }
nuclear@2 137
nuclear@2 138 void cam_aspect(float a)
nuclear@2 139 {
nuclear@2 140 aspect = a;
nuclear@2 141 }
nuclear@2 142
nuclear@2 143 void cam_separation(float s)
nuclear@2 144 {
nuclear@2 145 eye_sep = s;
nuclear@2 146 }
nuclear@2 147
nuclear@2 148 void cam_focus_dist(float d)
nuclear@2 149 {
nuclear@2 150 focus_dist = d;
nuclear@2 151
nuclear@2 152 cam_separation(d / 30.0);
nuclear@2 153 }
nuclear@2 154
nuclear@2 155 void cam_view_matrix(void)
nuclear@2 156 {
nuclear@2 157 cam_stereo_view_matrix(CAM_CENTER);
nuclear@2 158 }
nuclear@2 159
nuclear@2 160 void cam_stereo_view_matrix(int eye)
nuclear@2 161 {
nuclear@2 162 static const float offs_sign[] = {0.0f, 0.5f, -0.5f}; /* center, left, right */
nuclear@2 163 float offs = eye_sep * offs_sign[eye];
nuclear@2 164
nuclear@2 165 gl_translatef(offs, 0, 0);
nuclear@2 166
nuclear@2 167 gl_translatef(0, 0, -cam_dist);
nuclear@2 168 gl_rotatef(cam_phi, 1, 0, 0);
nuclear@2 169 gl_rotatef(cam_theta, 0, 1, 0);
nuclear@2 170 gl_translatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
nuclear@2 171 }
nuclear@2 172
nuclear@2 173 void cam_proj_matrix(void)
nuclear@2 174 {
nuclear@2 175 cam_stereo_proj_matrix(CAM_CENTER);
nuclear@2 176 }
nuclear@2 177
nuclear@2 178 void cam_stereo_proj_matrix(int eye)
nuclear@2 179 {
nuclear@2 180 float vfov_rad = M_PI * vfov / 180.0;
nuclear@2 181 float top = nearclip * tan(vfov_rad * 0.5);
nuclear@2 182 float right = top * aspect;
nuclear@2 183
nuclear@2 184 static const float offs_sign[] = {0.0f, 1.0, -1.0}; /* center, left, right */
nuclear@2 185 float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist);
nuclear@2 186
nuclear@2 187 gl_frustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip);
nuclear@2 188 }