1 /* camera.c - Managing the Povray camera in preview mode, from OpenGL settings
2  *
3  * Copyright (C) 2003 Patrice St-Gelais
4  *         patrstg@users.sourceforge.net
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include <GL/gl.h>
22 #include <GL/glu.h>
23 #include <gtk/gtk.h>
24 #include <locale.h>
25 
26 #include "gl_preview.h"
27 
28 /* These variables are now defined in globals.h and the RC file
29 
30 #define DISTANCE_INIT 2.5
31 #define DEFAULT_ANGLE 55 // Povray standard (width), translates to ~38 in GL standard (height)
32 // #define DEFAULT_ROT_Y 180
33 #define DEFAULT_ROT_Y 0
34 // #define DEFAULT_ROT_X 140
35 #define DEFAULT_ROT_X 50
36 #define ASPECT_RATIO 1.3333333333
37 
38 */
39 
40 extern gint DEFAULT_ANGLE[], DEFAULT_ROT_X[], DEFAULT_ROT_Y[];
41 extern gfloat DISTANCE_INIT[], ASPECT_RATIO[], RIGHT_LEFT_DISPL[], HEIGHT[];
42 
43 // Camera_def is the default camera, from which others are reset
44 // Camera[NBCAMERAS] is used for keeping the current parameters between each new document
45 
46 camera_struct camera_def = {FALSE, 0, 0, 0.0, 0.0, 0.0, 0, 0.0} ;
47 
48 camera_struct cameras[NBCAMERAS] ;
49 
50 /*************************************************************************************************/
51 // Camera management
52 
53 //	How it works (2003-10-12)
54 //	1. The preview settings (translation and rotation of the HF) are translated
55 //	    into Povray camera parameters (rotation of the camera around the HF,
56 //	    negative translation). Povray lights are not rotated nor translated, as of v. 0.12.
57 //	2. Each document has 5 cameras.
58 //	3. Each camera can be reset to default values (in "camera_def").
59 //	4. The 5 cameras of a newly created document are copied from the last active document.
60 //	5. The 5 cameras of the last active document are saved in a the geomorph_session file
61 //
62 //	camera1, camera2... camera5 are used as buffers for "transmitting" the cameras settings
63 //	between the current document and the newly created ones
64 //	==> each time we activate a document, its cameras must be copied into these buffers
65 
copy_camera(camera_struct * camera_out,camera_struct * camera_in)66 void copy_camera (camera_struct *camera_out, camera_struct *camera_in) {
67 	memcpy(camera_out, camera_in, sizeof(camera_struct));
68 }
69 
init_default_camera()70 void init_default_camera ( ) {
71 	if (camera_def.init)
72 		return;
73 	camera_def.init = TRUE;
74 	camera_def.rot_x = DEFAULT_ROT_X[0];
75 	camera_def.rot_y = DEFAULT_ROT_Y[0];
76 	camera_def.distance = DISTANCE_INIT[0];
77 	camera_def.translate_x = RIGHT_LEFT_DISPL[0];
78 	camera_def.translate_y = HEIGHT[0];
79 	camera_def.angle_w = DEFAULT_ANGLE[0];
80 	camera_def.aspect_ratio = ASPECT_RATIO[0];
81 }
82 
init_cameras()83 void init_cameras ( ) {
84 //	Method initializing the camera buffers (array of NBCAMERAS cameras)
85 //	with the default camera
86 	gint i;
87 	for (i=0; i<NBCAMERAS; i++) {
88 	//	Old way: initialize cameras from the default one
89 //		copy_camera (&cameras[i],&camera_def);
90 	//	Now we can have default values for all the 5 cameras
91 		cameras[i].init = TRUE;
92 		cameras[i].rot_x = DEFAULT_ROT_X[i];
93 		cameras[i].rot_y = DEFAULT_ROT_Y[i];
94 		cameras[i].distance = DISTANCE_INIT[i];
95 		cameras[i].translate_x = RIGHT_LEFT_DISPL[i];
96 		cameras[i].translate_y = HEIGHT[i];
97 		cameras[i].angle_w = DEFAULT_ANGLE[i];
98 		cameras[i].aspect_ratio = ASPECT_RATIO[i];
99 	}
100 }
101 
print_default_camera()102 void print_default_camera () {
103 
104 	printf("DEFAULT CAMERA:\nINIT: %d;\nROT_X: %d;\nROT_Y: %d;\nDISTANCE: %5.3f;\n", camera_def.init,   camera_def.rot_x, camera_def.rot_y, camera_def.distance);
105 	printf("TRANSLATE_X: %5.3f;\nTRANSLATE_Y: %5.3f;\nANGLE_W: %d;\nASPECT_RATIO: %5.3f;\n", camera_def.translate_x,   camera_def.translate_y, camera_def.angle_w, camera_def.aspect_ratio);
106 
107 	printf("DEFAULT_VALUES: \nROT_X: %d;\nROT_Y: %d;\nDISTANCE: %5.3f;\nANGLE_W: %d;\nASPECT_RATIO: %5.3f;\n", DEFAULT_ROT_X[0], DEFAULT_ROT_Y[0], DISTANCE_INIT[0], DEFAULT_ANGLE[0], ASPECT_RATIO[0]);
108 }
109 
gl_save_camera_inc(camera_struct * camera)110 void gl_save_camera_inc (camera_struct * camera) {
111 //	Public method
112 //	Save the current camera parameters in "camera.inc" in the current directory
113 
114 	FILE *fin;
115 	gchar *loc, *tmp, *msg_buf;
116 	if (!(fin=fopen("camera.inc","wb"))) {
117 		msg_buf = (gchar *) x_malloc(sizeof(gchar) + strlen("camera.inc") + strlen(_("Not able to open '%s' file for writing"))+5 , "const gchar (msg_buf - open file for writing)");
118 		sprintf(msg_buf,_("Not able to open '%s' file for writing"),"camera.inc");
119 		my_msg(msg_buf,WARNING);
120 	}
121 	else {
122 		tmp = setlocale(LC_NUMERIC,NULL); // Povray uses "." as decimal separator instead of ","
123 		loc = (gchar *) malloc(strlen(tmp)+1);
124 		strcpy(loc,tmp);
125 		setlocale(LC_NUMERIC,"C");
126 		fprintf(fin,"#declare gl_angle = %d;\n",camera->angle_w);
127 		fprintf(fin,"#declare aspect_ratio = %10.7f;\n",camera->aspect_ratio);
128 		fprintf(fin,"#declare tr_x = %10.7f;\n",-camera->translate_x/2.0);
129 		fprintf(fin,"#declare tr_y = %10.7f;\n",-camera->translate_y/2.0);
130 		fprintf(fin,"#declare tr_z = %10.7f;\n", -(1.35+(camera->distance-2.5)/2.0));
131 		fprintf(fin,"#declare rot_x = %d;\n",camera->rot_x);
132 		fprintf(fin,"#declare rot_y = %d;\n",camera->rot_y);
133 		fprintf(fin,"#declare rot_z = 0;\n");
134 		setlocale(LC_NUMERIC,loc);
135 		free(loc);
136 		fclose(fin);
137 	}
138 }
139 
set_perspective(camera_struct * camera)140 void set_perspective (camera_struct *camera) {
141 
142 //	Set perspective
143 	gfloat angle;
144 
145 	glMatrixMode(GL_PROJECTION);
146 	glLoadIdentity();
147 	// camera->angle_w is in the Povray standard (horizontal)
148 	// gluPerspective() takes a vertical angle
149 	angle = atanf( tanf(((gfloat) camera->angle_w)*PI/360.0)/camera->aspect_ratio);
150 	gluPerspective(angle*360.0/PI,camera->aspect_ratio,0.1,20.0);
151 
152 	glMatrixMode(GL_MODELVIEW);
153 }
154 
set_camera(gpointer glp,camera_struct * camera)155 void set_camera (gpointer glp, camera_struct *camera) {
156 	gl_preview_struct *gl_preview = (gl_preview_struct *) glp;
157 	gtk_adjustment_set_value(
158 		GTK_ADJUSTMENT(gl_preview->adj_rot_y), camera->rot_y);
159 	gtk_adjustment_set_value(
160 		GTK_ADJUSTMENT(gl_preview->adj_rot_x), camera->rot_x);
161 	gtk_adjustment_set_value(
162 		GTK_ADJUSTMENT(gl_preview->adj_distance), camera->distance);
163 	gtk_adjustment_set_value(
164 		GTK_ADJUSTMENT(gl_preview->adj_translate_x), camera->translate_x);
165 	gtk_adjustment_set_value(
166 		GTK_ADJUSTMENT(gl_preview->adj_translate_y), camera->translate_y);
167 	gtk_adjustment_set_value(
168 		GTK_ADJUSTMENT(gl_preview->adj_angle_w), camera->angle_w);
169 	set_perspective (camera);
170 	gtk_widget_queue_draw(GTK_WIDGET(gl_preview->gl_area));
171 }
172 
set_camera_callb(GtkWidget * wdg,gpointer data)173 void set_camera_callb (GtkWidget *wdg, gpointer data) {
174 //	Sets the camera from the label of a radio button
175 	gchar *txt;
176 	gl_preview_struct *gl_preview = (gl_preview_struct *) data;
177 
178 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
179 		return;
180 	gtk_label_get(GTK_LABEL(GTK_BIN(wdg)->child), &txt);
181 
182 	gl_preview->current_camera_id = atoi(txt);
183 	if ( (gl_preview->current_camera_id<1) || (gl_preview->current_camera_id>NBCAMERAS))
184 		gl_preview->current_camera_id = 1;
185 
186 	gl_preview->current_camera_id--;	 // current_camera_id is a C index
187 
188 	set_camera (gl_preview, gl_preview->cameras[gl_preview->current_camera_id]);
189 }
190 
191