4 Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5 Copyright (c) 1998 Paul Rademacher
7 This file is part of simavr.
9 simavr is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 simavr is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with simavr. If not, see <http://www.gnu.org/licenses/>.
30 const c3f new_distance)
32 if ( new_distance <= 0.0 ) /* Distance has to be positive */
35 /* We find the current forward vector */
36 // forward = lookat - eye;
37 c->forward = c3vec3_normalize(c3vec3_sub(c->lookat, c->eye));
40 c->distance = new_distance;
42 /* Find new eye point */
43 c->eye = c3vec3_sub(c->lookat, c3vec3_mulf(c->forward, c->distance));
63 c3cam_set_upv(c, c3vec3f(x,y,z));
82 c3cam_set_eyev(c, c3vec3f(x,y,z));
88 const c3vec3 new_lookat)
90 c->lookat = new_lookat;
101 c3cam_set_lookatv(c, c3vec3f(x,y,z));
110 c3mat4 rot = rotation3D(c->forward, angle );
111 c->up = c3mat4_mulv3(&rot, c->up);
120 c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
121 c3mat4 rot = rotation3D( c->up, angle );
123 eye_pt = c3mat4_mulv3(&rot, eye_pt);
124 c->eye = c3vec3_add(c->lookat, eye_pt);
135 c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
136 c3mat4 rot = rotation3D( axis, angle );
138 eye_pt = c3mat4_mulv3(&rot, eye_pt);
139 c->eye = c3vec3_add(c->lookat, eye_pt);
141 c->up = c3mat4_mulv3(&rot, c->up);
152 c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
153 c3mat4 rot = rotation3D( c->side, angle );
155 eye_pt = c3mat4_mulv3(&rot, eye_pt);
156 c->eye = c3vec3_add(c->lookat, eye_pt);
158 c->up = c3mat4_mulv3(&rot, c->up);
168 c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
169 c3mat4 rot = rotation3D( c->up, -angle );
171 lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
172 c->lookat = c3vec3_add(c->eye, lookat_pt);
182 c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
183 c3mat4 rot = rotation3D( c->side, -angle );
185 lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
186 c->lookat = c3vec3_add(c->eye, lookat_pt);
188 c->up = c3mat4_mulv3(&rot, c->up);
198 c3vec3 eye_pt = c3vec3_sub(c->lookat, c->eye); /* eye w/lookat at center */
199 c3f eye_distance = c3vec3_length(eye_pt);
200 c->eye.n[axis_num] = c->lookat.n[axis_num];
201 /* Bring eye to same level as lookat */
203 c3vec3 vector = c3vec3_sub(c->eye, c->lookat);
204 vector = c3vec3_normalize(vector);
205 vector = c3vec3_mulf(vector, eye_distance);
207 c->eye = c3vec3_add(c->lookat, vector);
208 c->up = c3vec3f( 0.0, 0.0, 0.0 );
209 c->up.n[axis_num] = 1.0;
218 c3cam_reset_up_axis(c, VY ); /* Resets to the Y axis */
228 c->eye = c3vec3_add(c->eye, c3vec3_mulf(c->forward, forw_move));
229 c->eye = c3vec3_add(c->eye, c3vec3_mulf(c->side, side_move));
230 c->eye = c3vec3_add(c->eye, c3vec3_mulf(c->up, up_move));
231 c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->forward, forw_move));
232 c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->side, side_move));
233 c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->up, up_move));
240 const c3vec3 v) /* A vector version of the above command */
242 c3cam_movef(c, v.n[VX], v.n[VY], v.n[VZ] );
248 const c3vec3 new_eye)
250 c3vec3 diff = c3vec3_sub(new_eye, c->eye);
252 c->lookat = c3vec3_add(c->lookat, diff);
253 c->eye = c3vec3_add(c->eye, diff);
259 c3cam_move_by_lookat(
261 const c3vec3 new_lookat)
263 c3vec3 diff = c3vec3_sub(new_lookat, c->lookat);
265 c->lookat = c3vec3_add(c->lookat, diff);
266 c->eye = c3vec3_add(c->eye, diff);
276 c->lookat = c3vec3_add(c->lookat, v);
277 c->eye = c3vec3_add(c->eye, v);
287 c3vec3 view = c3vec3_sub(c->lookat, c->eye);
289 view = c3mat4_mulv3(rot, view);
290 c->up = c3mat4_mulv3(rot, c->up);
292 c->lookat = c3vec3_add(c->eye, view);
298 c3cam_rot_about_lookat(
302 // NOT QUITE RIGHT YET
304 c3vec3 view = c3vec3_sub(c->eye, c->lookat);
306 view = c3mat4_mulv3(rot, view);
307 c->up = c3mat4_mulv3(rot, c->up);
309 c->eye = c3vec3_add(c->lookat, view);
320 c->mtx = c3mat4_vec4(
321 c3vec4f(c->side.n[VX], c->up.n[VX], c->forward.n[VX], 0.0),
322 c3vec4f(c->side.n[VY], c->up.n[VY], c->forward.n[VY], 0.0),
323 c3vec4f(c->side.n[VZ], c->up.n[VZ], c->forward.n[VZ], 0.0),
324 c3vec4f(0.0, 0.0, 0.0, 1.0));
328 c3cam_load_to_openGL(c3cam_p c)
334 glMatrixMode( GL_MODELVIEW );
336 glMultMatrixf( (c3f*) &mtx[0][0]);
337 glTranslatef( -eye[VX], -eye[VY], -eye[VZ] );
341 c3cam_load_to_openGL_noident(c3cam_p c)
347 glMatrixMode( GL_MODELVIEW );
348 glMultMatrixf( (c3f*) &mtx[0][0]);
349 glTranslatef( -eye[VX], -eye[VY], -eye[VZ] );
357 memset(c, 0, sizeof(*c));
358 c->up = c3vec3f( 0.0, 1.0, 0.0 );
359 c->eye = c3vec3f(0.0, 0.0, 10.0);
360 c->lookat = c3vec3f(0.0,0.0,0.0);
362 c->mtx = identity3D();
386 /* get proper side and forward vectors, and distance */
387 c->forward = c3vec3_minus(c3vec3_sub(c->lookat, c->eye));
388 c->distance = c3vec3_length(c->forward);
389 c->forward = c3vec3_divf(c->forward, c->distance);
391 c->side = c3vec3_cross(c->up, c->forward);
392 c->up = c3vec3_cross(c->forward, c->side);
394 c->forward = c3vec3_normalize(c->forward);
395 c->up = c3vec3_normalize(c->up);
396 c->side = c3vec3_normalize(c->side);
401 c3cam_dump(c3cam_p c, FILE *output) const
403 fprintf( output, "Viewmodel: \n" );
404 eye.print( output, " eye" );
405 lookat.print( output, " lookat" );
406 up.print( output, " up" );
407 side.print( output, " side" );
408 forward.print(output, " forward");
409 mtx.print( output, " mtx" );