"Fossies" - the Fresh Open Source Software Archive 
Member "gamgi0.17.5x/src/io/gamgi_io_x3d.c" (23 Feb 2022, 58955 Bytes) of package /linux/misc/gamgi-all-0.17.5x.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*******************************************
2 *
3 * $GAMGI/src/io/gamgi_io_x3d.c
4 *
5 * Copyright (C) 2008 Tiago Farto
6 *
7 * Distributed under the terms of the GNU
8 * General Public License: $GAMGI/LICENSE
9 *
10 */
11
12 #include "gamgi_engine.h"
13 #include "gamgi_io.h"
14 #include "gamgi_gtk.h"
15 #include "gamgi_mesa.h"
16 #include "gamgi_math.h"
17 #include "gamgi_phys.h"
18 #include "gamgi_global.h"
19
20 #include "gamgi_engine_list.h"
21 #include "gamgi_engine_array.h"
22 #include "gamgi_mesa_atom.h"
23 #include "gamgi_mesa_bond.h"
24 #include "gamgi_math_vector.h"
25 #include "gamgi_math_quaternion.h"
26 #include "gamgi_io_file.h"
27 #include "gamgi_io_error.h"
28 #include "gamgi_io_x3d_render.h"
29
30 /************* internal function ***********
31 * *
32 * STATIC_SCALE *
33 * *
34 * open the scale node of an object *
35 *******************************************/
36
37 static void static_scale (FILE *fp, double scale, double *center,
38 gamgi_bool *error)
39 {
40 char string[GAMGI_ENGINE_LINE];
41
42 /*******************
43 * Transform start *
44 *******************/
45
46 /*********************************************************
47 * move the object center to the origin, scale the *
48 * object, move the object back to its original position *
49 *********************************************************/
50
51 if (fabs (scale - 1.0) > GAMGI_MATH_TOLERANCE)
52 {
53 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
54 gamgi->gamgi->length, center[0],
55 gamgi->gamgi->length, center[1],
56 gamgi->gamgi->length, center[2]);
57 gamgi_io_file_fprintf (fp, string, error);
58
59 sprintf (string, "<Transform scale=\"%.*f %.*f %.*f\">\n",
60 GAMGI_MATH_DECIMAL_SCALE, scale,
61 GAMGI_MATH_DECIMAL_SCALE, scale,
62 GAMGI_MATH_DECIMAL_SCALE, scale);
63 gamgi_io_file_fprintf (fp, string, error);
64
65 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
66 gamgi->gamgi->length, -center[0],
67 gamgi->gamgi->length, -center[1],
68 gamgi->gamgi->length, -center[2]);
69 gamgi_io_file_fprintf (fp, string, error);
70 }
71 }
72
73 /************* internal function ***********
74 * *
75 * STATIC_UNSCALE *
76 * *
77 * close the scale node of an object *
78 *******************************************/
79
80 static void static_unscale (FILE *fp, double scale, gamgi_bool *error)
81 {
82 /*****************
83 * Transform end *
84 *****************/
85
86 if (fabs (scale - 1.0) > GAMGI_MATH_TOLERANCE)
87 gamgi_io_file_fprintf(fp, "</Transform>\n</Transform>\n</Transform>\n", error);
88 }
89
90 static void static_line (FILE *fp, gamgi_bool lights, float *color,
91 double *start, double *end, int width, gamgi_bool *error)
92 {
93 char string[GAMGI_ENGINE_LINE];
94
95 /***************
96 * Shape start *
97 ***************/
98
99 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
100
101 /************************
102 * Appearance start+end *
103 ************************/
104
105 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
106
107 if (lights == TRUE)
108 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
109 GAMGI_MATH_DECIMAL_COLOR, color[0],
110 GAMGI_MATH_DECIMAL_COLOR, color[1],
111 GAMGI_MATH_DECIMAL_COLOR, color[2]);
112 else
113 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
114 GAMGI_MATH_DECIMAL_COLOR, color[0],
115 GAMGI_MATH_DECIMAL_COLOR, color[1],
116 GAMGI_MATH_DECIMAL_COLOR, color[2]);
117 gamgi_io_file_fprintf (fp, string, error);
118
119 sprintf (string, "<LineProperties linewidthScaleFactor=\"%d\"/>\n", width);
120 gamgi_io_file_fprintf (fp, string, error);
121
122 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
123
124 /******************
125 * Line start+end *
126 ******************/
127
128 gamgi_io_file_fprintf (fp, "<IndexedLineSet coordIndex=\"0 1 -1\">\n", error);
129 sprintf (string, "<Coordinate point=\"%.*f %.*f %.*f %.*f %.*f %.*f\"/>\n",
130 gamgi->gamgi->length, start[0],
131 gamgi->gamgi->length, start[1],
132 gamgi->gamgi->length, start[2],
133 gamgi->gamgi->length, end[0],
134 gamgi->gamgi->length, end[1],
135 gamgi->gamgi->length, end[2]);
136 gamgi_io_file_fprintf (fp, string, error);
137 gamgi_io_file_fprintf (fp, "</IndexedLineSet>\n", error);
138
139 /*************
140 * Shape end *
141 *************/
142
143 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
144 }
145
146 static void static_cylinder (FILE *fp, gamgi_bool lights, float *color,
147 double length, double radius, gamgi_bool *error)
148 {
149 char string[GAMGI_ENGINE_LINE];
150
151 /***************
152 * Shape start *
153 ***************/
154
155 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
156
157 /************************
158 * Appearance start+end *
159 ************************/
160
161 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
162 if (lights == TRUE)
163 sprintf (string, "<Material shininess=\"%.*f\" diffuseColor=\"%.*f %.*f %.*f\"/>\n",
164 GAMGI_MATH_DECIMAL_SHININESS, gamgi->light->shininess,
165 GAMGI_MATH_DECIMAL_COLOR, color[0],
166 GAMGI_MATH_DECIMAL_COLOR, color[1],
167 GAMGI_MATH_DECIMAL_COLOR, color[2]);
168 else
169 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
170 GAMGI_MATH_DECIMAL_COLOR, color[0],
171 GAMGI_MATH_DECIMAL_COLOR, color[1],
172 GAMGI_MATH_DECIMAL_COLOR, color[2]);
173 gamgi_io_file_fprintf (fp, string, error);
174 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
175
176 /**********************
177 * Cylinder start+end *
178 **********************/
179
180 sprintf (string, "<Cylinder height=\"%.*f\" radius=\"%.*f\" top=\"false\" bottom=\"false\"/>\n",
181 gamgi->gamgi->length, length, gamgi->gamgi->length, radius);
182 gamgi_io_file_fprintf (fp, string, error);
183
184 /*************
185 * Shape end *
186 *************/
187
188 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
189 }
190
191 static void static_text (FILE *fp, gamgi_text *text,
192 gamgi_bool lights, gamgi_bool *error)
193 {
194 gamgi_dlist *dlist;
195 char string[GAMGI_ENGINE_LINE];
196 double axis[3];
197 double phi;
198
199 /*************************
200 * scale Transform start *
201 *************************/
202
203 static_scale (fp, text->object.scale, text->center, error);
204
205 /*******************************
206 * rotate+move Transform start *
207 *******************************/
208
209 gamgi_math_quaternion_to_axis (text->quaternion, &phi, axis);
210 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\" rotation=\"%.*f %.*f %.*f %.*f\">\n",
211 gamgi->gamgi->length, text->origin[0],
212 gamgi->gamgi->length, text->origin[1],
213 gamgi->gamgi->length, text->origin[2],
214 gamgi->gamgi->length, axis[0],
215 gamgi->gamgi->length, axis[1],
216 gamgi->gamgi->length, axis[2],
217 gamgi->gamgi->angle, phi);
218 gamgi_io_file_fprintf (fp, string, error);
219
220 /***************
221 * Shape start *
222 ***************/
223
224 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
225
226 /************************
227 * Appearance start+end *
228 ************************/
229
230 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
231 if (lights == TRUE)
232 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
233 GAMGI_MATH_DECIMAL_COLOR, text->red,
234 GAMGI_MATH_DECIMAL_COLOR, text->green,
235 GAMGI_MATH_DECIMAL_COLOR, text->blue);
236 else
237 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
238 GAMGI_MATH_DECIMAL_COLOR, text->red,
239 GAMGI_MATH_DECIMAL_COLOR, text->green,
240 GAMGI_MATH_DECIMAL_COLOR, text->blue);
241 gamgi_io_file_fprintf(fp, string, error);
242 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
243
244 /*************************
245 * export geometric data *
246 *************************/
247
248 if (text->font > GAMGI_IO_FONTS_WIRED)
249 gamgi_io_x3d_render_solid (fp, text, error);
250 else
251 gamgi_io_x3d_render_wired (fp, text, error);
252
253 /************************************
254 * Shape, rotate+move Transform end *
255 ************************************/
256
257 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
258 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
259
260 /***********************
261 * child objects: text *
262 ***********************/
263
264 for (dlist = text->text_start; dlist != NULL; dlist = dlist->next)
265 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
266
267 /***********************
268 * scale Transform end *
269 ***********************/
270
271 static_unscale (fp, text->object.scale, error);
272 }
273
274 static void static_orbital (FILE *fp, gamgi_orbital *orbital,
275 gamgi_bool lights, gamgi_bool *error)
276 {
277 gamgi_dlist *dlist;
278 int *dots;
279 char string[GAMGI_ENGINE_LINE];
280 double axis[3];
281 double phi;
282 float background[4];
283 float color[3];
284
285 /*************************
286 * scale Transform start *
287 *************************/
288
289 static_scale (fp, orbital->object.scale, orbital->center, error);
290
291 /*******************************
292 * rotate+move Transform start *
293 *******************************/
294
295 gamgi_math_quaternion_to_axis (orbital->quaternion, &phi, axis);
296 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\" rotation=\"%.*f %.*f %.*f %.*f\">\n",
297 gamgi->gamgi->length, orbital->origin[0],
298 gamgi->gamgi->length, orbital->origin[1],
299 gamgi->gamgi->length, orbital->origin[2],
300 gamgi->gamgi->length, axis[0],
301 gamgi->gamgi->length, axis[1],
302 gamgi->gamgi->length, axis[2],
303 gamgi->gamgi->angle, phi);
304 gamgi_io_file_fprintf (fp, string, error);
305
306 glGetFloatv (GL_COLOR_CLEAR_VALUE, background);
307
308 dots = orbital->dots;
309 if (orbital->style == GAMGI_MESA_WIRED)
310 {
311 /*************************
312 * export geometric data *
313 *************************/
314
315 glLineWidth (4.0);
316 if (dots[1] > 0)
317 {
318 color[0] = orbital->base_r;
319 color[1] = orbital->base_g;
320 color[2] = orbital->base_b;
321 gamgi_io_x3d_render_points (fp, dots[1],
322 orbital->points + 3 * dots[0], color, error);
323 }
324
325 if (dots[2] > 0)
326 {
327 color[0] = orbital->phase_r;
328 color[1] = orbital->phase_g;
329 color[2] = orbital->phase_b;
330 gamgi_io_x3d_render_points (fp, dots[2],
331 orbital->points + 3 * dots[0] + 3 * dots[1], color, error);
332 }
333 }
334
335 if (orbital->style == GAMGI_MESA_SOLID)
336 {
337 if (dots[1] > 0)
338 {
339 /***************
340 * Shape start *
341 ***************/
342
343 /************************
344 * Appearance start+end *
345 ************************/
346
347 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
348 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
349 if (lights == TRUE)
350 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
351 GAMGI_MATH_DECIMAL_COLOR, orbital->base_r,
352 GAMGI_MATH_DECIMAL_COLOR, orbital->base_g,
353 GAMGI_MATH_DECIMAL_COLOR, orbital->base_b);
354 else
355 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
356 GAMGI_MATH_DECIMAL_COLOR, orbital->base_r,
357 GAMGI_MATH_DECIMAL_COLOR, orbital->base_g,
358 GAMGI_MATH_DECIMAL_COLOR, orbital->base_b);
359 gamgi_io_file_fprintf (fp, string, error);
360 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
361
362 /*************************
363 * export geometric data *
364 *************************/
365
366 gamgi_io_x3d_render_triangles (fp, dots[1] / 3,
367 orbital->points + 3 * dots[0], error);
368 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
369
370 /*************
371 * Shape end *
372 *************/
373 }
374
375 if (dots[2] > 0)
376 {
377 /***************
378 * Shape start *
379 ***************/
380
381 /************************
382 * Appearance start+end *
383 ************************/
384
385 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
386 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
387 if (lights == TRUE)
388 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
389 GAMGI_MATH_DECIMAL_COLOR, orbital->phase_r,
390 GAMGI_MATH_DECIMAL_COLOR, orbital->phase_g,
391 GAMGI_MATH_DECIMAL_COLOR, orbital->phase_b);
392 else
393 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
394 GAMGI_MATH_DECIMAL_COLOR, orbital->phase_r,
395 GAMGI_MATH_DECIMAL_COLOR, orbital->phase_g,
396 GAMGI_MATH_DECIMAL_COLOR, orbital->phase_b);
397 gamgi_io_file_fprintf (fp, string, error);
398 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
399
400 /*************************
401 * export geometric data *
402 *************************/
403
404 gamgi_io_x3d_render_triangles (fp, dots[2] / 3,
405 orbital->points + 3 * dots[0] + 3 * dots[1], error);
406 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
407
408 /*************
409 * Shape end *
410 *************/
411 }
412 }
413
414 /*****************************
415 * rotate+move Transform end *
416 *****************************/
417
418 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
419
420 /***********************
421 * child objects: text *
422 ***********************/
423
424 for (dlist = orbital->text_start; dlist!=NULL; dlist = dlist->next)
425 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
426
427 /***********************
428 * scale Transform end *
429 ***********************/
430
431 static_unscale (fp, orbital->object.scale, error);
432 }
433
434 static void static_bond (FILE *fp, gamgi_bond *bond, gamgi_atom *atom,
435 gamgi_bool lights, gamgi_bool *error)
436 {
437 gamgi_dlist *dlist;
438 char string[GAMGI_ENGINE_LINE];
439 double endpoint[3];
440 double center[3], sub[3], axis[3];
441 double length, radius;
442 double angle = 0.0;
443 float background[4];
444 float color[3];
445
446 glGetFloatv (GL_COLOR_CLEAR_VALUE, background);
447
448 if (bond->atom2 == NULL) return;
449
450 /***************************************
451 * when color is a bond property, this *
452 * function is executed only for atom1 *
453 ***************************************/
454
455 if (bond->color == TRUE && bond->atom2 == atom) return;
456
457 if (bond->color == FALSE)
458 {
459 color[0] = atom->red;
460 color[1] = atom->green;
461 color[2] = atom->blue;
462
463 /*****************************************************
464 * the point where color changes from atom1 to atom2 *
465 *****************************************************/
466
467 endpoint[0] = (bond->atom1->position[0] + bond->atom2->position[0]) / 2.0;
468 endpoint[1] = (bond->atom1->position[1] + bond->atom2->position[1]) / 2.0;
469 endpoint[2] = (bond->atom1->position[2] + bond->atom2->position[2]) / 2.0;
470 }
471 else
472 {
473 color[0] = bond->red;
474 color[1] = bond->green;
475 color[2] = bond->blue;
476
477 /***********************************
478 * this code runs for atom1 only, *
479 * so the endpoint is always atom2 *
480 ***********************************/
481
482 endpoint[0] = bond->atom2->position[0];
483 endpoint[1] = bond->atom2->position[1];
484 endpoint[2] = bond->atom2->position[2];
485 }
486
487 if (bond->draw == gamgi_mesa_bond_draw_cylinder)
488 {
489 /******************
490 * draw cylinders *
491 ******************/
492
493 radius = bond->object.scale * bond->size * gamgi->atom->min;
494
495 center[0] = (atom->position[0] + endpoint[0]) / 2.0;
496 center[1] = (atom->position[1] + endpoint[1]) / 2.0;
497 center[2] = (atom->position[2] + endpoint[2]) / 2.0;
498
499 if (atom == bond->atom1)
500 gamgi_math_vector_sub (atom->position, endpoint, sub);
501 else
502 gamgi_math_vector_sub (endpoint, atom->position, sub);
503 length = gamgi_math_vector_length (sub);
504 angle = acos (sub[1] / length);
505 gamgi_math_vector_absolute (axis, sub[2], 0.0, -sub[0]);
506 gamgi_math_vector_normal (axis);
507
508 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\" rotation=\"%.*f %.*f %.*f %.*f\">\n",
509 gamgi->gamgi->length, center[0],
510 gamgi->gamgi->length, center[1],
511 gamgi->gamgi->length, center[2],
512 gamgi->gamgi->length, axis[0],
513 gamgi->gamgi->length, axis[1],
514 gamgi->gamgi->length, axis[2],
515 gamgi->gamgi->angle, angle);
516 gamgi_io_file_fprintf (fp, string, error);
517
518 if (bond->order <= 1.5)
519 {
520 /**********************************************
521 * single bond: rendered as a single cylinder *
522 **********************************************/
523
524 static_cylinder (fp, lights, color, length, radius, error);
525 }
526 else if (bond->order <= 2.5)
527 {
528 /********************************************************************
529 * double bond: render a central cylinder and two lateral cylinders *
530 ********************************************************************/
531
532 static_cylinder (fp, lights, color, length, radius, error);
533
534 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
535 gamgi->gamgi->length, 0.0, gamgi->gamgi->length, 0.0,
536 gamgi->gamgi->length, -radius);
537 gamgi_io_file_fprintf (fp, string, error);
538 static_cylinder (fp, lights, color, length, radius / 2.0, error);
539 gamgi_io_file_fprintf(fp, "</Transform>\n", error);
540
541 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
542 gamgi->gamgi->length, 0.0, gamgi->gamgi->length, 0.0,
543 gamgi->gamgi->length, radius);
544 gamgi_io_file_fprintf(fp, string, error);
545 static_cylinder (fp, lights, color, length, radius / 2.0, error);
546 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
547 }
548 else
549 {
550 /*********************************************************************
551 * triple bond: render a central cylinder and four lateral cylinders *
552 *********************************************************************/
553
554 static_cylinder (fp, lights, color, length, radius, error);
555
556 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
557 gamgi->gamgi->length, -radius,
558 gamgi->gamgi->length, 0.0, gamgi->gamgi->length, 0.0);
559 gamgi_io_file_fprintf (fp, string, error);
560 static_cylinder (fp, lights, color, length, radius / 3.0, error);
561 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
562
563 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
564 gamgi->gamgi->length, radius,
565 gamgi->gamgi->length, 0.0, gamgi->gamgi->length, 0.0);
566 gamgi_io_file_fprintf (fp, string, error);
567 static_cylinder (fp, lights, color, length, radius / 3.0, error);
568 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
569
570 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
571 gamgi->gamgi->length, 0.0, gamgi->gamgi->length, 0.0,
572 gamgi->gamgi->length, -radius);
573 gamgi_io_file_fprintf (fp, string, error);
574 static_cylinder (fp, lights, color, length, radius / 3.0, error);
575 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
576
577 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
578 gamgi->gamgi->length, 0.0, gamgi->gamgi->length, 0.0,
579 gamgi->gamgi->length, radius);
580 gamgi_io_file_fprintf (fp, string, error);
581 static_cylinder (fp, lights, color, length, radius / 3.0, error);
582 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
583 }
584 gamgi_io_file_fprintf(fp, "</Transform>\n", error);
585 }
586 else
587 {
588 /**************
589 * draw lines *
590 **************/
591
592 if (bond->order <= 1.5)
593 {
594 /******************************************************************
595 * bonds rendered as a single line: render the whole bond segment *
596 ******************************************************************/
597
598 static_line (fp, lights, color, atom->position, endpoint, 2, error);
599 }
600 else if (bond->order <= 2.5)
601 {
602 /*********************************************************************
603 * bonds rendered as a double line: 1) render the whole bond segment *
604 * with bond color; 2) render a inner segment with background color *
605 *********************************************************************/
606
607 static_line (fp, lights, background, atom->position, endpoint, 2, error);
608 static_line (fp, lights, color, atom->position, endpoint, 6, error);
609 }
610 else
611 {
612 /***************************************************************
613 * bonds rendered as a triple line: 1) render the whole bond *
614 * segment with bond color; 2) render inner segment with *
615 * background color; 3) render central segment with bond color *
616 ***************************************************************/
617
618 static_line (fp, lights, color, atom->position, endpoint, 2, error);
619 static_line (fp, lights, background, atom->position, endpoint, 6, error);
620 static_line (fp, lights, color, atom->position, endpoint, 10, error);
621 }
622 }
623
624 /**************************************************
625 * when color is inherited from the parent atoms, *
626 * this function is run for each atom, but the *
627 * section below is executed only for atom 1 *
628 **************************************************/
629
630 if (bond->color == FALSE && atom == bond->atom2) return;
631
632 /********************************
633 * child objects: orbital, text *
634 ********************************/
635
636 center[0] = (bond->atom1->position[0] + bond->atom2->position[0]) / 2.0;
637 center[1] = (bond->atom1->position[1] + bond->atom2->position[1]) / 2.0;
638 center[2] = (bond->atom1->position[2] + bond->atom2->position[2]) / 2.0;
639
640 static_scale (fp, bond->object.scale, center, error);
641
642 for (dlist = bond->orbital_start; dlist != NULL; dlist = dlist->next)
643 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
644
645 for (dlist = bond->text_start; dlist != NULL; dlist = dlist->next)
646 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
647
648 static_unscale (fp, bond->object.scale, error);
649 }
650
651 static void static_atom (FILE *fp, gamgi_atom *atom,
652 gamgi_bool lights, gamgi_bool *error)
653 {
654 gamgi_dlist *dlist;
655 char string[GAMGI_ENGINE_LINE];
656 double radius;
657 float size;
658
659 static_scale (fp, atom->object.scale, atom->position, error);
660
661 if (atom->draw == gamgi_mesa_atom_draw_sphere || atom->bond_start == NULL)
662 {
663 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
664 gamgi->gamgi->length, atom->position[0],
665 gamgi->gamgi->length, atom->position[1],
666 gamgi->gamgi->length, atom->position[2]);
667 gamgi_io_file_fprintf(fp, string, error);
668
669 gamgi_io_file_fprintf (fp, "<Shape>\n<Appearance>\n", error);
670 if (lights == TRUE)
671 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
672 GAMGI_MATH_DECIMAL_COLOR, atom->red,
673 GAMGI_MATH_DECIMAL_COLOR, atom->green,
674 GAMGI_MATH_DECIMAL_COLOR, atom->blue);
675 else
676 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
677 GAMGI_MATH_DECIMAL_COLOR, atom->red,
678 GAMGI_MATH_DECIMAL_COLOR, atom->green,
679 GAMGI_MATH_DECIMAL_COLOR, atom->blue);
680 gamgi_io_file_fprintf (fp, string, error);
681
682 if (atom->draw != gamgi_mesa_atom_draw_sphere)
683 {
684 sprintf (string, "<LineProperties linewidthScaleFactor=\"%d\"/>\n",
685 gamgi->atom->width);
686 gamgi_io_file_fprintf (fp, string, error);
687 }
688 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
689
690 if (atom->draw == gamgi_mesa_atom_draw_sphere)
691 {
692 radius = atom->size * (atom->variancy * atom->radius +
693 (1 - atom->variancy) * gamgi->atom->min);
694 sprintf (string, "<Sphere radius=\"%.*f\"/>\n",
695 gamgi->gamgi->length, radius);
696 gamgi_io_file_fprintf (fp, string, error);
697 }
698
699 if (atom->draw == gamgi_mesa_atom_draw_cross)
700 {
701 size = 0.5 * gamgi->atom->size * gamgi->atom->min;
702 gamgi_io_file_fprintf (fp, "<IndexedLineSet coordIndex=\""
703 "0 1 -1 2 3 -1 4 5 -1\">\n", error);
704 sprintf (string, "<Coordinate point=\""
705 "%.*f 0 0 %.*f 0 0 0 %.*f 0 0 %.*f 0 0 0 %.*f 0 0 %.*f\"/>\n",
706 GAMGI_MATH_DECIMAL_SIZE, -size, GAMGI_MATH_DECIMAL_SIZE, size,
707 GAMGI_MATH_DECIMAL_SIZE, -size, GAMGI_MATH_DECIMAL_SIZE, size,
708 GAMGI_MATH_DECIMAL_SIZE, -size, GAMGI_MATH_DECIMAL_SIZE, size);
709 gamgi_io_file_fprintf(fp, string, error);
710 gamgi_io_file_fprintf(fp, "</IndexedLineSet>\n", error);
711 }
712
713 gamgi_io_file_fprintf(fp, "</Shape>\n</Transform>\n", error);
714 }
715
716 /**************************************
717 * child objects: bond, orbital, text *
718 **************************************/
719
720 for (dlist = atom->bond_start; dlist != NULL; dlist = dlist->next)
721 static_bond (fp, GAMGI_CAST_BOND dlist->data, atom, lights, error);
722
723 for (dlist = atom->orbital_start; dlist != NULL; dlist = dlist->next)
724 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
725
726 for (dlist = atom->text_start; dlist != NULL; dlist = dlist->next)
727 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
728
729 static_unscale (fp, atom->object.scale, error);
730 }
731
732 static void static_direction (FILE *fp, gamgi_direction *direction,
733 gamgi_bool lights, gamgi_bool *error)
734 {
735 gamgi_dlist * dlist;
736 char string[GAMGI_ENGINE_LINE];
737 double axis[3];
738 double phi;
739 float color[3];
740
741 static_scale (fp, direction->object.scale, direction->center, error);
742
743 if (direction->loops[0] != 0)
744 {
745 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
746 gamgi->gamgi->length, direction->origin[0],
747 gamgi->gamgi->length, direction->origin[1],
748 gamgi->gamgi->length, direction->origin[2]);
749 gamgi_io_file_fprintf (fp, string, error);
750
751 if (direction->model == GAMGI_PHYS_LINE)
752 {
753 /******************************
754 * render direction as a line *
755 ******************************/
756
757 gamgi_math_quaternion_to_axis (direction->quaternion, &phi, axis);
758 sprintf (string, "<Transform rotation=\"%.*f %.*f %.*f %.*f\">\n",
759 gamgi->gamgi->length, axis[0],
760 gamgi->gamgi->length, axis[1],
761 gamgi->gamgi->length, axis[2],
762 gamgi->gamgi->angle, phi);
763 gamgi_io_file_fprintf(fp, string, error);
764
765 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
766
767 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
768 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
769 GAMGI_MATH_DECIMAL_COLOR, direction->red,
770 GAMGI_MATH_DECIMAL_COLOR, direction->green,
771 GAMGI_MATH_DECIMAL_COLOR, direction->blue);
772 gamgi_io_file_fprintf (fp, string, error);
773 sprintf (string, "<LineProperties linewidthScaleFactor=\"%.*f\"/>\n",
774 GAMGI_MATH_DECIMAL_SCALE, GAMGI_IO_X3D_DIRECTION_WIDTH);
775 gamgi_io_file_fprintf (fp, string, error);
776 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
777
778 gamgi_io_x3d_render_lines (fp, direction->loops, direction->points, error);
779
780 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
781 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
782 }
783 else if (direction->model == GAMGI_PHYS_POLE)
784 {
785 /*****************************************************************
786 * stereographic projection: render direction as a chess bitmask *
787 *****************************************************************/
788
789 color[0] = direction->red;
790 color[1] = direction->green;
791 color[2] = direction->blue;
792 gamgi_io_x3d_render_chess (fp, direction->loops[0], direction->points, color, error);
793 }
794 else if (direction->model == GAMGI_PHYS_TRACE)
795 {
796 /*********************************************************
797 * stereographic projection: render direction as an arch *
798 *********************************************************/
799
800 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
801
802 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
803 if (lights)
804 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
805 GAMGI_MATH_DECIMAL_COLOR, direction->red,
806 GAMGI_MATH_DECIMAL_COLOR, direction->green,
807 GAMGI_MATH_DECIMAL_COLOR, direction->blue);
808 else
809 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
810 GAMGI_MATH_DECIMAL_COLOR, direction->red,
811 GAMGI_MATH_DECIMAL_COLOR, direction->green,
812 GAMGI_MATH_DECIMAL_COLOR, direction->blue);
813 gamgi_io_file_fprintf (fp, string, error);
814 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
815
816 gamgi_io_x3d_render_line_strip (fp, direction->loops[0], direction->points, error);
817 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
818 }
819
820 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
821 }
822
823 /**************************************
824 * child objects: atom, orbital, text *
825 **************************************/
826
827 for (dlist = direction->atom_start; dlist != NULL; dlist = dlist->next)
828 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
829
830 for (dlist = direction->orbital_start; dlist != NULL; dlist = dlist->next)
831 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
832
833 for (dlist = direction->text_start; dlist != NULL; dlist = dlist->next)
834 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
835
836 if (direction->loops[0] != 0)
837 static_unscale (fp, direction->object.scale, error);
838 }
839
840 static void static_plane (FILE *fp, gamgi_plane *plane,
841 gamgi_bool lights, gamgi_bool *error)
842 {
843 gamgi_dlist *dlist;
844 char string[GAMGI_ENGINE_LINE];
845 double axis[3];
846 double phi;
847 float color[3];
848
849 static_scale (fp, plane->object.scale, plane->center, error);
850
851 if (plane->loops[0] != 0)
852 {
853 if (plane->model == GAMGI_PHYS_VECTOR)
854 {
855 /*******************************************************
856 * reciprocal lattice: render plane as a cross bitmask *
857 *******************************************************/
858
859 color[0] = plane->red;
860 color[1] = plane->green;
861 color[2] = plane->blue;
862 gamgi_io_x3d_render_cross (fp, plane->loops[0], plane->points, color, error);
863 }
864 else
865 {
866 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
867 gamgi->gamgi->length, plane->origin[0],
868 gamgi->gamgi->length, plane->origin[1],
869 gamgi->gamgi->length, plane->origin[2]);
870 gamgi_io_file_fprintf (fp, string, error);
871
872 if (plane->model == GAMGI_PHYS_POLYGON)
873 {
874 /*****************************
875 * render plane as a polygon *
876 *****************************/
877
878 gamgi_math_quaternion_to_axis (plane->quaternion, &phi, axis);
879 sprintf (string, "<Transform rotation=\"%.*f %.*f %.*f %.*f\">\n",
880 gamgi->gamgi->length, axis[0],
881 gamgi->gamgi->length, axis[1],
882 gamgi->gamgi->length, axis[2],
883 gamgi->gamgi->angle, phi);
884 gamgi_io_file_fprintf (fp, string, error);
885
886 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
887
888 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
889 if (lights == TRUE)
890 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
891 GAMGI_MATH_DECIMAL_COLOR, plane->red,
892 GAMGI_MATH_DECIMAL_COLOR, plane->green,
893 GAMGI_MATH_DECIMAL_COLOR, plane->blue);
894 else
895 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
896 GAMGI_MATH_DECIMAL_COLOR, plane->red,
897 GAMGI_MATH_DECIMAL_COLOR, plane->green,
898 GAMGI_MATH_DECIMAL_COLOR, plane->blue);
899 gamgi_io_file_fprintf (fp, string, error);
900 gamgi_io_file_fprintf(fp, "</Appearance>\n", error);
901
902 gamgi_io_x3d_render_polygons (fp, plane->loops, plane->points, error);
903
904 gamgi_io_file_fprintf(fp, "</Shape>\n", error);
905 gamgi_io_file_fprintf(fp, "</Transform>\n", error);
906 }
907 else if (plane->model == GAMGI_PHYS_POLE)
908 {
909 /*************************************************************
910 * stereographic projection: render plane as a cross bitmask *
911 *************************************************************/
912
913 color[0] = plane->red;
914 color[1] = plane->green;
915 color[2] = plane->blue;
916 gamgi_io_x3d_render_cross (fp, plane->loops[0], plane->points, color, error);
917 }
918 else if (plane->model == GAMGI_PHYS_TRACE)
919 {
920 /*****************************************************
921 * stereographic projection: render plane as an arch *
922 *****************************************************/
923
924 gamgi_io_file_fprintf(fp, "<Shape>\n", error);
925
926 gamgi_io_file_fprintf(fp, "<Appearance>\n", error);
927 if (lights == TRUE)
928 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
929 GAMGI_MATH_DECIMAL_COLOR, plane->red,
930 GAMGI_MATH_DECIMAL_COLOR, plane->green,
931 GAMGI_MATH_DECIMAL_COLOR, plane->blue);
932 else
933 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
934 GAMGI_MATH_DECIMAL_COLOR, plane->red,
935 GAMGI_MATH_DECIMAL_COLOR, plane->green,
936 GAMGI_MATH_DECIMAL_COLOR, plane->blue);
937 gamgi_io_file_fprintf (fp, string, error);
938 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
939
940 gamgi_io_x3d_render_line_strip (fp, plane->loops[0], plane->points, error);
941 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
942 }
943
944 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
945 }
946 }
947
948 /*************************************************
949 * child objects: direction, atom, orbital, text *
950 *************************************************/
951
952 for (dlist = plane->direction_start; dlist != NULL; dlist = dlist->next)
953 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
954
955 for (dlist = plane->atom_start; dlist != NULL; dlist = dlist->next)
956 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
957
958 for (dlist = plane->orbital_start; dlist != NULL; dlist = dlist->next)
959 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
960
961 for (dlist = plane->text_start; dlist != NULL; dlist = dlist->next)
962 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
963
964 if (plane->loops[0] != 0)
965 static_unscale (fp, plane->object.scale, error);
966 }
967
968 static void static_group (FILE *fp, gamgi_group *group,
969 gamgi_bool lights, gamgi_bool *error)
970 {
971 gamgi_dlist * dlist;
972 char string[GAMGI_ENGINE_LINE];
973 double axis[4];
974 double phi;
975 float background[4];
976
977 glGetFloatv (GL_COLOR_CLEAR_VALUE, background);
978
979 static_scale (fp, group->object.scale, group->center, error);
980
981 gamgi_math_quaternion_to_axis (group->quaternion, &phi, axis);
982
983 if (group->loops != NULL)
984 {
985 sprintf (string,
986 "<Transform translation=\"%.*f %.*f %.*f\" rotation=\"%.*f %.*f %.*f %.*f\">\n",
987 gamgi->gamgi->length, group->origin[0],
988 gamgi->gamgi->length, group->origin[1],
989 gamgi->gamgi->length, group->origin[2],
990 gamgi->gamgi->length, axis[0],
991 gamgi->gamgi->length, axis[1],
992 gamgi->gamgi->length, axis[2],
993 gamgi->gamgi->angle, phi);
994 gamgi_io_file_fprintf (fp, string, error);
995
996 gamgi_io_file_fprintf (fp, "<Shape>\n<Appearance>\n", error);
997 sprintf (string, "<LineProperties linewidthScaleFactor=\"%.*f\"/>",
998 GAMGI_MATH_DECIMAL_SCALE, GAMGI_MESA_POLYHEDRON_WIDTH);
999 gamgi_io_file_fprintf (fp, string, error);
1000
1001 if (group->faces == FALSE)
1002 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1003 GAMGI_MATH_DECIMAL_COLOR, group->red,
1004 GAMGI_MATH_DECIMAL_COLOR, group->green,
1005 GAMGI_MATH_DECIMAL_COLOR, group->blue);
1006 else if (lights == TRUE)
1007 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
1008 GAMGI_MATH_DECIMAL_COLOR, background[0],
1009 GAMGI_MATH_DECIMAL_COLOR, background[1],
1010 GAMGI_MATH_DECIMAL_COLOR, background[2]);
1011 else
1012 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1013 GAMGI_MATH_DECIMAL_COLOR, background[0],
1014 GAMGI_MATH_DECIMAL_COLOR, background[1],
1015 GAMGI_MATH_DECIMAL_COLOR, background[2]);
1016 gamgi_io_file_fprintf (fp, string, error);
1017 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
1018
1019 gamgi_io_x3d_render_loops (fp, group->loops, group->points, error);
1020
1021 if (group->faces == TRUE)
1022 {
1023 gamgi_io_file_fprintf (fp, "</Shape>\n<Shape>\n", error);
1024
1025 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
1026 if (lights == TRUE)
1027 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
1028 GAMGI_MATH_DECIMAL_COLOR, group->red,
1029 GAMGI_MATH_DECIMAL_COLOR, group->green,
1030 GAMGI_MATH_DECIMAL_COLOR, group->blue);
1031 else
1032 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1033 GAMGI_MATH_DECIMAL_COLOR, group->red,
1034 GAMGI_MATH_DECIMAL_COLOR, group->green,
1035 GAMGI_MATH_DECIMAL_COLOR, group->blue);
1036 gamgi_io_file_fprintf (fp, string, error);
1037 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
1038
1039 gamgi_io_x3d_render_polygons (fp, group->loops, group->points, error);
1040 }
1041
1042 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
1043 gamgi_io_file_fprintf(fp, "</Transform>\n", error);
1044 }
1045
1046 /**********************************
1047 * child objects: group, plane, *
1048 * direction, atom, orbital, text *
1049 **********************************/
1050
1051 for (dlist = group->group_start; dlist!=NULL; dlist = dlist->next)
1052 static_group (fp, GAMGI_CAST_GROUP dlist->data, lights, error);
1053
1054 for (dlist = group->plane_start; dlist!=NULL; dlist = dlist->next)
1055 static_plane (fp, GAMGI_CAST_PLANE dlist->data, lights, error);
1056
1057 for (dlist = group->direction_start; dlist!=NULL; dlist = dlist->next)
1058 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
1059
1060 for (dlist = group->atom_start; dlist!=NULL; dlist = dlist->next)
1061 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
1062
1063 for (dlist = group->orbital_start; dlist!=NULL; dlist = dlist->next)
1064 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
1065
1066 for (dlist = group->text_start; dlist!=NULL; dlist = dlist->next)
1067 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1068
1069 static_unscale (fp, group->object.scale, error);
1070 }
1071
1072 static void static_molecule (FILE *fp, gamgi_molecule *molecule,
1073 gamgi_bool lights, gamgi_bool *error)
1074 {
1075 gamgi_dlist *dlist;
1076 double center[3];
1077
1078 gamgi_math_vector_zero (center);
1079 static_scale (fp, molecule->object.scale, center, error);
1080
1081 /**********************************
1082 * child objects: group, plane, *
1083 * direction, atom, orbital, text *
1084 **********************************/
1085
1086 for (dlist = molecule->group_start; dlist != NULL; dlist = dlist->next)
1087 static_group (fp, GAMGI_CAST_GROUP dlist->data, lights, error);
1088
1089 for (dlist = molecule->plane_start; dlist != NULL; dlist = dlist->next)
1090 static_plane (fp, GAMGI_CAST_PLANE dlist->data, lights, error);
1091
1092 for (dlist = molecule->direction_start; dlist != NULL; dlist = dlist->next)
1093 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
1094
1095 for (dlist = molecule->atom_start; dlist != NULL; dlist = dlist->next)
1096 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
1097
1098 for (dlist = molecule->orbital_start; dlist != NULL; dlist = dlist->next)
1099 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
1100
1101 for (dlist = molecule->text_start; dlist != NULL; dlist = dlist->next)
1102 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1103
1104 static_unscale (fp, molecule->object.scale, error);
1105 }
1106
1107 static void static_cluster (FILE *fp, gamgi_cluster *cluster,
1108 gamgi_bool lights, gamgi_bool *error)
1109 {
1110 gamgi_dlist * dlist;
1111 char string[GAMGI_ENGINE_LINE];
1112 double axis[4];
1113 double phi;
1114 float background[4];
1115
1116 glGetFloatv (GL_COLOR_CLEAR_VALUE, background);
1117
1118 static_scale (fp, cluster->object.scale, cluster->center, error);
1119
1120 gamgi_math_quaternion_to_axis (cluster->quaternion, &phi, axis);
1121
1122 if (cluster->loops != NULL)
1123 {
1124 sprintf (string,
1125 "<Transform translation=\"%.*f %.*f %.*f\" rotation=\"%.*f %.*f %.*f %.*f\">\n",
1126 gamgi->gamgi->length, cluster->origin[0],
1127 gamgi->gamgi->length, cluster->origin[1],
1128 gamgi->gamgi->length, cluster->origin[2],
1129 gamgi->gamgi->length, axis[0],
1130 gamgi->gamgi->length, axis[1],
1131 gamgi->gamgi->length, axis[2],
1132 gamgi->gamgi->angle, phi);
1133 gamgi_io_file_fprintf (fp, string, error);
1134
1135 gamgi_io_file_fprintf (fp, "<Shape>\n<Appearance>\n", error);
1136 sprintf (string, "<LineProperties linewidthScaleFactor=\"%.*f\"/>",
1137 GAMGI_MATH_DECIMAL_SCALE, GAMGI_MESA_POLYHEDRON_WIDTH);
1138 gamgi_io_file_fprintf (fp, string, error);
1139
1140 if (cluster->faces == FALSE)
1141 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1142 GAMGI_MATH_DECIMAL_COLOR, cluster->colors[0],
1143 GAMGI_MATH_DECIMAL_COLOR, cluster->colors[1],
1144 GAMGI_MATH_DECIMAL_COLOR, cluster->colors[2]);
1145 else if (lights == TRUE)
1146 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
1147 GAMGI_MATH_DECIMAL_COLOR, background[0],
1148 GAMGI_MATH_DECIMAL_COLOR, background[1],
1149 GAMGI_MATH_DECIMAL_COLOR, background[2]);
1150 else
1151 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1152 GAMGI_MATH_DECIMAL_COLOR, background[0],
1153 GAMGI_MATH_DECIMAL_COLOR, background[1],
1154 GAMGI_MATH_DECIMAL_COLOR, background[2]);
1155 gamgi_io_file_fprintf (fp, string, error);
1156 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
1157
1158 gamgi_io_x3d_render_loops (fp, cluster->loops, cluster->points, error);
1159
1160 if (cluster->faces == TRUE)
1161 {
1162 gamgi_io_file_fprintf (fp, "</Shape>\n<Shape>\n", error);
1163 gamgi_io_x3d_render_polygons_color (fp, cluster->loops,
1164 cluster->points, cluster->paints, cluster->colors, error);
1165 }
1166
1167 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
1168
1169 if (cluster->atoms > 0)
1170 gamgi_io_x3d_render_points (fp, cluster->atoms,
1171 cluster->points, cluster->colors, error);
1172
1173 gamgi_io_file_fprintf(fp, "</Transform>\n", error);
1174 }
1175
1176 /********************************************
1177 * child objects: cluster, molecule, group, *
1178 * plane, direction, atom, orbital, text *
1179 ********************************************/
1180
1181 for (dlist = cluster->cluster_start; dlist!=NULL; dlist = dlist->next)
1182 static_cluster (fp, GAMGI_CAST_CLUSTER dlist->data, lights, error);
1183
1184 for (dlist = cluster->molecule_start; dlist!=NULL; dlist = dlist->next)
1185 static_molecule (fp, GAMGI_CAST_MOLECULE dlist->data, lights, error);
1186
1187 for (dlist = cluster->group_start; dlist!=NULL; dlist = dlist->next)
1188 static_group (fp, GAMGI_CAST_GROUP dlist->data, lights, error);
1189
1190 for (dlist = cluster->plane_start; dlist!=NULL; dlist = dlist->next)
1191 static_plane (fp, GAMGI_CAST_PLANE dlist->data, lights, error);
1192
1193 for (dlist = cluster->direction_start; dlist!=NULL; dlist = dlist->next)
1194 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
1195
1196 for (dlist = cluster->atom_start; dlist!=NULL; dlist = dlist->next)
1197 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
1198
1199 for (dlist = cluster->orbital_start; dlist!=NULL; dlist = dlist->next)
1200 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
1201
1202 for (dlist = cluster->text_start; dlist!=NULL; dlist = dlist->next)
1203 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1204
1205 static_unscale (fp, cluster->object.scale, error);
1206 }
1207
1208 static void static_cell (FILE *fp, gamgi_cell *cell,
1209 gamgi_bool lights, gamgi_bool *error)
1210 {
1211 gamgi_dlist * dlist;
1212 char string[GAMGI_ENGINE_LINE];
1213 double axis[3];
1214 double phi;
1215 float background[4];
1216 float color[3];
1217
1218 /****************************
1219 * scale, translate, rotate *
1220 ****************************/
1221
1222 static_scale (fp, cell->object.scale, cell->center, error);
1223
1224 sprintf (string, "<Transform translation=\"%.*f %.*f %.*f\">\n",
1225 gamgi->gamgi->length, cell->origin[0],
1226 gamgi->gamgi->length, cell->origin[1],
1227 gamgi->gamgi->length, cell->origin[2]);
1228 gamgi_io_file_fprintf (fp, string, error);
1229
1230 if (cell->model != GAMGI_PHYS_PROJECTION)
1231 {
1232 gamgi_math_quaternion_to_axis (cell->quaternion, &phi, axis);
1233 sprintf (string, "<Transform rotation=\"%.*f %.*f %.*f %.*f\">\n",
1234 gamgi->gamgi->length, axis[0],
1235 gamgi->gamgi->length, axis[1],
1236 gamgi->gamgi->length, axis[2],
1237 gamgi->gamgi->angle, phi);
1238 gamgi_io_file_fprintf (fp, string, error);
1239 }
1240
1241 glGetFloatv (GL_COLOR_CLEAR_VALUE, background);
1242
1243 /*********
1244 * Shape *
1245 *********/
1246
1247 if (cell->loops != NULL && cell->borders != FALSE &&
1248 (cell->lattice != GAMGI_PHYS_HEXAGONAL_P ||
1249 (cell->model != GAMGI_PHYS_WIGNER && cell->model != GAMGI_PHYS_CONVENTIONAL)) &&
1250 (cell->lattice != GAMGI_PHYS_ORTHORHOMBIC_C || cell->model != GAMGI_PHYS_WIGNER))
1251 {
1252 gamgi_io_file_fprintf (fp, "<Shape>\n<Appearance>\n", error);
1253
1254 if (cell->faces == TRUE)
1255 {
1256 color[0] = background[0];
1257 color[1] = background[1];
1258 color[2] = background[2];
1259 }
1260 else
1261 {
1262 color[0] = cell->red;
1263 color[1] = cell->green;
1264 color[2] = cell->blue;
1265 }
1266
1267 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1268 GAMGI_MATH_DECIMAL_COLOR, color[0],
1269 GAMGI_MATH_DECIMAL_COLOR, color[1],
1270 GAMGI_MATH_DECIMAL_COLOR, color[2]);
1271 gamgi_io_file_fprintf (fp, string, error);
1272
1273 sprintf (string, "<LineProperties linewidthScaleFactor=\"%.*f\"/>\n",
1274 GAMGI_MATH_DECIMAL_SCALE, GAMGI_MESA_CELL_LINE);
1275 gamgi_io_file_fprintf (fp, string, error);
1276 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
1277
1278 gamgi_io_x3d_render_loops (fp, cell->loops, cell->points, error);
1279 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
1280 }
1281
1282 if (cell->lines != NULL)
1283 {
1284 gamgi_io_file_fprintf (fp, "<Shape>\n<Appearance>\n", error);
1285
1286 if (cell->faces == TRUE)
1287 {
1288 color[0] = background[0];
1289 color[1] = background[1];
1290 color[2] = background[2];
1291 }
1292 else
1293 {
1294 color[0] = cell->red;
1295 color[1] = cell->green;
1296 color[2] = cell->blue;
1297 }
1298
1299 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1300 GAMGI_MATH_DECIMAL_COLOR, color[0],
1301 GAMGI_MATH_DECIMAL_COLOR, color[1],
1302 GAMGI_MATH_DECIMAL_COLOR, color[2]);
1303 gamgi_io_file_fprintf (fp, string, error);
1304
1305 sprintf (string, "<LineProperties linewidthScaleFactor=\"%.*f\"/>\n",
1306 GAMGI_MATH_DECIMAL_SCALE, GAMGI_MESA_CELL_LINE);
1307 gamgi_io_file_fprintf (fp, string, error);
1308 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
1309
1310 gamgi_io_x3d_render_lines (fp, cell->lines, cell->points, error);
1311 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
1312 }
1313
1314 if (cell->faces == TRUE)
1315 {
1316 gamgi_io_file_fprintf (fp, "<Shape>\n<Appearance>\n", error);
1317
1318 if (lights == TRUE)
1319 sprintf (string, "<Material diffuseColor=\"%.*f %.*f %.*f\"/>\n",
1320 GAMGI_MATH_DECIMAL_COLOR, cell->red,
1321 GAMGI_MATH_DECIMAL_COLOR, cell->green,
1322 GAMGI_MATH_DECIMAL_COLOR, cell->blue);
1323 else
1324 sprintf (string, "<Material emissiveColor=\"%.*f %.*f %.*f\"/>\n",
1325 GAMGI_MATH_DECIMAL_COLOR, cell->red,
1326 GAMGI_MATH_DECIMAL_COLOR, cell->green,
1327 GAMGI_MATH_DECIMAL_COLOR, cell->blue);
1328 gamgi_io_file_fprintf (fp, string, error);
1329 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
1330
1331 gamgi_io_x3d_render_polygons (fp, cell->loops, cell->points, error);
1332 gamgi_io_file_fprintf(fp, "</Shape>\n", error);
1333 }
1334
1335 if (cell->nodes == TRUE)
1336 gamgi_io_x3d_render_points (fp, cell->n_nodes, cell->points, color,error);
1337
1338 if (cell->model != GAMGI_PHYS_PROJECTION)
1339 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
1340
1341 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
1342
1343 /********************************************
1344 * child objects: cluster, molecule, group, *
1345 * plane, direction, atom, orbital, text *
1346 ********************************************/
1347
1348 for (dlist = cell->cluster_start; dlist != NULL; dlist = dlist->next)
1349 static_cluster (fp, GAMGI_CAST_CLUSTER dlist->data, lights, error);
1350
1351 for (dlist = cell->molecule_start; dlist != NULL; dlist = dlist->next)
1352 static_molecule (fp, GAMGI_CAST_MOLECULE dlist->data, lights, error);
1353
1354 for (dlist = cell->group_start; dlist != NULL; dlist = dlist->next)
1355 static_group (fp, GAMGI_CAST_GROUP dlist->data, lights, error);
1356
1357 for (dlist = cell->plane_start; dlist != NULL; dlist = dlist->next)
1358 static_plane (fp, GAMGI_CAST_PLANE dlist->data, lights, error);
1359
1360 for (dlist = cell->direction_start; dlist != NULL; dlist = dlist->next)
1361 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
1362
1363 for (dlist = cell->atom_start; dlist != NULL; dlist = dlist->next)
1364 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
1365
1366 for (dlist = cell->orbital_start; dlist != NULL; dlist = dlist->next)
1367 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
1368
1369 for (dlist = cell->text_start; dlist != NULL; dlist = dlist->next)
1370 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1371
1372 static_unscale (fp, cell->object.scale, error);
1373 }
1374
1375 static void static_arrow (FILE *fp, gamgi_arrow *arrow,
1376 gamgi_bool lights, gamgi_bool *error)
1377 {
1378 gamgi_dlist * dlist;
1379
1380 /***********************
1381 * child objects: text *
1382 ***********************/
1383
1384 for (dlist = arrow->text_start; dlist != NULL; dlist = dlist->next)
1385 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1386 }
1387
1388 static void static_shape (FILE * fp, gamgi_shape *shape,
1389 gamgi_bool lights, gamgi_bool *error)
1390 {
1391 gamgi_dlist * dlist;
1392
1393 /***********************
1394 * child objects: text *
1395 ***********************/
1396
1397 for (dlist = shape->text_start; dlist != NULL; dlist = dlist->next)
1398 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1399 }
1400
1401 static void static_graph (FILE *fp, gamgi_graph *graph,
1402 gamgi_bool lights, gamgi_bool *error)
1403 {
1404 gamgi_dlist * dlist;
1405
1406 /***********************
1407 * child objects: text *
1408 ***********************/
1409
1410 for (dlist = graph->text_start; dlist != NULL; dlist = dlist->next)
1411 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1412 }
1413
1414 static void static_assembly (FILE *fp, gamgi_assembly *assembly,
1415 gamgi_bool lights, gamgi_bool *error)
1416 {
1417 gamgi_dlist * dlist;
1418 double center[3];
1419
1420 gamgi_math_vector_zero (center);
1421 static_scale (fp, assembly->object.scale, center, error);
1422
1423 /******************************************
1424 * child objects: assembly, graph, arrow, *
1425 * shape, cell, cluster, molecule, group, *
1426 * plane, direction, atom, orbital, text *
1427 ******************************************/
1428
1429 for (dlist = assembly->assembly_start; dlist != NULL; dlist = dlist->next)
1430 static_assembly (fp, GAMGI_CAST_ASSEMBLY dlist->data, lights, error);
1431
1432 for (dlist = assembly->graph_start; dlist != NULL; dlist = dlist->next)
1433 static_graph (fp, GAMGI_CAST_GRAPH dlist->data, lights, error);
1434
1435 for (dlist = assembly->arrow_start; dlist != NULL; dlist = dlist->next)
1436 static_arrow (fp, GAMGI_CAST_ARROW dlist->data, lights, error);
1437
1438 for (dlist = assembly->shape_start; dlist != NULL; dlist = dlist->next)
1439 static_shape (fp, GAMGI_CAST_SHAPE dlist->data, lights, error);
1440
1441 for (dlist = assembly->cell_start; dlist != NULL; dlist = dlist->next)
1442 static_cell (fp, GAMGI_CAST_CELL dlist->data, lights, error);
1443
1444 for (dlist = assembly->cluster_start; dlist != NULL; dlist = dlist->next)
1445 static_cluster (fp, GAMGI_CAST_CLUSTER dlist->data, lights, error);
1446
1447 for (dlist = assembly->molecule_start; dlist != NULL; dlist = dlist->next)
1448 static_molecule (fp, GAMGI_CAST_MOLECULE dlist->data, lights, error);
1449
1450 for (dlist = assembly->group_start; dlist != NULL; dlist = dlist->next)
1451 static_group (fp, GAMGI_CAST_GROUP dlist->data, lights, error);
1452
1453 for (dlist = assembly->plane_start; dlist != NULL; dlist = dlist->next)
1454 static_plane (fp, GAMGI_CAST_PLANE dlist->data, lights, error);
1455
1456 for (dlist = assembly->direction_start; dlist != NULL; dlist = dlist->next)
1457 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
1458
1459 for (dlist = assembly->atom_start; dlist != NULL; dlist = dlist->next)
1460 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
1461
1462 for (dlist = assembly->orbital_start; dlist != NULL; dlist = dlist->next)
1463 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
1464
1465 for (dlist = assembly->text_start; dlist != NULL; dlist = dlist->next)
1466 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1467
1468 static_unscale (fp, assembly->object.scale, error);
1469 }
1470
1471 static void static_light (FILE *fp, gamgi_light *light, gamgi_bool *error)
1472 {
1473 char string[GAMGI_ENGINE_LINE];
1474 double direction[3], position[3];
1475 float color[3];
1476 float ambient;
1477
1478 direction[0] = light->direction[0];
1479 direction[1] = light->direction[1];
1480 direction[2] = light->direction[2];
1481
1482 position[0] = light->position[0];
1483 position[1] = light->position[1];
1484 position[2] = light->position[2];
1485
1486 /***********************************************************************
1487 * set ambient as the average of the three ambient components *
1488 * *
1489 * set color as the sum (limited to 1.0) of diffuse and specular color *
1490 ***********************************************************************/
1491
1492 ambient = (light->ambient[0] + light->ambient[1] + light->ambient[2]) / 3;
1493
1494 color[0] = light->diffuse[0] + light->specular[0];
1495 if (color[0] > 1.0) color[0] = 1.0;
1496 color[1] = light->diffuse[1] + light->specular[1];
1497 if (color[1] > 1.0) color[1] = 1.0;
1498 color[2] = light->diffuse[2] + light->specular[2];
1499 if (color[2] > 1.0) color[2] = 1.0;
1500
1501 if (light->position[3] == 0.0)
1502 {
1503 /*********************
1504 * directional light *
1505 *********************/
1506
1507 sprintf (string, "<DirectionalLight ambientIntensity=\"%.*f\""
1508 " color=\"%.*f %.*f %.*f\" direction=\"%.*f %.*f %.*f\"/>\n",
1509 GAMGI_MATH_DECIMAL_COLOR, ambient,
1510 GAMGI_MATH_DECIMAL_COLOR, color[0],
1511 GAMGI_MATH_DECIMAL_COLOR, color[1],
1512 GAMGI_MATH_DECIMAL_COLOR, color[2],
1513 gamgi->gamgi->length, direction[0],
1514 gamgi->gamgi->length, direction[1],
1515 gamgi->gamgi->length, direction[2]);
1516 }
1517 else if (light->angle == 180.0)
1518 {
1519 /********************
1520 * positional light *
1521 ********************/
1522
1523 sprintf (string, "<PointLight ambientIntensity=\"%.*f\""
1524 " color=\"%.*f %.*f %.*f\" location=\"%.*f %.*f %.*f\"/>\n",
1525 GAMGI_MATH_DECIMAL_COLOR, ambient,
1526 GAMGI_MATH_DECIMAL_COLOR, color[0],
1527 GAMGI_MATH_DECIMAL_COLOR, color[1],
1528 GAMGI_MATH_DECIMAL_COLOR, color[2],
1529 gamgi->gamgi->length, position[0],
1530 gamgi->gamgi->length, position[1],
1531 gamgi->gamgi->length, position[2]);
1532 }
1533 else
1534 {
1535 /**************
1536 * spot light *
1537 **************/
1538
1539 sprintf (string, "<SpotLight ambientIntensity=\"%.*f\""
1540 " color=\"%.*f %.*f %.*f\" cutOffAngle=\"%.*f\""
1541 " direction=\"%.*f %.*f %.*f\" location=\"%.*f %.*f %.*f\"/>\n",
1542 GAMGI_MATH_DECIMAL_COLOR, ambient,
1543 GAMGI_MATH_DECIMAL_COLOR, color[0],
1544 GAMGI_MATH_DECIMAL_COLOR, color[1],
1545 GAMGI_MATH_DECIMAL_COLOR, color[2],
1546 gamgi->gamgi->angle, light->angle * GAMGI_MATH_DEG_RAD,
1547 gamgi->gamgi->length, direction[0],
1548 gamgi->gamgi->length, direction[1],
1549 gamgi->gamgi->length, direction[2],
1550 gamgi->gamgi->length, position[0],
1551 gamgi->gamgi->length, position[1],
1552 gamgi->gamgi->length, position[2]);
1553 }
1554
1555 gamgi_io_file_fprintf (fp, string, error);
1556 }
1557
1558 static void static_layer (FILE *fp, gamgi_layer *layer, gamgi_bool *error)
1559 {
1560 gamgi_dlist *dlist;
1561 char string[GAMGI_ENGINE_LINE];
1562 double normal[3];
1563 double scale;
1564 float color[4];
1565 gamgi_bool lights;
1566
1567 /********************************************************
1568 * The exported scene describes only the current layer! *
1569 ********************************************************/
1570
1571 gamgi_io_file_fprintf (fp, "<Scene>\n", error);
1572
1573 /***************************************************************
1574 * Apparently, the GAMGI OpenGL lightning seems to be slightly *
1575 * better simulated in X3D when headLight is set to false. *
1576 * *
1577 * Possible values are: WALK, FLY, EXAMINE, LOOKAT, ANY, NONE *
1578 * values can be combined, for example: type='"EXAMINE" "ANY"' *
1579 * *
1580 * Apparently, the GAMGI OpenGL lightning seems to be slightly *
1581 * better simulated in X3D when global is set to false, which *
1582 * means that lights apply only to the local node. *
1583 ***************************************************************/
1584
1585 gamgi_io_file_fprintf (fp, "<NavigationInfo headlight=\"false\"", error);
1586 gamgi_io_file_fprintf (fp, " type='\"ANY\"'/>\n", error);
1587
1588 gamgi_io_file_fprintf (fp, "<DirectionalLight global=\"false\"/>\n", error);
1589
1590 /**************
1591 * projection *
1592 **************/
1593
1594 if (layer->perspective == TRUE)
1595 {
1596 gamgi_io_file_fprintf (fp, "<Viewpoint description=\"perspective\"", error);
1597 sprintf (string, " fieldOfView=\"%.*f\"\n",
1598 gamgi->gamgi->length, 2.0 * atan ((2.0 * layer->top) * 0.5 / layer->near));
1599 }
1600 else
1601 {
1602 gamgi_io_file_fprintf (fp, "<OrthoViewpoint description=\"orthographic\"", error);
1603 sprintf (string, " fieldOfView=\"%.*f %.*f %.*f %.*f\"",
1604 gamgi->gamgi->length, -layer->top,
1605 gamgi->gamgi->length, -layer->top,
1606 gamgi->gamgi->length, layer->top,
1607 gamgi->gamgi->length, layer->top);
1608 }
1609 gamgi_io_file_fprintf (fp, string, error);
1610
1611 /*************
1612 * modelview *
1613 *************/
1614
1615 gamgi_math_vector_sub (layer->eye, layer->center, normal);
1616 gamgi_math_vector_normal (normal);
1617 sprintf (string, "orientation=\"%.*f %.*f %.*f %.*f\"",
1618 gamgi->gamgi->length, normal[0],
1619 gamgi->gamgi->length, normal[1],
1620 gamgi->gamgi->length, normal[2],
1621 gamgi->gamgi->length, 0.0);
1622 gamgi_io_file_fprintf (fp, string, error);
1623
1624 sprintf (string, " position=\"%.*f %.*f %.*f\"/>\n",
1625 gamgi->gamgi->length, layer->eye[0],
1626 gamgi->gamgi->length, layer->eye[1],
1627 gamgi->gamgi->length, layer->eye[2]);
1628 gamgi_io_file_fprintf (fp, string, error);
1629
1630 glGetFloatv (GL_COLOR_CLEAR_VALUE, color);
1631 sprintf (string, "<Background skyColor=\"%.*f %.*f %.*f\"/>\n",
1632 GAMGI_MATH_DECIMAL_COLOR, color[0],
1633 GAMGI_MATH_DECIMAL_COLOR, color[1],
1634 GAMGI_MATH_DECIMAL_COLOR, color[2]);
1635 gamgi_io_file_fprintf (fp, string, error);
1636
1637 scale = layer->object.scale;
1638 if (fabs (scale - 1.0) > GAMGI_MATH_TOLERANCE)
1639 {
1640 sprintf (string, "<Transform scale=\"%.*f %.*f %.*f\">\n",
1641 GAMGI_MATH_DECIMAL_SCALE, scale,
1642 GAMGI_MATH_DECIMAL_SCALE, scale,
1643 GAMGI_MATH_DECIMAL_SCALE, scale);
1644 gamgi_io_file_fprintf (fp, string, error);
1645 }
1646
1647 if (layer->light_start == NULL) lights = FALSE;
1648 else lights = TRUE;
1649
1650 /*************************************************
1651 * child objects: light, assembly, graph, shape, *
1652 * arrow, cell, cluster, molecule, group, plane, *
1653 * direction, atom, orbital, text *
1654 *************************************************/
1655
1656 for (dlist = layer->light_start; dlist != NULL; dlist = dlist->next)
1657 static_light (fp, GAMGI_CAST_LIGHT dlist->data, error);
1658
1659 for (dlist = layer->assembly_start; dlist != NULL; dlist = dlist->next)
1660 static_assembly (fp, GAMGI_CAST_ASSEMBLY dlist->data, lights, error);
1661
1662 for (dlist = layer->graph_start; dlist != NULL; dlist = dlist->next)
1663 static_graph (fp, GAMGI_CAST_GRAPH dlist->data, lights, error);
1664
1665 for (dlist = layer->shape_start; dlist != NULL; dlist = dlist->next)
1666 static_shape (fp, GAMGI_CAST_SHAPE dlist->data, lights, error);
1667
1668 for (dlist = layer->arrow_start; dlist != NULL; dlist = dlist->next)
1669 static_arrow (fp, GAMGI_CAST_ARROW dlist->data, lights, error);
1670
1671 for (dlist = layer->cell_start; dlist != NULL; dlist = dlist->next)
1672 static_cell(fp, GAMGI_CAST_CELL dlist->data, lights, error);
1673
1674 for (dlist = layer->cluster_start; dlist != NULL; dlist = dlist->next)
1675 static_cluster(fp, GAMGI_CAST_CLUSTER dlist->data, lights, error);
1676
1677 for (dlist = layer->molecule_start; dlist != NULL; dlist = dlist->next)
1678 static_molecule(fp, GAMGI_CAST_MOLECULE dlist->data, lights, error);
1679
1680 for (dlist = layer->group_start; dlist != NULL; dlist = dlist->next)
1681 static_group (fp, GAMGI_CAST_GROUP dlist->data, lights, error);
1682
1683 for (dlist = layer->plane_start; dlist != NULL; dlist = dlist->next)
1684 static_plane (fp, GAMGI_CAST_PLANE dlist->data, lights, error);
1685
1686 for (dlist = layer->direction_start; dlist != NULL; dlist = dlist->next)
1687 static_direction (fp, GAMGI_CAST_DIRECTION dlist->data, lights, error);
1688
1689 for (dlist = layer->atom_start; dlist != NULL; dlist = dlist->next)
1690 static_atom (fp, GAMGI_CAST_ATOM dlist->data, lights, error);
1691
1692 for (dlist = layer->orbital_start; dlist != NULL; dlist = dlist->next)
1693 static_orbital (fp, GAMGI_CAST_ORBITAL dlist->data, lights, error);
1694
1695 for (dlist = layer->text_start; dlist != NULL; dlist = dlist->next)
1696 static_text (fp, GAMGI_CAST_TEXT dlist->data, lights, error);
1697
1698 if (fabs (scale - 1.0) > GAMGI_MATH_TOLERANCE)
1699 gamgi_io_file_fprintf (fp, "</Transform>\n", error);
1700
1701 gamgi_io_file_fprintf (fp, "</Scene>", error);
1702 }
1703
1704 /************ external function **********
1705 * *
1706 * GAMGI_IO_X3D *
1707 * *
1708 * Main x3d writing function call *
1709 *****************************************/
1710
1711 gamgi_bool gamgi_io_x3d (FILE *fp, gamgi_window *window, gamgi_bool *error)
1712 {
1713 /*********************************
1714 * export only the current layer *
1715 *********************************/
1716
1717 static_layer (fp, window->layer, error);
1718
1719 return TRUE;
1720 }