"Fossies" - the Fresh Open Source Software Archive 
Member "gamgi0.17.5x/src/io/gamgi_io_x3d_render.c" (23 Feb 2022, 34705 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_render.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_math_vector.h"
23 #include "gamgi_io_file.h"
24 #include "gamgi_io_font_sun.h"
25 #include "gamgi_io_font_hershey.h"
26 #include "gamgi_io_x3d_render.h"
27 #include "gamgi_mesa_atom.h"
28 #include "gamgi_mesa_bond.h"
29 #include "gamgi_mesa_text.h"
30
31 #define GAMGI_IO_X3D_TOTAL 500
32 #define GAMGI_IO_X3D_STEP 2
33 #define GAMGI_IO_X3D_POINT_SIZE 0.025
34
35 /*
36 * OGLFT: A library for drawing text with OpenGL using the FreeType library
37 * Copyright (C) 2002 lignum Computing, Inc.
38 * Author: Allen Barnett
39 *
40 * This program is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License as published by
42 * the Free Software Foundation; either version 2 of the License, or
43 * (at your option) any later version.
44 *
45 * This program is distributed in the hope that it will be useful,
46 * but WITHOUT ANY WARRANTY; without even the implied warranty of
47 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 * GNU General Public License for more details.
49 *
50 * You should have received a copy of the GNU General Public License
51 * along with this program; if not, write to the Free Software
52 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
53 */
54
55 /*********************************
56 * Code taken from: OGLFT-0.9 *
57 * *
58 * Functions with OGLFT code: *
59 * static_glu_begin *
60 * static_glu_vertex *
61 * static_glu_combine *
62 * static_vertical_move *
63 * static_vertical_line *
64 * static_vertical_conic *
65 * static_vertical_cubic *
66 * x3d_font_face *
67 * static_extruded_create *
68 * static_extruded_remove *
69 * gamgi_io_x3d_render_solid *
70 * *
71 * Code taken by: Carlos Pereira *
72 *********************************/
73
74 /*
75 * GLE: The Tubing and Extrusion Library
76 * Copyright (C) 1991,1994,2003 Linas Vepstas
77 *
78 * The GLE library is distributed under two licenses:
79 * GNU General Public License (GPL) and Public Domain
80 *
81 * This program is free software; you can redistribute it and/or modify
82 * it under the terms of the GNU General Public License as published by
83 * the Free Software Foundation; either version 2 of the License, or
84 * (at your option) any later version.
85 *
86 * This program is distributed in the hope that it will be useful,
87 * but WITHOUT ANY WARRANTY; without even the implied warranty of
88 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
89 * GNU General Public License for more details.
90 *
91 * You should have received a copy of the GNU General Public License
92 * along with this program; if not, write to the Free Software
93 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
94 */
95
96 /***********************************************
97 * Code taken from: GLE-3.1.0 *
98 * *
99 * Functions with GLE code: x3d_font_extrusion *
100 * *
101 * Code taken by: Carlos Pereira *
102 ***********************************************/
103
104 /************* internal function ***********
105 * *
106 * STATIC_POINT *
107 * *
108 * render a X3D point *
109 *******************************************/
110
111 static void static_point (FILE *fp, int n_points, double *points,
112 float *color, int type, int width, int pattern, gamgi_bool *error)
113 {
114 char string[GAMGI_ENGINE_LINE];
115 float p[3];
116 int i;
117
118 if (n_points <= 0) return;
119
120 /***************
121 * Shape start *
122 ***************/
123
124 gamgi_io_file_fprintf (fp, "<Shape>\n", error);
125
126 /********************
127 * Appearance start *
128 ********************/
129
130 if (color != NULL || width == TRUE || pattern == TRUE)
131 {
132 gamgi_io_file_fprintf (fp, "<Appearance>\n", error);
133
134 /************************
135 * LineProperties start *
136 ************************/
137
138 if (width == TRUE || pattern == TRUE)
139 gamgi_io_file_fprintf (fp, "<LineProperties ", error);
140
141 if (width == TRUE)
142 {
143 sprintf (string, "linewidthScaleFactor=\"%d\" ", width);
144 gamgi_io_file_fprintf (fp, string, error);
145 }
146
147 if (pattern == TRUE)
148 {
149 sprintf (string, "linetype=\"%d\" ", pattern);
150 gamgi_io_file_fprintf (fp, string, error);
151 }
152
153 /**********************
154 * LineProperties end *
155 **********************/
156
157 if (width == TRUE || pattern == TRUE)
158 gamgi_io_file_fprintf (fp, "/>\n", error);
159
160 if (color != NULL)
161 {
162 sprintf (string, "<Material emissiveColor=\"%f %f %f\"/>\n",
163 color[0], color[1], color[2]);
164 gamgi_io_file_fprintf (fp, string, error);
165 }
166
167 gamgi_io_file_fprintf (fp, "</Appearance>\n", error);
168 }
169
170 /******************
171 * Appearance end *
172 ******************/
173
174 /************************
175 * IndexedlineSet start *
176 ************************/
177
178 gamgi_io_file_fprintf (fp, "<IndexedLineSet coordIndex=\"\n", error);
179
180 for (i = 0; i < n_points; i++)
181 {
182 if (type == 1)
183 sprintf (string, "%d %d -1 %d %d -1 %d %d -1 %d %d -1\n",
184 i*8 + 0, i*8 + 1, i*8 + 2, i*8 + 3, i*8 + 4, i*8 + 5, i*8 + 6, i*8 + 7);
185 else
186 sprintf (string, "%d %d -1 %d %d -1 %d %d -1\n",
187 i*6 + 0, i*6 + 1, i*6 + 2, i*6 + 3, i*6 + 4, i*6 + 5);
188
189 gamgi_io_file_fprintf (fp, string, error);
190 }
191
192 gamgi_io_file_fprintf (fp, "\">\n", error);
193
194 /********************
195 * Coordinate start *
196 ********************/
197
198 gamgi_io_file_fprintf (fp, "<Coordinate point=\"\n", error);
199
200 for (i = 0; i < n_points; i++)
201 {
202 p[0] = points[3*i + 0];
203 p[1] = points[3*i + 1];
204 p[2] = points[3*i + 2];
205
206 if (type == 1)
207 {
208 sprintf (string, "%f %f %f %f %f %f\n",
209 p[0] - GAMGI_IO_X3D_POINT_SIZE, p[1] + GAMGI_IO_X3D_POINT_SIZE,
210 p[2] - GAMGI_IO_X3D_POINT_SIZE, p[0] + GAMGI_IO_X3D_POINT_SIZE,
211 p[1] - GAMGI_IO_X3D_POINT_SIZE, p[2] + GAMGI_IO_X3D_POINT_SIZE);
212 gamgi_io_file_fprintf (fp, string, error);
213
214 sprintf (string, "%f %f %f %f %f %f\n",
215 p[0] + GAMGI_IO_X3D_POINT_SIZE, p[1] + GAMGI_IO_X3D_POINT_SIZE,
216 p[2] - GAMGI_IO_X3D_POINT_SIZE, p[0] - GAMGI_IO_X3D_POINT_SIZE,
217 p[1] - GAMGI_IO_X3D_POINT_SIZE, p[2] + GAMGI_IO_X3D_POINT_SIZE);
218 gamgi_io_file_fprintf (fp, string, error);
219
220 sprintf (string, "%f %f %f %f %f %f\n",
221 p[0] - GAMGI_IO_X3D_POINT_SIZE, p[1] + GAMGI_IO_X3D_POINT_SIZE,
222 p[2] + GAMGI_IO_X3D_POINT_SIZE, p[0] + GAMGI_IO_X3D_POINT_SIZE,
223 p[1] - GAMGI_IO_X3D_POINT_SIZE, p[2] - GAMGI_IO_X3D_POINT_SIZE);
224 gamgi_io_file_fprintf (fp, string, error);
225
226 sprintf (string, "%f %f %f %f %f %f\n",
227 p[0] + GAMGI_IO_X3D_POINT_SIZE, p[1] + GAMGI_IO_X3D_POINT_SIZE,
228 p[2] + GAMGI_IO_X3D_POINT_SIZE, p[0] - GAMGI_IO_X3D_POINT_SIZE,
229 p[1] - GAMGI_IO_X3D_POINT_SIZE, p[2] - GAMGI_IO_X3D_POINT_SIZE);
230 gamgi_io_file_fprintf (fp, string, error);
231 }
232 else
233 {
234 sprintf (string, "%f %f %f %f %f %f\n",
235 p[0] + GAMGI_IO_X3D_POINT_SIZE, p[1], p[2],
236 p[0] - GAMGI_IO_X3D_POINT_SIZE, p[1], p[2]);
237 gamgi_io_file_fprintf (fp, string, error);
238
239 sprintf (string, "%f %f %f %f %f %f\n",
240 p[0], p[1] + GAMGI_IO_X3D_POINT_SIZE, p[2],
241 p[0], p[1] - GAMGI_IO_X3D_POINT_SIZE, p[2]);
242 gamgi_io_file_fprintf (fp, string, error);
243
244 sprintf (string, "%f %f %f %f %f %f\n",
245 p[0], p[1], p[2] + GAMGI_IO_X3D_POINT_SIZE,
246 p[0], p[1], p[2] - GAMGI_IO_X3D_POINT_SIZE);
247 gamgi_io_file_fprintf (fp, string, error);
248 }
249 }
250
251 /***************************************
252 * Coordinate+IndexedLineSet+Shape end *
253 ***************************************/
254
255 gamgi_io_file_fprintf (fp, "\"/>\n", error);
256 gamgi_io_file_fprintf (fp, "</IndexedLineSet>\n", error);
257 gamgi_io_file_fprintf (fp, "</Shape>\n", error);
258 }
259
260 /************* external function ***********
261 * *
262 * GAMGI_IO_X3D_RENDER_CROSS *
263 * *
264 * draws points of the type "cross" *
265 *******************************************/
266
267 void gamgi_io_x3d_render_cross (FILE *fp, int n_points,
268 double *points, float *color, gamgi_bool *error)
269 {
270 static_point (fp, n_points, points, color, 0, 4, 0, error);
271 }
272
273
274 /************* external function ***********
275 * *
276 * GAMGI_IO_X3D_RENDER_CHESS *
277 * *
278 * draws points of the type "chess" *
279 *******************************************/
280
281 void gamgi_io_x3d_render_chess (FILE *fp, int n_points,
282 double *points, float *color, gamgi_bool *error)
283 {
284 static_point (fp, n_points, points, color, 1, 4, 0, error);
285 }
286
287 /************* external function ***********
288 * *
289 * GAMGI_IO_X3D_RENDER_POINTS *
290 * *
291 * draws points of the type "normal" *
292 *******************************************/
293
294 void gamgi_io_x3d_render_points (FILE *fp, int n_points,
295 double *points, float *color, gamgi_bool *error)
296 {
297 static_point (fp, n_points, points, color, 0, 3, 0, error);
298 }
299
300 /************* external function ***********
301 * *
302 * GAMGI_IO_X3D_RENDER_LOOPS *
303 * *
304 * draws line loops (connected lines) *
305 *******************************************/
306
307 void gamgi_io_x3d_render_loops (FILE *fp, int *loops,
308 double *points, gamgi_bool * error)
309 {
310 char string[GAMGI_ENGINE_LINE];
311 int i, j, c, p, n_loops;
312
313 if (loops == NULL) return;
314
315 n_loops = loops[0];
316
317 gamgi_io_file_fprintf (fp, "<IndexedLineSet coordIndex='", error);
318
319 p = 1;
320 c = 0;
321 for (i = 0; i < n_loops; i++)
322 {
323 for (j = 0; j < loops[p]; j++)
324 {
325 sprintf (string, "%d ", c);
326 gamgi_io_file_fprintf(fp, string, error);
327 c++;
328 }
329 sprintf (string, "%d -1", c - loops[p]);
330 gamgi_io_file_fprintf(fp, string, error);
331 if (i != n_loops - 1)
332 gamgi_io_file_fprintf(fp, " ", error);
333
334 p += loops[p]+1;
335 }
336
337 gamgi_io_file_fprintf (fp, "'>\n<Coordinate point='", error);
338
339 i = 1;
340 while (n_loops-- > 0)
341 {
342 p = loops[i++];
343 while (p-- > 0)
344 {
345 sprintf (string, "%f %f %f",
346 points[3*loops[i]], points[3*loops[i]+1], points[3*loops[i]+2]);
347 gamgi_io_file_fprintf (fp, string, error);
348 i++;
349
350 if (p > 0 || n_loops > 0) gamgi_io_file_fprintf (fp, ", ", error);
351 }
352 }
353 gamgi_io_file_fprintf(fp, "'/>\n</IndexedLineSet>\n", error);
354 }
355
356 /************* external function ***********
357 * *
358 * GAMGI_IO_X3D_RENDER_LINES *
359 * *
360 * draws lines *
361 *******************************************/
362
363 void gamgi_io_x3d_render_lines (FILE *fp,
364 int *lines, double *points, gamgi_bool *error)
365 {
366 char string[GAMGI_ENGINE_LINE];
367 int i, n_lines;
368
369 n_lines = lines[0];
370 if (n_lines == 0) return;
371
372 gamgi_io_file_fprintf(fp, "<IndexedLineSet coordIndex='", error);
373
374 for (i = 0; i <n_lines; i++)
375 {
376 sprintf (string, "%d %d -1", i*2, i*2+1);
377 gamgi_io_file_fprintf (fp, string, error);
378
379 if (i != n_lines - 1)
380 gamgi_io_file_fprintf (fp, " ", error);
381 }
382
383 gamgi_io_file_fprintf(fp, "'>\n<Coordinate point='", error);
384
385 i = 1;
386 while (n_lines-- > 0)
387 {
388 sprintf (string, "%f %f %f, ",
389 points[3*lines[i]], points[3*lines[i]+1], points[3*lines[i]+2]);
390 gamgi_io_file_fprintf(fp, string, error);
391 i++;
392 sprintf (string, "%f %f %f",
393 points[3*lines[i]], points[3*lines[i]+1], points[3*lines[i]+2]);
394 gamgi_io_file_fprintf(fp, string, error);
395 i++;
396
397 if (n_lines>0)
398 gamgi_io_file_fprintf(fp, ", ", error);
399 }
400
401 gamgi_io_file_fprintf(fp, "'/>\n</IndexedLineSet>\n", error);
402 }
403
404 /************* external function ***********
405 * *
406 * GAMGI_IO_X3D_RENDER_TRIANGLES *
407 * *
408 * render a triangle-based face *
409 *******************************************/
410
411 void gamgi_io_x3d_render_triangles (FILE *fp,
412 int n_triangles, double *points, gamgi_bool *error)
413 {
414 char string[GAMGI_ENGINE_LINE];
415 int n_points, i;
416
417 if (n_triangles == 0) return;
418 n_points = 3 * n_triangles;
419
420 gamgi_io_file_fprintf (fp, "<IndexedTriangleSet ", error);
421 gamgi_io_file_fprintf (fp, "solid=\"false\" ", error);
422 gamgi_io_file_fprintf (fp, "ccw=\"true\" ", error);
423 gamgi_io_file_fprintf (fp, "normalPerVertex=\"false\" ", error);
424 gamgi_io_file_fprintf (fp, "index=\"\n", error);
425
426 for (i = 0; i < n_points; i += 3)
427 {
428 sprintf (string, "%d %d %d\n", i + 0, i + 1, i + 2);
429 gamgi_io_file_fprintf (fp, string, error);
430 }
431 gamgi_io_file_fprintf (fp, "\">\n<Coordinate point=\"\n", error);
432
433 for (i = 0; i < n_points; i++)
434 {
435 sprintf (string, "%f %f %f\n",
436 points[3 * i + 0], points[3 * i + 1] + 10, points[3 * i + 2]);
437 gamgi_io_file_fprintf (fp, string, error);
438 }
439
440 gamgi_io_file_fprintf (fp, "\"/>\n</IndexedTriangleSet>\n", error);
441 }
442
443 /************* external function ***********
444 * *
445 * GAMGI_IO_X3D_RENDER_LINE_STRIP *
446 * *
447 * draws a line strip *
448 *******************************************/
449
450 void gamgi_io_x3d_render_line_strip (FILE *fp,
451 int n_points, double * points, gamgi_bool * error)
452 {
453 char string[GAMGI_ENGINE_LINE];
454 int i;
455
456 if (n_points == 0) return;
457
458 gamgi_io_file_fprintf(fp, "<IndexedLineSet coordIndex='", error);
459
460 for (i = 0; i < n_points; i++)
461 {
462 sprintf (string, "%d", i);
463 gamgi_io_file_fprintf(fp, string, error);
464
465 if (i != n_points - 1)
466 gamgi_io_file_fprintf (fp, " ", error);
467 else
468 gamgi_io_file_fprintf(fp, " -1'>\n<Coordinate point='", error);
469 }
470
471 while (n_points-- > 0)
472 {
473 sprintf (string, "%f %f %f",
474 *(points+3*n_points), *(points+3*n_points+1), *(points+3*n_points+2));
475 gamgi_io_file_fprintf (fp, string, error);
476
477 if (n_points > 0)
478 gamgi_io_file_fprintf (fp, ", ", error);
479 }
480
481 gamgi_io_file_fprintf (fp, "'/>\n</IndexedLineSet>\n", error);
482 }
483
484 /************* external function ***********
485 * *
486 * GAMGI_IO_X3D_RENDER_POLYGONS *
487 * *
488 * draws polygons *
489 *******************************************/
490
491 void gamgi_io_x3d_render_polygons (FILE *fp,
492 int *loops, double *points, gamgi_bool * error)
493 {
494 char str[256];
495 int p, i, j, n_loops, c;
496 int * n_vertices;
497
498 double ** point;
499
500 p = 0;
501 c = 0;
502
503 n_loops = loops[p++];
504 n_vertices = malloc(sizeof(int)*n_loops);
505 point = malloc(sizeof(double *)*n_loops);
506
507 gamgi_io_file_fprintf(fp, "<IndexedFaceSet solid='false' coordIndex='", error);
508
509 for(i=0; i<n_loops; i++)
510 {
511 n_vertices[i] = loops[p++];
512 point[i] = malloc(n_vertices[i]*sizeof(double)*3);
513
514 for(j=0; j<n_vertices[i]; j++)
515 {
516 if(i==0 && j==0)
517 sprintf(str, "%d", c);
518 else
519 sprintf(str, " %d", c);
520
521 gamgi_io_file_fprintf(fp, str, error);
522
523 c++;
524
525 point[i][j*3] = points[3 * loops[p]];
526 point[i][j*3+1] = points[3 * loops[p]+1];
527 point[i][j*3+2] = points[3 * loops[p]+2];
528
529 p++;
530 }
531
532 sprintf(str, " -1");
533
534 gamgi_io_file_fprintf(fp, str, error);
535 }
536
537 gamgi_io_file_fprintf(fp, "'>\n<Coordinate point='", error);
538 for(i=0; i<n_loops; i++)
539 {
540 for(j=0; j<n_vertices[i]; j++)
541 {
542 sprintf(str, "%f %f %f", point[i][j*3], point[i][j*3+1], point[i][j*3+2]);
543 gamgi_io_file_fprintf(fp, str, error);
544 if(!(i==n_loops-1&&j==n_vertices[i]-1))
545 gamgi_io_file_fprintf(fp, ", ", error);
546 }
547 }
548
549 gamgi_io_file_fprintf(fp, "'/>\n</IndexedFaceSet>\n", error);
550
551 for(i=0; i<n_loops; i++) free(point[i]);
552 free(point);
553 }
554
555
556 /* draws colored polygons */
557 void gamgi_io_x3d_render_polygons_color (FILE *fp, int *loops,
558 double *points, int *paints, float *colors, gamgi_bool * error)
559 {
560 char str[256];
561 int p, i, j, n_loops, c;
562 int * n_vertices;
563
564 double ** point;
565
566 p = 0;
567 c = 0;
568
569 n_loops = loops[p++];
570 n_vertices = malloc(sizeof(int)*n_loops);
571 point = malloc(sizeof(double *)*n_loops);
572
573 gamgi_io_file_fprintf(fp, "<IndexedFaceSet solid='false' coordIndex='", error);
574
575 for(i=0; i<n_loops; i++)
576 {
577 n_vertices[i] = loops[p++];
578 point[i] = malloc(n_vertices[i]*sizeof(double)*3);
579
580 for(j=0; j<n_vertices[i]; j++)
581 {
582 if(i==0 && j==0)
583 sprintf(str, "%d", c);
584 else
585 sprintf(str, " %d", c);
586
587 gamgi_io_file_fprintf(fp, str, error);
588
589 c++;
590
591 point[i][j*3] = points[3 * loops[p]];
592 point[i][j*3+1] = points[3 * loops[p]+1];
593 point[i][j*3+2] = points[3 * loops[p]+2];
594
595 p++;
596 }
597
598 sprintf(str, " -1");
599
600 gamgi_io_file_fprintf(fp, str, error);
601 }
602
603 gamgi_io_file_fprintf(fp, "' colorPerVertex='false' colorIndex='", error);
604
605 c=-1;
606 p=1;
607 for(i=0; i<n_loops; i++)
608 {
609 if(paints[0] == p)
610 {
611 c++;
612 paints++;
613 }
614
615 p += loops[p]+1;
616
617 sprintf(str, "%d", c);
618 gamgi_io_file_fprintf(fp, str, error);
619
620 if(i<n_loops)
621 gamgi_io_file_fprintf(fp, " ", error);
622 }
623
624 gamgi_io_file_fprintf(fp, "'>\n<Coordinate point='", error);
625 for(i=0; i<n_loops; i++)
626 {
627 for(j=0; j<n_vertices[i]; j++)
628 {
629 sprintf(str, "%f %f %f", point[i][j*3], point[i][j*3+1], point[i][j*3+2]);
630 gamgi_io_file_fprintf(fp, str, error);
631 if(!(i==n_loops-1&&j==n_vertices[i]-1))
632 gamgi_io_file_fprintf(fp, ", ", error);
633 }
634 }
635
636 gamgi_io_file_fprintf(fp, "'/>\n<Color color='", error);
637
638 for(i=0; i<=c; i++)
639 {
640 sprintf(str, "%f %f %f", colors[0], colors[1], colors[2]);
641 gamgi_io_file_fprintf(fp, str, error);
642 colors += 3;
643
644 if(i!=c)
645 gamgi_io_file_fprintf(fp, ", ", error);
646 }
647
648 gamgi_io_file_fprintf(fp, "'/>\n</IndexedFaceSet>\n", error);
649
650
651
652 for(i=0; i<n_loops; i++) free(point[i]);
653 free(point);
654 }
655
656 /************* internal function ***************
657 * *
658 * GAMGI_IO_X3D_RENDER_WIRED *
659 * *
660 * draws wired text using the hard coded fonts *
661 ***********************************************/
662
663 void gamgi_io_x3d_render_wired (FILE *fp, gamgi_text *text, gamgi_bool *error)
664 {
665 int c = 0;
666 int i, j;
667 int *driver;
668 float *points;
669 char str[256];
670 float spacing;
671
672 printf ("ola\n");
673
674 gamgi_mesa_text_data_wired (text->font, (const float **) &points, (const int **) &driver);
675 gamgi_io_file_fprintf (fp, "<IndexedLineSet coordIndex='", error);
676
677
678 for(i=0; i<text->length; i++)
679 {
680 j = driver[text->string[i]-GAMGI_IO_ASCII_START];
681
682 while(points[j] != GAMGI_IO_CHAR)
683 {
684 if(points[j] == GAMGI_IO_STROKE)
685 {
686 gamgi_io_file_fprintf(fp, "-1, ", error);
687 j++;
688 }
689 else
690 {
691 sprintf(str, "%d, ", c);
692 gamgi_io_file_fprintf(fp, str, error);
693 c++;
694 j+=2;
695 }
696 }
697
698 if(i<text->length-1)
699 gamgi_io_file_fprintf(fp, "-1, ", error);
700 }
701
702 gamgi_io_file_fprintf(fp, "-1'>\n<Coordinate point='", error);
703 spacing = 0.0f;
704
705 for(i=0; i<text->length; i++)
706 {
707 j = driver[text->string[i]-GAMGI_IO_ASCII_START];
708
709 while(points[j] != GAMGI_IO_CHAR)
710 {
711 if(points[j] != GAMGI_IO_STROKE)
712 {
713 sprintf(str, "%f %f 0.0", points[j]/GAMGI_MESA_STROKED_SCALE+spacing, points[j+1]/GAMGI_MESA_STROKED_SCALE);
714 gamgi_io_file_fprintf(fp, str, error);
715 j+=2;
716
717 if(i<text->length-1 || points[j] != GAMGI_IO_CHAR)
718 gamgi_io_file_fprintf(fp, ", ", error);
719 }
720 else
721 {
722 j++;
723 }
724 }
725
726 spacing += points[text->string[i]-GAMGI_IO_ASCII_START+2]/GAMGI_MESA_STROKED_SCALE;
727 }
728
729 gamgi_io_file_fprintf(fp, "'/>\n</IndexedLineSet>\n", error);
730 }
731
732 void x3d_font_extrusion(glu_tessdata * data)
733 {
734 int i;
735 double depth = GAMGI_MESA_EXTRUDED_DEPTH * GAMGI_MESA_EXTRUDED_SCALE;
736
737 int n_contour = data->extruded->contour->offset;
738 double *contour = data->extruded->contour->array;
739 double scale = data->extruded->scale;
740
741 int itemp[4];
742 double dtemp[3];
743
744 data->polygon = GL_TRIANGLE_STRIP;
745 data->vertex = 0;
746
747 for(i = 0; i <= n_contour; i++)
748 {
749 if(i == n_contour)
750 i = n_contour = 0;
751
752 if(data->vertex>1)
753 {
754 itemp[0] = data->vcount/3-2;
755 itemp[1] = data->vcount/3-1;
756 itemp[2] = data->vcount/3;
757 itemp[3] = -1;
758
759 data->ocount += 4;
760
761 gamgi_engine_iarray_push(data->order, itemp);
762 }
763
764 if(contour[2*i + 0] == contour[2*i + 0])
765 dtemp[0] = data->x + contour[2*i + 0] * scale;
766 else
767 dtemp[0] = data->x;
768
769 if(contour[2*i + 1] == contour[2*i + 1])
770 dtemp[1] = data->y + contour[2*i + 1] * scale;
771 else
772 dtemp[1] = data->y;
773
774 dtemp[2] = data->z - depth / 2.0;
775
776 data->vcount += 3;
777 data->vertex++;
778
779 gamgi_engine_darray_push(data->vert, dtemp);
780
781 if(data->vertex>1)
782 {
783 itemp[0] = data->vcount/3-2;
784 itemp[1] = data->vcount/3-1;
785 itemp[2] = data->vcount/3;
786 itemp[3] = -1;
787
788 data->ocount += 4;
789
790 gamgi_engine_iarray_push(data->order, itemp);
791 }
792
793 if(contour[2*i + 0] == contour[2*i + 0])
794 dtemp[0] = data->x + contour[2*i + 0] * scale;
795 else
796 dtemp[0] = data->x;
797
798 if(contour[2*i + 1] == contour[2*i + 1])
799 dtemp[1] = data->y + contour[2*i + 1] * scale;
800 else
801 dtemp[1] = data->y;
802
803 dtemp[2] = data->z + depth / 2.0;
804
805 data->vcount += 3;
806 data->vertex++;
807
808 gamgi_engine_darray_push(data->vert, dtemp);
809 }
810 }
811
812
813 static void static_glu_begin (GLenum polygon, glu_tessdata *data)
814 {
815 data->polygon = polygon;
816 data->vertex = 0;
817
818 if (polygon == GL_TRIANGLE_FAN)
819 data->fancenter = data->vcount / 3;
820 }
821
822 static void static_glu_vertex (double* vertex, glu_tessdata *data)
823 {
824 int temp[4];
825 double point[3];
826
827 switch (data->polygon)
828 {
829 case GL_TRIANGLES: /* 0, 1, 2, -1, 3, 4, 5, -1... */
830 if ((data->vertex + 1) % 3 == 0)
831 {
832 temp[0] = data->vcount / 3 - 2;
833 temp[1] = data->vcount / 3 - 1;
834 temp[2] = data->vcount / 3 - 0;
835 temp[3] = -1;
836
837 data->ocount += 4;
838 gamgi_engine_iarray_push(data->order, temp);
839 }
840 break;
841
842 case GL_TRIANGLE_STRIP: /*Strip: 0,1,2,-1,1,2,3,-1,2,3,4,-1... "n-2, n-1, n, -1" */
843 if (data->vertex > 1)
844 {
845 temp[0] = data->vcount / 3 - 2;
846 temp[1] = data->vcount / 3 - 1;
847 temp[2] = data->vcount / 3 - 0;
848 temp[3] = -1;
849
850 data->ocount += 4;
851 gamgi_engine_iarray_push(data->order, temp);
852 }
853 break;
854
855 case GL_TRIANGLE_FAN: /* Fan: 0,1,2,-1,0,2,3,-1,0,3,4,-1... "0, n-1, n, -1" */
856 if (data->vertex > 1)
857 {
858 temp[0] = data->fancenter;
859 temp[1] = data->vcount / 3 - 1;
860 temp[2] = data->vcount / 3;
861 temp[3] = -1;
862
863 data->ocount += 4;
864 gamgi_engine_iarray_push(data->order, temp);
865 }
866 break;
867 }
868
869 point[0] = vertex[0] + data->x;
870 point[1] = vertex[1] + data->y;
871 point[2] = vertex[2] + data->z;
872
873 data->vcount += 3;
874 data->vertex++;
875
876 gamgi_engine_darray_push(data->vert, point);
877 }
878
879
880 static void static_glu_combine (double coords[3], void *vertices[4],
881 float weights[4], void** output, glu_tessdata *data)
882 {
883 double *vertex;
884 gamgi_extruded *extruded = data->extruded;
885
886 /***************************************************
887 * vertices and weights data is used to calculate *
888 * averaged points and is not used in this context *
889 ***************************************************/
890
891 vertex = (double *) malloc (3 * sizeof(double));
892 gamgi_math_vector_copy(coords, vertex);
893
894 *output = vertex;
895 extruded->extra = gamgi_engine_slist_add_start (extruded->extra);
896 extruded->extra->data = vertex;
897 }
898
899 static int static_vertical_move (FT_Vector *to, glu_tessdata *data)
900 {
901 if (data->extruded->open == TRUE)
902 {
903 gamgi_engine_darray_push(data->extruded->normals, data->extruded->normals->array);
904
905 x3d_font_extrusion (data);
906
907 gamgi_engine_darray_pop(data->extruded->contour, 0);
908 gamgi_engine_darray_pop(data->extruded->normals, 0);
909 }
910
911 data->extruded->last[0] = to->x;
912 data->extruded->last[1] = to->y;
913 data->extruded->last[2] = 0.0;
914
915 data->extruded->open = TRUE;
916
917 return 0;
918 }
919
920 static int static_vertical_line (FT_Vector *to, glu_tessdata *data)
921 {
922 double vertex[2];
923 double normal[2];
924 gamgi_extruded * extruded = data->extruded;
925
926 vertex[0] = to->x;
927 vertex[1] = to->y;
928
929 normal[0] = extruded->normal_y * (vertex[1] - extruded->last[1]);
930 normal[1] = extruded->normal_x * (vertex[0] - extruded->last[0]);
931
932 gamgi_engine_darray_push (extruded->contour, vertex);
933 gamgi_engine_darray_push (extruded->normals, normal);
934
935 extruded->last[0] = vertex[0];
936 extruded->last[1] = vertex[1];
937 extruded->last[2] = 0.0;
938
939 return 0;
940 }
941
942 static int static_vertical_conic (FT_Vector *control, FT_Vector *to, glu_tessdata *data)
943 {
944 double vertex[2];
945 double normal[2];
946 double to_vertex[2];
947 double control_vertex[2];
948 double b[2], c[2], d[2], f[2], df[2], d2f[2];
949 int i;
950 gamgi_extruded * extruded = data->extruded;
951
952 to_vertex[0] = to->x;
953 to_vertex[1] = to->y;
954
955 control_vertex[0] = control->x;
956 control_vertex[1] = control->y;
957
958 b[0] = extruded->last[0] - 2 * control_vertex[0] + to_vertex[0];
959 b[1] = extruded->last[1] - 2 * control_vertex[1] + to_vertex[1];
960
961 c[0] = -2 * extruded->last[0] + 2 * control_vertex[0];
962 c[1] = -2 * extruded->last[1] + 2 * control_vertex[1];
963
964 d[0] = extruded->last[0];
965 d[1] = extruded->last[1];
966
967 f[0] = d[0];
968 f[1] = d[1];
969 df[0] = c[0] * extruded->delta1 + b[0] * extruded->delta2;
970 df[1] = c[1] * extruded->delta1 + b[1] * extruded->delta2;
971 d2f[0] = 2 * b[0] * extruded->delta2;
972 d2f[1] = 2 * b[1] * extruded->delta2;
973
974 for (i = 0; i < GAMGI_MESA_EXTRUDED_STEPS - 1; i++)
975 {
976 f[0] += df[0];
977 f[1] += df[1];
978
979 vertex[0] = f[0];
980 vertex[1] = f[1];
981
982 normal[0] = extruded->normal_y * df[1];
983 normal[1] = extruded->normal_x * df[0];
984
985 gamgi_engine_darray_push (extruded->contour, vertex);
986 gamgi_engine_darray_push (extruded->normals, normal);
987
988 df[0] += d2f[0];
989 df[1] += d2f[1];
990 }
991
992 vertex[0] = to->x;
993 vertex[1] = to->y;
994
995 normal[0] = extruded->normal_y * df[1];
996 normal[1] = extruded->normal_x * df[0];
997
998 gamgi_engine_darray_push (extruded->contour, vertex);
999 gamgi_engine_darray_push (extruded->normals, normal);
1000
1001 extruded->last[0] = to_vertex[0];
1002 extruded->last[1] = to_vertex[1];
1003 extruded->last[2] = 0.0;
1004
1005 return 0;
1006 }
1007
1008 static int static_vertical_cubic (FT_Vector *control1,
1009 FT_Vector *control2, FT_Vector* to, glu_tessdata * data)
1010 {
1011 gamgi_extruded *extruded = data->extruded;
1012 double vertex[2];
1013 double normal[2];
1014 double to_vertex[2];
1015 double control1_vertex[2];
1016 double control2_vertex[2];
1017 double a[2], b[2], c[2], d[2], f[2], df[2], d2f[2], d3f[2];
1018 int i;
1019
1020 to_vertex[0] = to->x;
1021 to_vertex[1] = to->y;
1022
1023 control1_vertex[0] = control1->x;
1024 control1_vertex[1] = control1->y;
1025
1026 control2_vertex[0] = control2->x;
1027 control2_vertex[1] = control2->y;
1028
1029 a[0] = -extruded->last[0] + 3 * control1_vertex[0]
1030 -3 * control2_vertex[0] + to_vertex[0];
1031 a[1] = -extruded->last[1] + 3 * control1_vertex[1]
1032 -3 * control2_vertex[1] + to_vertex[1];
1033
1034 b[0] = 3 * extruded->last[0] - 6 * control1_vertex[0] +
1035 3 * control2_vertex[0];
1036 b[1] = 3 * extruded->last[1] - 6 * control1_vertex[1] +
1037 3 * control2_vertex[1];
1038
1039 c[0] = -3 * extruded->last[0] + 3 * control1_vertex[0];
1040 c[1] = -3 * extruded->last[1] + 3 * control1_vertex[1];
1041
1042 d[0] = extruded->last[0];
1043 d[1] = extruded->last[1];
1044
1045 f[0] = d[0];
1046 f[1] = d[1];
1047 df[0] = c[0] * extruded->delta1 + b[0] * extruded->delta2 + a[0] * extruded->delta3;
1048 df[1] = c[1] * extruded->delta1 + b[1] * extruded->delta2 + a[1] * extruded->delta3;
1049 d2f[0] = 2 * b[0] * extruded->delta2 + 6 * a[0] * extruded->delta3;
1050 d2f[1] = 2 * b[1] * extruded->delta2 + 6 * a[1] * extruded->delta3;
1051 d3f[0] = 6 * a[0] * extruded->delta3;
1052 d3f[1] = 6 * a[1] * extruded->delta3;
1053
1054 for (i = 0; i < GAMGI_MESA_EXTRUDED_STEPS - 1; i++)
1055 {
1056 f[0] += df[0];
1057 f[1] += df[1];
1058
1059 vertex[0] = f[0];
1060 vertex[1] = f[1];
1061
1062 normal[0] = extruded->normal_y * df[1];
1063 normal[1] = extruded->normal_x * df[0];
1064
1065 gamgi_engine_darray_push (extruded->contour, vertex);
1066 gamgi_engine_darray_push (extruded->normals, normal);
1067
1068 df[0] += d2f[0];
1069 df[1] += d2f[1];
1070 d2f[0] += d3f[0];
1071 d2f[1] += d3f[1];
1072 }
1073
1074 vertex[0] = to->x;
1075 vertex[1] = to->y;
1076
1077 normal[0] = extruded->normal_y * df[1];
1078 normal[1] = extruded->normal_x * df[0];
1079
1080 gamgi_engine_darray_push (extruded->contour, vertex);
1081 gamgi_engine_darray_push (extruded->normals, normal);
1082
1083 extruded->last[0] = to_vertex[0];
1084 extruded->last[1] = to_vertex[1];
1085 extruded->last[2] = 0.0;
1086
1087 return 0;
1088 }
1089
1090 static void x3d_font_face (FT_OutlineGlyph glyph, glu_tessdata *data)
1091 {
1092 gluTessBeginPolygon (data->extruded->tesselator, data);
1093 data->extruded->open = FALSE;
1094
1095 FT_Outline_Decompose (&glyph->outline, &data->extruded->horizontal, data->extruded);
1096
1097 if (data->extruded->open == TRUE)
1098 gluTessEndContour (data->extruded->tesselator);
1099
1100 gluTessEndPolygon (data->extruded->tesselator);
1101 }
1102
1103 gamgi_extruded *static_extruded_create (gamgi_enum font,
1104 FT_Library *freetype, FT_Face *face)
1105 {
1106 gamgi_extruded *extruded;
1107 char fullname[GAMGI_IO_FULLNAME];
1108 char filename[GAMGI_ENGINE_TOKEN];
1109
1110 gamgi_mesa_text_data_solid (font, filename);
1111
1112 sprintf (fullname, "%s/%s", gamgi->text->path, filename);
1113
1114 FT_Init_FreeType (freetype);
1115
1116 FT_New_Face (*freetype, fullname, 0, face);
1117
1118 if ((*face)->charmap == 0 && (*face)->num_charmaps > 0)
1119 FT_Select_Charmap (*face, (*face)->charmaps[0]->encoding);
1120
1121 extruded = (gamgi_extruded *) malloc (sizeof (gamgi_extruded));
1122
1123 extruded->horizontal.move_to = (FT_Outline_MoveTo_Func) gamgi_mesa_text_horizontal_move;
1124 extruded->horizontal.line_to = (FT_Outline_LineTo_Func) gamgi_mesa_text_horizontal_line;
1125 extruded->horizontal.conic_to = (FT_Outline_ConicTo_Func) gamgi_mesa_text_horizontal_conic;
1126 extruded->horizontal.cubic_to = (FT_Outline_CubicTo_Func) gamgi_mesa_text_horizontal_cubic;
1127 extruded->horizontal.shift = 0;
1128 extruded->horizontal.delta = 0;
1129
1130 extruded->vertical.move_to = (FT_Outline_MoveTo_Func) static_vertical_move;
1131 extruded->vertical.line_to = (FT_Outline_LineTo_Func) static_vertical_line;
1132 extruded->vertical.conic_to = (FT_Outline_ConicTo_Func) static_vertical_conic;
1133 extruded->vertical.cubic_to = (FT_Outline_CubicTo_Func) static_vertical_cubic;
1134 extruded->vertical.shift = 0;
1135 extruded->vertical.delta = 0;
1136
1137 extruded->delta1 = 1.0 / GAMGI_MESA_EXTRUDED_STEPS;
1138 extruded->delta2 = extruded->delta1 * extruded->delta1;
1139 extruded->delta3 = extruded->delta2 * extruded->delta1;
1140
1141 FT_Set_Char_Size (*face, 0, (*face)->units_per_EM, 0, 0);
1142 extruded->scale = GAMGI_MESA_EXTRUDED_SCALE / (*face)->units_per_EM;
1143
1144 extruded->vertices = NULL;
1145 extruded->extra = NULL;
1146
1147 extruded->contour = gamgi_engine_darray_create(GAMGI_MESA_EXTRUDED_START,
1148 GAMGI_MESA_EXTRUDED_STEP, 2);
1149 extruded->normals = gamgi_engine_darray_create(GAMGI_MESA_EXTRUDED_START,
1150 GAMGI_MESA_EXTRUDED_STEP, 2);
1151
1152 extruded->tesselator = gluNewTess ();
1153
1154 gluTessCallback (extruded->tesselator, GLU_TESS_VERTEX_DATA,
1155 (gamgi_tesselation) static_glu_vertex);
1156 gluTessCallback (extruded->tesselator, GLU_TESS_BEGIN_DATA,
1157 (gamgi_tesselation) static_glu_begin);
1158 gluTessCallback(extruded->tesselator, GLU_TESS_COMBINE_DATA,
1159 (gamgi_tesselation) static_glu_combine);
1160
1161 return extruded;
1162 }
1163
1164 gamgi_bool static_extruded_remove (FT_Library freetype,
1165 FT_Face face, gamgi_extruded *extruded)
1166 {
1167 gamgi_bool valid = TRUE;
1168
1169 gluDeleteTess (extruded->tesselator);
1170 gamgi_engine_darray_remove (extruded->contour);
1171 gamgi_engine_darray_remove (extruded->normals);
1172 free (extruded);
1173
1174 if (FT_Done_Face (face) != 0) valid = FALSE;
1175 if (FT_Done_FreeType (freetype) != 0) valid = FALSE;
1176
1177 return valid;
1178 }
1179
1180 /************* external function ***********
1181 * *
1182 * GAMGI_IO_X3D_RENDER_SOLID *
1183 * *
1184 * draws solid text *
1185 *******************************************/
1186
1187 void gamgi_io_x3d_render_solid (FILE *fp, gamgi_text *text, gamgi_bool *error)
1188 {
1189 glu_tessdata tessdata;
1190 FT_OutlineGlyph glyph;
1191 FT_Library freetype;
1192 FT_Face face;
1193 gamgi_slist *slist;
1194 char string[GAMGI_ENGINE_LINE];
1195 double *vert;
1196 double depth;
1197 int *order;
1198 int ascii, index;
1199 int i;
1200
1201 tessdata.extruded = static_extruded_create (text->font, &freetype, &face);
1202 tessdata.vcount = 0;
1203 tessdata.ocount = 0;
1204 tessdata.x = tessdata.y = 0.0f;
1205
1206 tessdata.vert = gamgi_engine_darray_create (GAMGI_IO_X3D_TOTAL, GAMGI_IO_X3D_STEP, 3);
1207 tessdata.order = gamgi_engine_iarray_create (GAMGI_IO_X3D_TOTAL, GAMGI_IO_X3D_STEP, 4);
1208
1209 for (i = 0; i < text->length; i++)
1210 {
1211 ascii = text->string[i];
1212
1213 index = FT_Get_Char_Index(face, ascii);
1214 FT_Load_Glyph(face, index, FT_LOAD_NO_SCALE);
1215 FT_Get_Glyph(face->glyph, (FT_Glyph *) (void *) &glyph);
1216
1217 if (glyph->outline.flags & FT_OUTLINE_REVERSE_FILL)
1218 {
1219 tessdata.extruded->normal_x = -1;
1220 tessdata.extruded->normal_y = 1;
1221 }
1222 else
1223 {
1224 tessdata.extruded->normal_x = 1;
1225 tessdata.extruded->normal_y = -1;
1226 }
1227
1228 depth = GAMGI_MESA_EXTRUDED_DEPTH * GAMGI_MESA_EXTRUDED_SCALE;
1229
1230 tessdata.z = depth/2;
1231 x3d_font_face(glyph, &tessdata);
1232
1233 tessdata.z = -depth/2;
1234 x3d_font_face(glyph, &tessdata);
1235
1236 tessdata.z = 0.0;
1237
1238 tessdata.extruded->open = FALSE;
1239 FT_Outline_Decompose (&glyph->outline, &tessdata.extruded->vertical, &tessdata);
1240 if (tessdata.extruded->open == TRUE)
1241 {
1242 gamgi_engine_darray_push (tessdata.extruded->normals, tessdata.extruded->normals->array);
1243 x3d_font_extrusion (&tessdata);
1244 gamgi_engine_darray_pop(tessdata.extruded->contour, 0);
1245 gamgi_engine_darray_pop(tessdata.extruded->normals, 0);
1246 }
1247
1248 tessdata.x += face->glyph->advance.x * tessdata.extruded->scale;
1249 tessdata.y += face->glyph->advance.y * tessdata.extruded->scale;
1250
1251 FT_Done_Glyph((FT_Glyph) glyph);
1252
1253 for (slist = tessdata.extruded->vertices; slist != NULL; slist = slist->next)
1254 {
1255 free(slist->data);
1256 slist = gamgi_engine_slist_remove_start(slist);
1257 }
1258 tessdata.extruded->vertices = NULL;
1259 }
1260
1261 static_extruded_remove (freetype, face, tessdata.extruded);
1262
1263 gamgi_io_file_fprintf (fp, "<IndexedFaceSet solid='false' coordIndex='", error);
1264
1265 order = tessdata.order->array;
1266
1267 for (i = 0; i < tessdata.ocount-1; i++)
1268 {
1269 sprintf (string, "%d, ", order[i]);
1270 gamgi_io_file_fprintf(fp, string, error);
1271 }
1272 sprintf (string, "%d", order[i]);
1273 gamgi_io_file_fprintf (fp, string, error);
1274
1275 gamgi_io_file_fprintf (fp, "'>\n<Coordinate point='", error);
1276
1277 vert = tessdata.vert->array;
1278
1279 for (i = 0; i < tessdata.vcount / 3 - 1; i++)
1280 {
1281 sprintf (string, "%f %f %f, ", vert[i*3], vert[i*3+1], vert[i*3+2]);
1282 gamgi_io_file_fprintf(fp, string, error);
1283 }
1284 sprintf (string, "%f %f %f", vert[i*3], vert[i*3+1], vert[i*3+2]);
1285 gamgi_io_file_fprintf (fp, string, error);
1286
1287 gamgi_io_file_fprintf(fp, "'/>\n</IndexedFaceSet>\n", error);
1288
1289 gamgi_engine_darray_remove (tessdata.vert);
1290 gamgi_engine_iarray_remove (tessdata.order);
1291 }