]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/camera.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / camera.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 #include "qe3.h"
24
25 #define PAGEFLIPS       2
26
27 void DrawPathLines (void);
28
29 camera_t        camera;
30
31 /*
32 ============
33 Cam_Init
34 ============
35 */
36 void Cam_Init (void)
37 {
38 //      camera.draw_mode = cd_texture;
39 //      camera.draw_mode = cd_solid;
40 //      camera.draw_mode = cd_wire;
41
42         camera.timing = false;
43
44         camera.origin[0] = 0;
45         camera.origin[1] = 20;
46         camera.origin[2] = 46;
47
48         camera.color[0] = 0.3;
49         camera.color[1] = 0.3;
50         camera.color[2] = 0.3;
51 }
52
53
54 //============================================================================
55
56 void Cam_BuildMatrix (void)
57 {
58         float   xa, ya;
59         float   matrix[4][4];
60         int             i;
61
62         xa = camera.angles[0]/180*Q_PI;
63         ya = camera.angles[1]/180*Q_PI;
64
65         // the movement matrix is kept 2d
66
67     camera.forward[0] = cos(ya);
68     camera.forward[1] = sin(ya);
69     camera.right[0] = camera.forward[1];
70     camera.right[1] = -camera.forward[0];
71
72         glGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]);
73
74         for (i=0 ; i<3 ; i++)
75         {
76                 camera.vright[i] = matrix[i][0];
77                 camera.vup[i] = matrix[i][1];
78                 camera.vpn[i] = matrix[i][2];
79         }
80
81         VectorNormalize (camera.vright);
82         VectorNormalize (camera.vup);
83         VectorNormalize (camera.vpn);
84 }
85
86 //===============================================
87
88 /*
89 ===============
90 Cam_ChangeFloor
91 ===============
92 */
93 void Cam_ChangeFloor (qboolean up)
94 {
95         brush_t *b;
96         float   d, bestd, current;
97         vec3_t  start, dir;
98
99         start[0] = camera.origin[0];
100         start[1] = camera.origin[1];
101         start[2] = 8192;
102         dir[0] = dir[1] = 0;
103         dir[2] = -1;
104
105         current = 8192 - (camera.origin[2] - 48);
106         if (up)
107                 bestd = 0;
108         else
109                 bestd = 16384;
110
111         for (b=active_brushes.next ; b != &active_brushes ; b=b->next)
112         {
113                 if (!Brush_Ray (start, dir, b, &d))
114                         continue;
115                 if (up && d < current && d > bestd)
116                         bestd = d;
117                 if (!up && d > current && d < bestd)
118                         bestd = d;
119         }
120
121         if (bestd == 0 || bestd == 16384)
122                 return;
123
124         camera.origin[2] += current - bestd;
125         Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY);
126 }
127
128
129 //===============================================
130
131 int     cambuttonstate;
132 static  int     buttonx, buttony;
133 static  int     cursorx, cursory;
134
135 face_t  *side_select;
136
137 #define ANGLE_SPEED     300
138 #define MOVE_SPEED      400
139
140 /*
141 ================
142 Cam_PositionDrag
143 ================
144 */
145 void Cam_PositionDrag (void)
146 {
147         int             x, y;
148
149         Sys_GetCursorPos (&x, &y);
150         if (x != cursorx || y != cursory)
151         {
152                 x -= cursorx;
153                 VectorMA (camera.origin, x, camera.vright, camera.origin);
154                 y -= cursory;
155                 camera.origin[2] -= y;
156
157                 Sys_SetCursorPos (cursorx, cursory);
158                 Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY);
159         }
160 }
161
162 /*
163 ===============
164 Cam_MouseControl
165 ===============
166 */
167 void Cam_MouseControl (float dtime)
168 {
169         int             xl, xh;
170         int             yl, yh;
171         float   xf, yf;
172
173         if (cambuttonstate != MK_RBUTTON)
174                 return;
175
176         xf = (float)(buttonx - camera.width/2) / (camera.width/2);
177         yf = (float)(buttony - camera.height/2) / (camera.height/2);
178
179         xl = camera.width/3;
180         xh = xl*2;
181         yl = camera.height/3;
182         yh = yl*2;
183
184 #if 0
185         // strafe
186         if (buttony < yl && (buttonx < xl || buttonx > xh))
187                 VectorMA (camera.origin, xf*dtime*MOVE_SPEED, camera.right, camera.origin);
188         else
189 #endif
190         {
191                 xf *= 1.0 - fabs(yf);
192                 if (xf < 0)
193                 {
194                         xf += 0.1;
195                         if (xf > 0)
196                                 xf = 0;
197                 }
198                 else
199                 {
200                         xf -= 0.1;
201                         if (xf < 0)
202                                 xf = 0;
203                 }
204
205                 VectorMA (camera.origin, yf*dtime*MOVE_SPEED, camera.forward, camera.origin);
206                 camera.angles[YAW] += xf*-dtime*ANGLE_SPEED;
207         }
208         Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
209 }
210
211
212
213
214 /*
215 ==============
216 Cam_MouseDown
217 ==============
218 */
219 void Cam_MouseDown (int x, int y, int buttons)
220 {
221         vec3_t          dir;
222         float           f, r, u;
223         int                     i;
224
225         //
226         // calc ray direction
227         //
228         u = (float)(y - camera.height/2) / (camera.width/2);
229         r = (float)(x - camera.width/2) / (camera.width/2);
230         f = 1;
231
232         for (i=0 ; i<3 ; i++)
233                 dir[i] = camera.vpn[i] * f + camera.vright[i] * r + camera.vup[i] * u;
234         VectorNormalize (dir);
235
236         Sys_GetCursorPos (&cursorx, &cursory);
237
238         cambuttonstate = buttons;
239         buttonx = x;
240         buttony = y;
241
242         // LBUTTON = manipulate selection
243         // shift-LBUTTON = select
244         // middle button = grab texture
245         // ctrl-middle button = set entire brush to texture
246         // ctrl-shift-middle button = set single face to texture
247         if ( (buttons == MK_LBUTTON)
248                 || (buttons == (MK_LBUTTON | MK_SHIFT))
249                 || (buttons == (MK_LBUTTON | MK_CONTROL))
250                 || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT))
251                 || (buttons == MK_MBUTTON)
252                 || (buttons == (MK_MBUTTON|MK_CONTROL))
253                 || (buttons == (MK_MBUTTON|MK_SHIFT|MK_CONTROL)) )
254         {
255                 Drag_Begin (x, y, buttons,
256                         camera.vright, camera.vup,
257                         camera.origin, dir);
258                 return;
259         }
260
261         if (buttons == MK_RBUTTON)
262         {
263                 Cam_MouseControl (0.1);
264                 return;
265         }
266 }
267
268 /*
269 ==============
270 Cam_MouseUp
271 ==============
272 */
273 void Cam_MouseUp (int x, int y, int buttons)
274 {
275         cambuttonstate = 0;
276         Drag_MouseUp ();
277 }
278
279
280 /*
281 ==============
282 Cam_MouseMoved
283 ==============
284 */
285 void Cam_MouseMoved (int x, int y, int buttons)
286 {
287         cambuttonstate = buttons;
288         if (!buttons)
289                 return;
290         buttonx = x;
291         buttony = y;
292
293         if (buttons == (MK_RBUTTON|MK_CONTROL) )
294         {
295                 Cam_PositionDrag ();
296                 Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
297                 return;
298         }
299
300         Sys_GetCursorPos (&cursorx, &cursory);
301
302         if (buttons & (MK_LBUTTON | MK_MBUTTON) )
303         {
304                 Drag_MouseMoved (x, y, buttons);
305                 Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
306         }
307 }
308
309
310 vec3_t  cull1, cull2;
311 int             cullv1[3], cullv2[3];
312
313 void InitCull (void)
314 {
315         int             i;
316
317         VectorSubtract (camera.vpn, camera.vright, cull1);
318         VectorAdd (camera.vpn, camera.vright, cull2);
319
320         for (i=0 ; i<3 ; i++)
321         {
322                 if (cull1[i] > 0)
323                         cullv1[i] = 3+i;
324                 else
325                         cullv1[i] = i;
326                 if (cull2[i] > 0)
327                         cullv2[i] = 3+i;
328                 else
329                         cullv2[i] = i;
330         }
331 }
332
333 qboolean CullBrush (brush_t *b)
334 {
335         int             i;
336         vec3_t  point;
337         float   d;
338
339         for (i=0 ; i<3 ; i++)
340                 point[i] = b->mins[cullv1[i]] - camera.origin[i];
341
342         d = DotProduct (point, cull1);
343         if (d < -1)
344                 return true;
345
346         for (i=0 ; i<3 ; i++)
347                 point[i] = b->mins[cullv2[i]] - camera.origin[i];
348
349         d = DotProduct (point, cull2);
350         if (d < -1)
351                 return true;
352
353         return false;
354 }
355
356
357 /*
358 ==============
359 Cam_Draw
360 ==============
361 */
362 void Cam_Draw (void)
363 {
364     brush_t     *brush;
365         face_t  *face;
366         float   screenaspect;
367         float   yfov;
368         double  start, end;
369         int             i;
370
371         if (!active_brushes.next)
372                 return; // not valid yet
373
374         if (camera.timing)
375                 start = Sys_DoubleTime ();
376
377         //
378         // clear
379         //
380         QE_CheckOpenGLForErrors();
381
382         glViewport(0, 0, camera.width, camera.height);
383         glScissor(0, 0, camera.width, camera.height);
384         glClearColor (
385                 g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0],
386                 g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1],
387                 g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2],
388                 0);
389     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
390
391         //
392         // set up viewpoint
393         //
394         glMatrixMode(GL_PROJECTION);
395     glLoadIdentity ();
396
397     screenaspect = (float)camera.width/camera.height;
398         yfov = 2*atan((float)camera.height/camera.width)*180/Q_PI;
399     gluPerspective (yfov,  screenaspect,  2,  8192);
400
401     glRotatef (-90,  1, 0, 0);      // put Z going up
402     glRotatef (90,  0, 0, 1);       // put Z going up
403     glRotatef (camera.angles[0],  0, 1, 0);
404     glRotatef (-camera.angles[1],  0, 0, 1);
405     glTranslatef (-camera.origin[0],  -camera.origin[1],  -camera.origin[2]);
406
407         Cam_BuildMatrix ();
408
409         InitCull ();
410
411         //
412         // draw stuff
413         //
414
415         switch (camera.draw_mode)
416         {
417         case cd_wire:
418                 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
419             glDisable(GL_TEXTURE_2D);
420             glDisable(GL_TEXTURE_1D);
421                 glDisable(GL_BLEND);
422                 glDisable(GL_DEPTH_TEST);
423             glColor3f(1.0, 1.0, 1.0);
424 //              glEnable (GL_LINE_SMOOTH);
425                 break;
426
427         case cd_solid:
428                 glCullFace(GL_FRONT);
429                 glEnable(GL_CULL_FACE);
430                 glShadeModel (GL_FLAT);
431
432                 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
433                 glDisable(GL_TEXTURE_2D);
434
435                 glDisable(GL_BLEND);
436                 glEnable(GL_DEPTH_TEST);
437                 glDepthFunc (GL_LEQUAL);
438                 break;
439
440         case cd_texture:
441                 glCullFace(GL_FRONT);
442                 glEnable(GL_CULL_FACE);
443
444                 glShadeModel (GL_FLAT);
445
446                 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
447                 glEnable(GL_TEXTURE_2D);
448
449                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
450                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
451                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
452                 glDisable(GL_BLEND);
453                 glEnable(GL_DEPTH_TEST);
454                 glDepthFunc (GL_LEQUAL);
455
456 #if 0
457
458                 {
459            GLfloat fogColor[4] = {0.0, 1.0, 0.0, 0.25};
460
461                 glFogi (GL_FOG_MODE, GL_LINEAR);
462                 glHint (GL_FOG_HINT, GL_NICEST);  /*  per pixel   */
463                 glFogf (GL_FOG_START, -8192);
464                 glFogf (GL_FOG_END, 65536);
465            glFogfv (GL_FOG_COLOR, fogColor);
466
467                 }
468
469 #endif
470                 break;
471
472         case cd_blend:
473                 glCullFace(GL_FRONT);
474                 glEnable(GL_CULL_FACE);
475
476                 glShadeModel (GL_FLAT);
477
478                 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
479                 glEnable(GL_TEXTURE_2D);
480
481                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
482                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
483                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
484                 glDisable(GL_DEPTH_TEST);
485                 glEnable (GL_BLEND);
486                 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
487                 break;
488         }
489
490         glMatrixMode(GL_TEXTURE);
491         for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
492         {
493                 if (CullBrush (brush))
494                         continue;
495                 if (FilterBrush (brush))
496                         continue;
497
498                 Brush_Draw( brush );
499         }
500         glMatrixMode(GL_PROJECTION);
501
502         //
503         // now draw selected brushes
504         //
505
506         glTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
507         glMatrixMode(GL_TEXTURE);
508
509         // draw normally
510         for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
511         {
512                 Brush_Draw( brush );
513         }
514
515         // blend on top
516         glMatrixMode(GL_PROJECTION);
517
518         glColor4f(1.0, 0.0, 0.0, 0.3);
519         glEnable (GL_BLEND);
520         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
521         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
522         glDisable (GL_TEXTURE_2D);
523         for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
524                 for (face=brush->brush_faces ; face ; face=face->next)
525                         Face_Draw( face );
526         if (selected_face)
527                 Face_Draw(selected_face);
528
529         // non-zbuffered outline
530
531         glDisable (GL_BLEND);
532         glDisable (GL_DEPTH_TEST);
533         glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
534         glColor3f (1, 1, 1);
535         for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
536                 for (face=brush->brush_faces ; face ; face=face->next)
537                         Face_Draw( face );
538
539         // edge / vertex flags
540
541         if (g_qeglobals.d_select_mode == sel_vertex)
542         {
543                 glPointSize (4);
544                 glColor3f (0,1,0);
545                 glBegin (GL_POINTS);
546                 for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
547                         glVertex3fv (g_qeglobals.d_points[i]);
548                 glEnd ();
549                 glPointSize (1);
550         }
551         else if (g_qeglobals.d_select_mode == sel_edge)
552         {
553                 float   *v1, *v2;
554
555                 glPointSize (4);
556                 glColor3f (0,0,1);
557                 glBegin (GL_POINTS);
558                 for (i=0 ; i<g_qeglobals.d_numedges ; i++)
559                 {
560                         v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
561                         v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
562                         glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
563                 }
564                 glEnd ();
565                 glPointSize (1);
566         }
567
568         //
569         // draw pointfile
570         //
571         glEnable(GL_DEPTH_TEST);
572
573         DrawPathLines ();
574
575         if (g_qeglobals.d_pointfile_display_list)
576         {
577                 Pointfile_Draw();
578 //              glCallList (g_qeglobals.d_pointfile_display_list);
579         }
580
581         // bind back to the default texture so that we don't have problems
582         // elsewhere using/modifying texture maps between contexts
583         glBindTexture( GL_TEXTURE_2D, 0 );
584
585     glFinish();
586         QE_CheckOpenGLForErrors();
587 //      Sys_EndWait();
588         if (camera.timing)
589         {
590                 end = Sys_DoubleTime ();
591                 Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start)));
592         }
593 }
594