1 /*
2 * Tux Racer
3 * Copyright (C) 1999-2001 Jasmin F. Patry
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20
21 #include "tuxracer.h"
22 #include "hier.h"
23 #include "tcl_util.h"
24
25 /*
26 * Callbacks
27 */
28
tux_rotate(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])29 int tux_rotate( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
30 {
31 char *errmsg;
32
33 char *nodename;
34 char axis;
35 double angle ;
36
37 if (4 != argc) {
38 Tcl_AppendResult(ip, argv[0], ": wrong number of arguments\n",
39 "Usage: ", argv[0], " <node> [x|y|z] <angle>",
40 (char *)0 );
41 return TCL_ERROR;
42 }
43
44 /* obtain the nodename */
45 nodename = argv[1];
46
47 /* obtain the axis */
48 axis = argv[2][0];
49 if ('x' != axis && 'y' != axis && 'z' != axis) {
50 Tcl_AppendResult(ip, argv[0], ": invalid rotation axes",
51 (char *)0 );
52 return TCL_ERROR;
53 }
54
55 /* obtain the angle */
56 if (TCL_OK != Tcl_GetDouble(ip, argv[3], &angle)) {
57 Tcl_AppendResult(ip, argv[0], ": invalid rotation angle",
58 (char *)0 );
59 return TCL_ERROR;
60 }
61
62 errmsg = rotate_scene_node(nodename,axis,angle);
63
64 /* report error, if any */
65 if (errmsg) {
66 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
67 return TCL_ERROR;
68 }
69
70 return TCL_OK;
71 }
72
tux_translate(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])73 int tux_translate( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
74 {
75 char *errmsg;
76
77 char *nodename;
78 scalar_t vec[3];
79
80 if (3 != argc) {
81 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
82 "Usage: ", argv[0], " <node> { <x> <y> <z> }",
83 (char *)0 );
84 return TCL_ERROR;
85 }
86
87 /* obtain the nodename */
88 nodename = argv[1];
89
90 /* obtain the translation vector */
91 if (TCL_OK != get_tcl_tuple(ip,argv[2],vec,3)) {
92 Tcl_AppendResult(ip, argv[0], ": invalid translation vector",
93 (char *)0 );
94 return TCL_ERROR;
95 }
96
97 errmsg = translate_scene_node(nodename,make_vector_from_array(vec));
98
99 /* report error, if any */
100 if (errmsg) {
101 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
102 return TCL_ERROR;
103 }
104
105 return TCL_OK;
106 }
107
tux_scale(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])108 int tux_scale( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
109 {
110 char *errmsg;
111
112 char *nodename;
113 scalar_t origin[3];
114 scalar_t factors[3];
115
116 if (4 != argc) {
117 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
118 "Usage: ", argv[0], " <node> { <origin> } "
119 "{ <translation vector> }",
120 (char *)0 );
121 return TCL_ERROR;
122 }
123
124 /* obtain the nodename */
125 nodename = argv[1];
126
127 /* obtain the origin point */
128 if (TCL_OK != get_tcl_tuple(ip,argv[2],origin,3)) {
129 Tcl_AppendResult(ip, argv[0], ": invalid origin point",
130 (char *)0 );
131 return TCL_ERROR;
132 }
133
134 /* obtain the scale factors */
135 if (TCL_OK != get_tcl_tuple(ip,argv[3],factors,3)) {
136 Tcl_AppendResult(ip, argv[0], ": invalid scale factors",
137 (char *)0 );
138 return TCL_ERROR;
139 }
140
141 errmsg = scale_scene_node(nodename,make_point_from_array(origin),factors);
142
143 /* report error, if any */
144 if (errmsg) {
145 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
146 return TCL_ERROR;
147 }
148
149 return TCL_OK;
150 }
151
tux_transform(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])152 int tux_transform( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
153 {
154 char *errmsg;
155
156 char *parent_name;
157 char *child_name;
158
159 if (3 != argc) {
160 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
161 "Usage: ", argv[0], " <parent node> <child node>",
162 (char *)0 );
163 return TCL_ERROR;
164 }
165
166 /* obtain parent's name */
167 parent_name = argv[1];
168
169 /* obtain child's name */
170 child_name = argv[2];
171
172 errmsg = create_tranform_node(parent_name, child_name);
173
174 /* report error, if any */
175 if (errmsg) {
176 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
177 return TCL_ERROR;
178 }
179 return TCL_OK;
180 }
181
tux_sphere(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])182 int tux_sphere( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
183 {
184 char *errmsg;
185
186 char *parent_name;
187 char *child_name;
188 double resolution;
189
190 if (4 != argc) {
191 Tcl_AppendResult( ip, argv[0], ": wrong number of arguments\n",
192 "Usage: ", argv[0], " <parent node> <child node> "
193 "<radius>",
194 (char*) 0 );
195 return TCL_ERROR;
196 }
197
198 /* obtain parent's name */
199 parent_name = argv[1];
200
201 /* obtain child's name */
202 child_name = argv[2];
203
204 if ( TCL_OK != Tcl_GetDouble( ip, argv[3], &resolution ) ) {
205 Tcl_AppendResult( ip, argv[0], ": resolution is invalid",
206 (char*) 0 );
207 return TCL_ERROR;
208 }
209
210 errmsg = create_sphere_node(parent_name, child_name, resolution);
211
212 /* report error, if any */
213 if (errmsg) {
214 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
215 return TCL_ERROR;
216 }
217 return TCL_OK;
218 }
219
220
tux_material(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])221 int tux_material( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
222 {
223 char *errmsg;
224
225 char *mat_name;
226 scalar_t diffuse[3];
227 scalar_t specular[3];
228 double spec_exp;
229
230 if (5 != argc) {
231 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
232 "Usage: ", argv[0], " <name> { <ambient colour> } "
233 "{ <specular colour> } <specular exponent",
234 (char *)0 );
235 return TCL_ERROR;
236 }
237
238 /* obtain material name */
239 mat_name = argv[1];
240
241 /* obtain diffuse colour */
242 if (TCL_OK != get_tcl_tuple(ip,argv[2],diffuse,3)) {
243 Tcl_AppendResult(ip, argv[0], ": invalid diffuse colour",
244 (char *)0 );
245 return TCL_ERROR;
246 }
247
248 /* obtain specular colour */
249 if (TCL_OK != get_tcl_tuple(ip,argv[3],specular,3)) {
250 Tcl_AppendResult(ip, argv[0], ": invalid specular colour",
251 (char *)0 );
252 return TCL_ERROR;
253 }
254
255 /* obtain specular exponent */
256 if (TCL_OK != Tcl_GetDouble(ip,argv[4],&spec_exp)) {
257 Tcl_AppendResult(ip, argv[0], ": invalid specular exponent",
258 (char *)0 );
259 return TCL_ERROR;
260 }
261
262 errmsg = create_material(mat_name,make_colour_from_array(diffuse),
263 make_colour_from_array(specular), spec_exp);
264
265 /* report error, if any */
266 if (errmsg) {
267 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
268 return TCL_ERROR;
269 }
270 return TCL_OK;
271 }
272
tux_surfaceproperty(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])273 int tux_surfaceproperty( ClientData cd, Tcl_Interp *ip,
274 int argc, char *argv[] )
275 {
276 char *errmsg;
277
278 char *node_name;
279 char *mat_name;
280
281 if (3 != argc) {
282 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
283 "Usage: ", argv[0], " <node> <material name>",
284 (char *)0 );
285 return TCL_ERROR;
286 }
287
288 /* obtain node name */
289 node_name = argv[1];
290
291 /* obtain material name */
292 mat_name = argv[2];
293
294 errmsg = set_scene_node_material(node_name, mat_name);
295
296 /* report error, if any */
297 if (errmsg) {
298 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
299 return TCL_ERROR;
300 }
301 return TCL_OK;
302 }
303
tux_shadow(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])304 int tux_shadow( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
305 {
306 char *errmsg;
307
308 char *node_name;
309 char *state;
310
311 if (3 != argc) {
312 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
313 "Usage: ", argv[0], " <node> [on|off]",
314 (char *)0 );
315 return TCL_ERROR;
316 }
317
318 node_name = argv[1];
319 state = argv[2];
320
321 errmsg = set_scene_node_shadow_state(node_name, state);
322
323 /* report error, if any */
324 if (errmsg) {
325 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
326 return TCL_ERROR;
327 }
328 return TCL_OK;
329 }
330
tux_eye(ClientData cd,Tcl_Interp * ip,int argc,char * argv[])331 int tux_eye( ClientData cd, Tcl_Interp *ip, int argc, char *argv[] )
332 {
333 char *errmsg;
334
335 char *node_name;
336 char *which_eye;
337
338 if (3 != argc) {
339 Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n",
340 "Usage: ", argv[0], " <node> [left|right]",
341 (char *)0 );
342 return TCL_ERROR;
343 }
344
345 node_name = argv[1];
346 which_eye = argv[2];
347
348 errmsg = set_scene_node_eye( node_name, which_eye );
349
350 /* report error, if any */
351 if (errmsg) {
352 Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 );
353 return TCL_ERROR;
354 }
355 return TCL_OK;
356 }
357
registerHierCallbacks(Tcl_Interp * ip)358 int registerHierCallbacks (
359 Tcl_Interp *ip
360 ) {
361 Tcl_CreateCommand(ip, "tux_rotate", tux_rotate, 0,0);
362 Tcl_CreateCommand(ip, "tux_translate", tux_translate, 0,0);
363 Tcl_CreateCommand(ip, "tux_scale", tux_scale, 0,0);
364 Tcl_CreateCommand(ip, "tux_sphere", tux_sphere, 0,0);
365 Tcl_CreateCommand(ip, "tux_transform", tux_transform, 0,0);
366 Tcl_CreateCommand(ip, "tux_material", tux_material, 0,0);
367 Tcl_CreateCommand(ip, "tux_surfaceproperty", tux_surfaceproperty, 0,0);
368 Tcl_CreateCommand(ip, "tux_shadow", tux_shadow, 0,0);
369 Tcl_CreateCommand(ip, "tux_eye", tux_eye, 0,0);
370
371 return TCL_OK;
372 }
373