1 /*****************************************************************************
2  *
3  *  Elmer, A Finite Element Software for Multiphysical Problems
4  *
5  *  Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6  *
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation; either version 2
10  *  of the License, or (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  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 this program (in file fem/GPL-2); if not, write to the
19  *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  *****************************************************************************/
23 
24 /*******************************************************************************
25  *
26  * Camera main module & utilities
27  *
28  *******************************************************************************
29  *
30  *                     Author:       Juha Ruokolainen
31  *
32  *                    Address: CSC - IT Center for Science Ltd.
33  *                                Keilaranta 14, P.O. BOX 405
34  *                                  02101 Espoo, Finland
35  *                                  Tel. +358 0 457 2723
36  *                                Telefax: +358 0 457 2302
37  *                              EMail: Juha.Ruokolainen@csc.fi
38  *
39  *                       Date: 3 Oct 1995
40  *
41  * Modification history:
42  *
43  ******************************************************************************/
44 
45 extern void *TCLInterp;
46 
47 
48 /*
49  * $Id: camera.c,v 1.4 2004/11/29 08:27:09 jpr Exp $
50  *
51  * $Log: camera.c,v $
52  * Revision 1.4  2004/11/29 08:27:09  jpr
53  * *** empty log message ***
54  *
55  * Revision 1.3  2003/02/06 09:37:46  jpr
56  * *** empty log message ***
57  *
58  * Revision 1.2  1998/08/01 12:34:09  jpr
59  *
60  * Added Id, started Log.
61  *
62  *
63  */
64 
65 #define MODULE_CAMERAS
66 
67 #include "../elmerpost.h"
68 
69 #ifdef NOTDEF
cam_set_frame(int ncam,int status)70 void cam_set_frame(int ncam,int status)
71 {
72     camera[--ncam].frame = status;
73 }
74 
cam_set_camera_obj_mask(int ncam,int obj,int status)75 void cam_set_camera_obj_mask(int ncam,int obj,int status)
76 {
77     --ncam;
78     camera[ncam].obj_mask[obj] = status;
79 }
80 #endif
81 
82 /*******************************************************************************
83  *
84  *     Name:        cam_set_viewport( camera_t *,double,double,double,double )
85  *
86  *     Purpose:     set viewport values given camera structure pointer and
87  *                  two points.
88  *
89  *     Parameters:
90  *
91  *         Input:   (double,double) lower left hand corner of the viewport
92  *                  (double,double) upper right hand corner of the viewport
93  *
94  *         Output:  (camera_t *) camera structure is modified
95  *
96  *   Return value:  void
97  *
98  *******************************************************************************/
cam_set_viewport(camera_t * camera,double lx,double ly,double hx,double hy)99 void cam_set_viewport(camera_t *camera,double lx,double ly,double hx,double hy)
100 {
101     camera->ViewportLowX  = lx;
102     camera->ViewportLowY  = ly;
103     camera->ViewportHighX = hx;
104     camera->ViewportHighY = hy;
105 }
106 
107 /*******************************************************************************
108  *
109  *     Name:        cam_set_projection( camera_t *,camera_proj_t )
110  *
111  *     Purpose:     Set camera projection type. Internal only.
112  *
113  *     Parameters:
114  *
115  *         Input:   (camera_proj_t) projection type to set.
116  *
117  *         Output:  (camera_t *) camera structure is modified
118  *
119  *   Return value:  void
120  *
121  *******************************************************************************/
cam_set_projection(camera_t * camera,camera_proj_t projection)122 void cam_set_projection( camera_t *camera,camera_proj_t projection )
123 {
124     camera->ProjectionType = projection;
125 }
126 
127 /*******************************************************************************
128  *
129  *     Name:        cam_set_file_angle( camera_t *,float )
130  *
131  *     Purpose:     Set camera filed angle for perspective projection.
132  *                  Internal only.
133  *
134  *     Parameters:
135  *
136  *         Input:   (float) intput field angle.
137  *
138  *         Output:  (camera_t *) camera structure is modified
139  *
140  *   Return value:  void
141  *
142  *******************************************************************************/
cam_set_field_angle(camera_t * camera,double angle)143 void cam_set_field_angle( camera_t *camera, double angle )
144 {
145     camera->FieldAngle = angle;
146 }
147 
148 /*******************************************************************************
149  *
150  *     Name:        cam_set_look_from( camera_t *,double,double,double,int )
151  *
152  *     Purpose:     Set camera position to given value.
153  *
154  *     Parameters:
155  *
156  *         Input:   (double,double,double) x,y,z coordinates of the camera
157  *                  (int) flag saying if inputs should be added to current
158  *                        position
159  *
160  *         Output:  (camera_t *) camera structure is modified
161  *
162  *   Return value:  void
163  *
164  *******************************************************************************/
cam_set_look_from(camera_t * camera,double x,double y,double z,int relative)165 void cam_set_look_from(camera_t *camera,double x,double y,double z,int relative)
166 {
167     if ( relative )
168     {
169         camera->LookFromX += x;
170         camera->LookFromY += y;
171         camera->LookFromZ += z;
172     } else
173     {
174         camera->LookFromX = x;
175         camera->LookFromY = y;
176         camera->LookFromZ = z;
177     }
178 }
179 
180 /*******************************************************************************
181  *
182  *     Name:        cam_set_up_vector( camera_t *,double,double,double )
183  *
184  *     Purpose:     Set camera up vector
185  *
186  *     Parameters:
187  *
188  *         Input:   (double,double,double) x,y,z direction upwadrds
189  *
190  *         Output:  (camera_t *) camera structure is modified
191  *
192  *   Return value:  void
193  *
194  *******************************************************************************/
cam_set_up_vector(camera_t * camera,double x,double y,double z)195 void cam_set_up_vector(camera_t *camera,double x,double y,double z )
196 {
197     camera->UpX = x;
198     camera->UpY = y;
199     camera->UpZ = z;
200 }
201 
202 /*******************************************************************************
203  *
204  *     Name:        cam_set_clip( camera_t *,double,double )
205  *
206  *     Purpose:     Set camera clip viewing planes
207  *
208  *     Parameters:
209  *
210  *         Input:   (double,double) near and far plane coordinates
211  *
212  *         Output:  (camera_t *) camera structure is modified
213  *
214  *   Return value:  void
215  *
216  *******************************************************************************/
cam_set_clip(camera_t * camera,double n,double f)217 void cam_set_clip(camera_t *camera,double n,double f)
218 {
219     camera->ClipNear = n;
220     camera->ClipFar  = f;
221 }
222 
223 /*******************************************************************************
224  *
225  *     Name:        cam_set_look_to( camera_t *,double,double,double,int )
226  *
227  *     Purpose:     Set point at which the camera is aimed
228  *
229  *     Parameters:
230  *
231  *         Input:   (double,double,double) x,y,z coordinates
232  *                  (int) flag saying if inputs should be added to current
233  *                        position
234  *
235  *         Output:  (camera_t *) camera structure is modified
236  *
237  *   Return value:  void
238  *
239  *******************************************************************************/
cam_set_look_to(camera_t * camera,double x,double y,double z,int relative)240 void cam_set_look_to(camera_t *camera,double x,double y,double z,int relative)
241 {
242     if ( relative )
243     {
244         camera->LookAtX += x;
245         camera->LookAtY += y;
246         camera->LookAtZ += z;
247     } else
248     {
249         camera->LookAtX = x;
250         camera->LookAtY = y;
251         camera->LookAtZ = z;
252     }
253 }
254 
cam_set_onoff(camera_t * camera,int onoff)255 void cam_set_onoff( camera_t *camera,int onoff)
256 {
257     camera->OnOff = onoff;
258 }
259 
260 /*******************************************************************************
261  *
262  *     Name:        cam_add_camera( camera_t *, char * )
263  *
264  *     Purpose:     Add camera to a given list of camera with given name.
265  *                  If one with given name already exists, it is returned.
266  *
267  *     Parameters:
268  *
269  *         Input:   (camera_t *) input list of cameras
270  *                  (char *)     name to be given to the camera
271  *
272  *         Output:  (camera_t *) camera structure is modified
273  *
274  *   Return value:  (camera_t *) pointer to the created camera structure
275  *
276  *******************************************************************************/
cam_add_camera(camera_t * camera,char * name)277 camera_t *cam_add_camera( camera_t *camera,char *name )
278 {
279     camera_t *new_cam = camera;
280 
281 
282     while( new_cam )
283     {
284 		if ( strcmp( new_cam->Name,name ) == 0 ) return new_cam;
285 		new_cam = new_cam->Next;
286     }
287 
288 	new_cam = (camera_t *)calloc(1,sizeof(camera_t) );
289 
290     if ( !new_cam )
291     {
292         fprintf( stderr, "cam_add_camera: FATAL: can't alloc a few bytes of memory\n" );
293         return NULL;
294     }
295 
296     if ( !(new_cam->Name = (char *)malloc( strlen(name)+1 ) ) )
297     {
298         fprintf( stderr, "cam_add_camera: FATAL: can't alloc a few bytes of memory\n" );
299         free( new_cam );
300         return NULL;
301     }
302 
303     strcpy( new_cam->Name, name );
304 
305     if ( camera )
306     {
307         while( camera->Next ) camera = camera->Next;
308         camera->Next = new_cam;
309     }
310 
311     return new_cam;
312 }
313 
314 /*******************************************************************************
315  *
316  *     Name:        cam_delete_list( camera_t * )
317  *
318  *     Purpose:     Delete (free mem ) list of camera definitions
319  *
320  *     Parameters:
321  *
322  *         Input:   (camera_t *) input list of cameras
323  *
324  *         Output:  none
325  *
326  *   Return value:  void
327  *
328  *******************************************************************************/
cam_delete_list(camera_t * camera)329 void cam_delete_list( camera_t *camera )
330 {
331     camera_t *ptr;
332 
333     while( camera )
334     {
335         if ( camera->Name ) free( camera->Name );
336 
337         ptr    = camera;
338         camera = camera->Next;
339 
340         free( ptr );
341     }
342 }
343 
344 static double upx,upy,upz,viewx,viewy,viewz,tox,toy,toz;
345 
346 #include <tcl.h>
347 /*******************************************************************************
348  *
349  *     Name:        cam_display_list( camera_t *, object_t * )
350  *
351  *     Purpose:     Display list of given objecst is given list of cameras
352  *
353  *     Parameters:
354  *
355  *         Input:   (camera_t *) input list of cameras
356  *                  (object_t *) input list of objecst
357  *
358  *         Output:  graphics
359  *
360  *   Return value:  if mouse interaction is going on and too slow FALSE,
361  *                  otherwise TRUE
362  *
363  *******************************************************************************/
cam_display_list(camera_t * camera,object_t * object)364 int cam_display_list( camera_t *camera, object_t *object )
365 {
366     double t = RealTime(), ct = CPUTime();
367 
368     int FitToPage = 0, nofcameras;
369     camera_t *cam;
370 
371     if ( GlobalOptions.OutputPS ) {
372        initglp( Tcl_GetVar( TCLInterp, "PSFileName", TCL_GLOBAL_ONLY ),
373                 GlobalOptions.FitToPagePS );
374     }
375     if ( user_hook_before_all ) (*user_hook_before_all)( camera,object );
376 
377      nofcameras = 0;
378      for( cam=camera; cam != NULL; cam = cam->Next, nofcameras++ );
379 
380     for( GlobalPass=0; GlobalPass < 2; GlobalPass++ )
381     {
382         for( cam=camera; cam != NULL; cam = cam->Next )
383         {
384             if ( !cam->OnOff ) continue;
385 
386             gra_set_projection( cam->ProjectionType, cam->FieldAngle,
387                                 cam->ViewportLowX, cam->ViewportHighX,
388                                 cam->ViewportLowY, cam->ViewportHighY,
389 	       	 	        cam->ClipNear, cam->ClipFar, nofcameras>1 );
390 
391             gra_push_matrix();
392 
393             gra_look_at(
394                          cam->LookFromX, cam->LookFromY, cam->LookFromZ,
395                             cam->LookAtX, cam->LookAtY, cam->LookAtZ,
396                                   cam->UpX, cam->UpY, cam->UpZ
397                        );
398 
399             if ( user_hook_camera_before ) (*user_hook_camera_before)( GlobalPass,cam,object,t );
400 
401             if ( !obj_display_list( object, t ) ) return FALSE;
402 
403             if ( user_hook_camera_after ) (*user_hook_camera_after)( GlobalPass,cam,object,t );
404 
405             gra_pop_matrix();
406 
407              if ( BreakLoop ) break;
408 
409         }
410         if ( BreakLoop ) break;
411     }
412 
413     if ( user_hook_after_all ) (*user_hook_after_all)( camera,object );
414     if ( GlobalOptions.OutputPS ) stopglp();
415 
416     return TRUE;
417 }
418