1 #include <QvElement.h>
2 #include <QvNodes.h>
3 #include <QvState.h>
4 #include <QvToWebOOGL.h>
5 #include <QvMaterialBinding.h>
6 #include <QvNormalBinding.h>
7 #include <QvUnknownNode.h>
8 #include <QvInfo.h>
9
10 extern "C" {
11 #include <unistd.h>
12 }
13
14 //////////////////////////////////////////////////////////////////////////////
15 //
16 // ToWebOOGL will traverse and convert any vrml object to WebOOGL!
17 // Because ToWebOOGL() is defined in the header for ALL node
18 // classes, each one has an implementation here.
19 //
20 //////////////////////////////////////////////////////////////////////////////
21
22 // For debugging
23 static int indent = 0;
24 static int oogldepth = 0, unique = 0, mypid = 0;
25 static char out[5000];
26 static char colstr[100];
27 enum Binding {
28 DEFAULT,
29 OVERALL,
30 PER_PART,
31 PER_PART_INDEXED,
32 PER_FACE,
33 PER_FACE_INDEXED,
34 PER_VERTEX,
35 PER_VERTEX_INDEXED,
36 };
37
38
39 static void
OOGLannounce(const char * className)40 OOGLannounce(const char *className)
41 {
42 /*
43 for (int i = 0; i < indent; i++)
44 fprintf(stderr,"\t");
45 fprintf(stderr,"Converting a %s to WebOOGL - depth: %d\n", className, oogldepth);
46 */
47 }
48 #define ANNOUNCE(className) OOGLannounce(QV__QUOTE(className))
49
50 static FILE *OOGLfout = (FILE *)NULL;
51 static char *OOGLhand = NULL;
52 static char *urls[100];
53
OOGLnumuniq()54 int OOGLnumuniq()
55 {
56 return unique;
57 }
58
59 char *
OOGLgeturls(int i)60 OOGLgeturls(int i)
61 {
62 return urls[i];
63 }
64
65 int
OOGLhandle(char * handle)66 OOGLhandle(char *handle)
67 {
68 OOGLhand = handle;
69 return 1;
70 }
71
72 int
OOGLfile(FILE * fout)73 OOGLfile(FILE *fout)
74 {
75 OOGLfout = fout;
76 mypid = (int) getpid();
77 return 1;
78 }
79
80 static void
OOGLout(const char * text)81 OOGLout(const char *text)
82 {
83 if (OOGLfout == NULL) return;
84
85 for (int i = 1; i < indent; i++)
86 fprintf(OOGLfout, " ");
87 fprintf(OOGLfout, "%s\n", text);
88 }
89
90 static void
OOGLflush()91 OOGLflush()
92 {
93 if(OOGLfout != NULL)
94 fflush(OOGLfout);
95 }
96
97 static void
OOGLoutindent()98 OOGLoutindent()
99 {
100 if (OOGLfout == NULL) return;
101
102 for (int i = 1; i < indent; i++)
103 fprintf(OOGLfout, " ");
104 }
105
106 static void
OOGLoutraw(const char * text)107 OOGLoutraw(const char *text)
108 {
109 if (OOGLfout == NULL) return;
110
111 fprintf(OOGLfout, "%s", text);
112 }
113
114
115 static void
OOGLgetcolor(QvMaterial * mt,QvMaterialBinding * mtb,int mtnum)116 OOGLgetcolor(QvMaterial *mt, QvMaterialBinding *mtb, int mtnum)
117 {
118 // float *amb;
119 float *em, *dif;
120 float a;
121
122 if (mt == NULL || mtnum < 0) { sprintf(colstr, "1 1 1 1"); return; }
123
124 a = 1 - (mt->transparency).values[mtnum % (mt->transparency).num];
125 em = &mt->emissiveColor.values[3 * (mtnum % mt->emissiveColor.num)];
126 dif = &mt->diffuseColor.values[3 * (mtnum % mt->diffuseColor.num)];
127 if (em[0] != 0.0 || em[1] != 0.0 || em[2] != 0.0) {
128 // Funky calculations to simulate emissive color
129 float r, g, b, ln;
130 r = em[0];
131 g = em[1];
132 b = em[2];
133 ln = (3.0 - sqrt(r*r + g*g + b*b)) / 6.0;
134 r += (1.0 - r)*ln; g += (1.0 - g)*ln; b += (1.0 - b)*ln;
135 sprintf(colstr, "%.3f %.3f %.3f %.3f", r, g, b, a);
136 }
137 else
138 sprintf(colstr, "%.3f %.3f %.3f %.3f", dif[0], dif[1], dif[2], a);
139
140 }
141
142 static void
OOGLappearance(QvMaterial * mt)143 OOGLappearance(QvMaterial *mt)
144 {
145
146 if (mt == NULL) return;
147
148 OOGLout("appearance { material {");
149 sprintf(out, "ambient %f %f %f", (mt->ambientColor).values[0],
150 (mt->ambientColor).values[1], (mt->ambientColor).values[2]);
151 OOGLout(out);
152
153 float r, g, b, ln;
154
155 if (!((mt->emissiveColor).values[0]==0.0 &&
156 (mt->emissiveColor).values[1]==0.0 &&
157 (mt->emissiveColor).values[2]==0.0))
158 {
159 // Funky calculations to simulate emissive color
160 r = (mt->emissiveColor).values[0];
161 g = (mt->emissiveColor).values[1];
162 b = (mt->emissiveColor).values[2];
163 ln = (3.0 - sqrt(r*r + g*g + b*b)) / 6.0;
164 r += (1.0 - r)*ln; g += (1.0 - g)*ln; b += (1.0 - b)*ln;
165 }
166 else {
167 r = mt->diffuseColor.values[0];
168 g = mt->diffuseColor.values[1];
169 b = mt->diffuseColor.values[2];
170 }
171 sprintf(out, "diffuse %.3f %.3f %.3f edgecolor %.3f %.3f %.3f", r, g, b, r, g, b);
172 OOGLout(out);
173
174 sprintf(out, "specular %.3f %.3f %.3f", (mt->specularColor).values[0],
175 (mt->specularColor).values[1], (mt->specularColor).values[2]);
176 OOGLout(out);
177 sprintf(out, "shininess %.3f", (mt->shininess).values[0]);
178 OOGLout(out);
179 sprintf(out, "alpha %.3f", 1.0 - (mt->transparency).values[0]);
180 OOGLout(out);
181 // Doesn't work with Geomview right now
182 // sprintf(out, "emission %f %f %f", (mt->emissiveColor).values[0],
183 // (mt->emissiveColor).values[1], (mt->emissiveColor).values[2]);
184
185 OOGLout(out);
186 OOGLout("}}");
187 }
188
189 #define DEFAULT_TRAVERSE(className) \
190 void \
191 className::ToWebOOGL(QvState *) \
192 { \
193 ANNOUNCE(className); \
194 }
195
196 //////////////////////////////////////////////////////////////////////////////
197 //
198 // Groups.
199 //
200 //////////////////////////////////////////////////////////////////////////////
201
202 void
ToWebOOGL(QvState * state)203 QvGroup::ToWebOOGL(QvState *state)
204 {
205 int savedepth, i;
206
207 ANNOUNCE(QvGroup);
208 OOGLout("{ = LIST");
209 OOGLout("# Group");
210
211 savedepth = oogldepth;
212
213 indent++;
214 for (i = 0; i < getNumChildren(); i++)
215 getChild(i)->ToWebOOGL(state);
216 indent--;
217
218 savedepth = oogldepth - savedepth; /* How deep did we get ? :-)*/
219
220 for (i = 0; i < savedepth; i++) { /* Do the equivalent OOGL pop */
221 out[i*2] = '}'; /* pop the LIST */
222 out[i*2+1] = '}'; /* pop the INST */
223 }
224
225 out[savedepth*2] = '\0';
226 OOGLout(out);
227 OOGLout("} # End Group");
228 oogldepth = oogldepth - savedepth;
229 }
230
231 void
ToWebOOGL(QvState * state)232 QvLOD::ToWebOOGL(QvState *state)
233 {
234 int savedepth, i;
235
236 ANNOUNCE(QvLOD);
237 savedepth = oogldepth;
238
239 indent++;
240
241 // ??? In a real implementation, this would choose a child based
242 // ??? on the projected screen areas.
243 // WebOOGL punts on this one
244
245 if (getNumChildren() > 0)
246 getChild(0)->ToWebOOGL(state);
247
248 indent--;
249
250 savedepth = oogldepth - savedepth; /* How deep did we get ? :-) */
251
252 for (i = 0; i < savedepth; i++) { /* Do the equivalent OOGL pop */
253 out[i*2] = '}'; /* pop the LIST */
254 out[i*2+1] = '}'; /* pop the INST */
255 }
256
257 out[savedepth*2] = '\0';
258 OOGLout(out);
259 oogldepth = oogldepth - savedepth;
260 }
261
262 void
ToWebOOGL(QvState * state)263 QvSeparator::ToWebOOGL(QvState *state)
264 {
265 int savedepth, i;
266
267 ANNOUNCE(QvSeparator);
268
269 OOGLout("{ = LIST # Separator");
270 savedepth = oogldepth;
271
272 state->push();
273 indent++;
274 for (i = 0; i < getNumChildren(); i++)
275 getChild(i)->ToWebOOGL(state);
276 indent--;
277 state->pop();
278
279 savedepth = oogldepth - savedepth; /* How deep did we get ? :-)*/
280
281 for (i = 0; i < savedepth; i++) { /* Do the equivalent OOGL pop */
282 out[i*2] = '}'; /* pop the LIST */
283 out[i*2+1] = '}'; /* pop the INST */
284 }
285 out[savedepth*2] = '\0';
286 OOGLout(out);
287 OOGLout("} # End Separator");
288 oogldepth = oogldepth - savedepth;
289 }
290
291 void
ToWebOOGL(QvState * state)292 QvSwitch::ToWebOOGL(QvState *state)
293 {
294 int savedepth, i;
295
296
297 ANNOUNCE(QvSwitch);
298 indent++;
299
300 int which = (int) whichChild.value;
301
302 savedepth = oogldepth;
303
304 if (which == QV_SWITCH_NONE)
305 ;
306
307 else if (which == QV_SWITCH_ALL)
308 for (i = 0; i < getNumChildren(); i++)
309 getChild(i)->ToWebOOGL(state);
310
311 else
312 if (which < getNumChildren())
313 getChild(which)->ToWebOOGL(state);
314
315 indent--;
316 savedepth = oogldepth - savedepth; /* How deep did we get ? :-)*/
317
318 for (i = 0; i < savedepth; i++) { /* Do the equivalent OOGL pop */
319 out[i*2] = '}'; /* pop the LIST */
320 out[i*2+1] = '}'; /* pop the INST */
321 }
322 out[savedepth*2] = '\0';
323 OOGLout(out);
324 oogldepth = oogldepth - savedepth;
325 }
326
327 void
ToWebOOGL(QvState * state)328 QvTransformSeparator::ToWebOOGL(QvState *state)
329 {
330 int savedepth, i;
331
332 ANNOUNCE(QvTransformSeparator);
333
334 // We need to "push" just the transformation stack. We'll
335 // accomplish this by just pushing a no-op transformation onto
336 // that stack. When we "pop", we'll restore that stack to its
337 // previous state.
338
339 QvElement *markerElt = new QvElement;
340 markerElt->data = this;
341 markerElt->type = QvElement::NoOpTransform;
342 state->addElement(QvState::TransformationIndex, markerElt);
343
344 savedepth = oogldepth;
345
346 indent++;
347 for (i = 0; i < getNumChildren(); i++)
348 getChild(i)->ToWebOOGL(state);
349 indent--;
350
351 // Now do the "pop"
352 while (state->getTopElement(QvState::TransformationIndex) != markerElt)
353 state->popElement(QvState::TransformationIndex);
354
355 savedepth = oogldepth - savedepth; /* How deep did we get ? :-)*/
356
357 for (i = 0; i < savedepth; i++) { /* Do the equivalent OOGL pop */
358 out[i*2] = '}'; /* pop the LIST */
359 out[i*2+1] = '}'; /* pop the INST */
360 }
361 out[savedepth*2] = '\0';
362 OOGLout(out);
363 oogldepth = oogldepth - savedepth;
364 }
365
366 //////////////////////////////////////////////////////////////////////////////
367 //
368 // Properties.
369 //
370 //////////////////////////////////////////////////////////////////////////////
371
372 void
ToWebOOGL(QvState * state)373 QvMaterial::ToWebOOGL(QvState *state)
374 {
375 oogldepth++;
376 ANNOUNCE(QvMaterial);
377 QvElement *elt = new QvElement;
378 elt->data = this;
379 state->addElement(QvState::MaterialIndex, elt);
380 OOGLout("{ = INST");
381 OOGLout("geom {");
382 OOGLappearance(this);
383 OOGLout("= LIST");
384 }
385
386 #define DO_PROPERTY(className, stackIndex) \
387 void \
388 className::ToWebOOGL(QvState *state) \
389 { \
390 ANNOUNCE(className); \
391 QvElement *elt = new QvElement; \
392 elt->data = this; \
393 state->addElement(QvState::stackIndex, elt); \
394 }
395
DO_PROPERTY(QvCoordinate3,Coordinate3Index)396 DO_PROPERTY(QvCoordinate3, Coordinate3Index)
397 DO_PROPERTY(QvMaterialBinding, MaterialBindingIndex)
398 DO_PROPERTY(QvNormal, NormalIndex)
399 DO_PROPERTY(QvNormalBinding, NormalBindingIndex)
400 DO_PROPERTY(QvShapeHints, ShapeHintsIndex)
401 DO_PROPERTY(QvFontStyle, FontStyleIndex)
402
403 // WebOOGL punts on these ... (no support for texture mapping)
404 DO_PROPERTY(QvTextureCoordinate2, TextureCoordinate2Index)
405 DO_PROPERTY(QvTexture2, Texture2Index)
406 DO_PROPERTY(QvTexture2Transform, Texture2TransformationIndex)
407
408
409 #define DO_TYPED_PROPERTY(className, stackIndex, eltType) \
410 void \
411 className::ToWebOOGL(QvState *state) \
412 { \
413 ANNOUNCE(className); \
414 QvElement *elt = new QvElement; \
415 elt->data = this; \
416 elt->type = QvElement::eltType; \
417 state->addElement(QvState::stackIndex, elt); \
418 }
419
420 void
421 QvMatrixTransform::ToWebOOGL(QvState *state)
422 {
423 oogldepth++;
424 ANNOUNCE(QvMatrixTransform);
425 QvElement *elt = new QvElement;
426 elt->data = this;
427 elt->type = QvElement::MatrixTransform;
428 state->addElement(QvState::TransformationIndex, elt);
429 OOGLout("{ = INST");
430 OOGLout("transform {");
431 sprintf(out, "%f %f %f %f", matrix.value[0][0], matrix.value[0][1],
432 matrix.value[0][2], matrix.value[0][3]);
433 OOGLout(out);
434 sprintf(out, "%f %f %f %f", matrix.value[1][0], matrix.value[1][1],
435 matrix.value[1][2], matrix.value[1][3]);
436 OOGLout(out);
437 sprintf(out, "%f %f %f %f", matrix.value[2][0], matrix.value[2][1],
438 matrix.value[2][2], matrix.value[2][3]);
439 OOGLout(out);
440 sprintf(out, "%f %f %f %f", matrix.value[3][0], matrix.value[3][1],
441 matrix.value[3][2], matrix.value[3][3]);
442 OOGLout(out);
443 OOGLout("} geom");
444 OOGLout("{ = LIST");
445 }
446
OOGLoutmat(QvSFMatrix * mat1)447 static void OOGLoutmat(QvSFMatrix *mat1)
448 {
449 int y;
450
451 for (y = 0; y < 4; y++) {
452 sprintf(out, "%f %f %f %f", mat1->value[0][y], mat1->value[1][y],
453 mat1->value[2][y], mat1->value[3][y]);
454 OOGLout(out);
455 }
456 }
457
OOGLmat_init(QvSFMatrix * mat1)458 static void OOGLmat_init(QvSFMatrix *mat1)
459 {
460 int x, y;
461
462 for (x = 0; x < 4; x++)
463 for (y = 0; y < 4; y++) {
464 if (x == y)
465 mat1->value[x][y] = 1.0;
466 else
467 mat1->value[x][y] = 0.0;
468 }
469 }
470
OOGLmat_mult(QvSFMatrix * mat1,QvSFMatrix * mat2,QvSFMatrix * result)471 static void OOGLmat_mult(QvSFMatrix *mat1, QvSFMatrix *mat2,
472 QvSFMatrix *result)
473 {
474 int x,y;
475
476 for (y = 0; y < 4; y++) {
477 for (x = 0; x < 4; x++) {
478 result->value[x][y] = mat1->value[0][y] * mat2->value[x][0]
479 + mat1->value[1][y] * mat2->value[x][1]
480 + mat1->value[2][y] * mat2->value[x][2]
481 + mat1->value[3][y] * mat2->value[x][3];
482
483 }
484 }
485 }
486
OOGLmat_scale(QvSFMatrix * mat1,float xt,float yt,float zt)487 static void OOGLmat_scale(QvSFMatrix *mat1, float xt, float yt, float zt)
488 {
489 int x, y;
490
491 for (x = 0; x < 4; x++)
492 for (y = 0; y < 4; y++) {
493 if (x == y)
494 mat1->value[x][y] = 1.0;
495 else
496 mat1->value[x][y] = 0.0;
497 }
498 mat1->value[0][0] = xt; mat1->value[1][1] = yt; mat1->value[2][2] = zt;
499
500 }
501
OOGLmat_trans(QvSFMatrix * mat1,float xt,float yt,float zt)502 static void OOGLmat_trans(QvSFMatrix *mat1, float xt, float yt, float zt)
503 {
504 int x, y;
505
506 for (x = 0; x < 4; x++)
507 for (y = 0; y < 4; y++) {
508 if (x == y)
509 mat1->value[x][y] = 1.0;
510 else
511 mat1->value[x][y] = 0.0;
512 }
513
514 mat1->value[0][3] = xt;
515 mat1->value[1][3] = yt;
516 mat1->value[2][3] = zt;
517 }
518
OOGLmat_rot(QvSFMatrix * mat1,float angle,float * rotaxis)519 static void OOGLmat_rot(QvSFMatrix *mat1, float angle, float *rotaxis)
520 {
521 float csA, snA, vsA, s;
522 float axis[3];
523
524 OOGLmat_init(mat1);
525 s = rotaxis[0]*rotaxis[0] + rotaxis[1]*rotaxis[1] + rotaxis[2]*rotaxis[2];
526 if(s == 0. || angle == 0.)
527 return;
528
529 s = 1/sqrt(s);
530 axis[0] = rotaxis[0]*s;
531 axis[1] = rotaxis[1]*s;
532 axis[2] = rotaxis[2]*s;
533 csA = cos(angle); snA = -sin(angle); vsA = 1 - csA;
534
535 mat1->value[0][0] = axis[0]*axis[0]*vsA + csA;
536 mat1->value[1][0] = axis[0]*axis[1]*vsA - axis[2]*snA;
537 mat1->value[2][0] = axis[0]*axis[2]*vsA + axis[1]*snA;
538
539 mat1->value[0][1] = axis[1]*axis[0]*vsA + axis[2]*snA;
540 mat1->value[1][1] = axis[1]*axis[1]*vsA + csA;
541 mat1->value[2][1] = axis[1]*axis[2]*vsA - axis[0]*snA;
542
543 mat1->value[0][2] = axis[2]*axis[0]*vsA - axis[1]*snA;
544 mat1->value[1][2] = axis[2]*axis[1]*vsA + axis[0]*snA;
545 mat1->value[2][2] = axis[2]*axis[2]*vsA + csA;
546 }
547
548 void
ToWebOOGL(QvState * state)549 QvTransform::ToWebOOGL(QvState *state) // NOT RIGHT YET
550 {
551 QvSFMatrix mat1, mat2, mat3;
552
553 OOGLmat_init(&mat1); OOGLmat_init(&mat2); OOGLmat_init(&mat3);
554
555 OOGLmat_trans(&mat2, -center.value[0], -center.value[1], -center.value[2]);
556 OOGLmat_mult(&mat1, &mat2, &mat3);
557 OOGLmat_rot(&mat2, scaleOrientation.angle, scaleOrientation.axis);
558 OOGLmat_mult(&mat3, &mat2, &mat1);
559 OOGLmat_scale(&mat2, scaleFactor.value[0], scaleFactor.value[1],
560 scaleFactor.value[2]);
561 OOGLmat_mult(&mat1, &mat2, &mat3);
562 OOGLmat_rot(&mat2, -scaleOrientation.angle, scaleOrientation.axis);
563 OOGLmat_mult(&mat3, &mat2, &mat1);
564 OOGLmat_rot(&mat2, rotation.angle, rotation.axis);
565 OOGLmat_mult(&mat1, &mat2, &mat3);
566 OOGLmat_trans(&mat2, center.value[0], center.value[1], center.value[2]);
567 OOGLmat_mult(&mat3, &mat2, &mat1);
568 OOGLmat_trans(&mat2, translation.value[0], translation.value[1],
569 translation.value[2]);
570 OOGLmat_mult(&mat1, &mat2, &mat3);
571
572 oogldepth++;
573 ANNOUNCE(QvTransform);
574 QvElement *elt = new QvElement;
575 elt->data = this;
576 elt->type = QvElement::Transform;
577 state->addElement(QvState::TransformationIndex, elt);
578 OOGLout("{ = INST");
579 OOGLout("transform {\t# VRML Transform");
580 OOGLoutmat(&mat3);
581 OOGLout("} geom");
582 OOGLout("{ = LIST");
583 }
584
585 void
ToWebOOGL(QvState * state)586 QvRotation::ToWebOOGL(QvState *state)
587 {
588 QvElement *elt = new QvElement;
589 QvSFMatrix mat1;
590
591 oogldepth++;
592 ANNOUNCE(QvRotation);
593
594 OOGLmat_init(&mat1);
595 OOGLmat_rot(&mat1, rotation.angle, rotation.axis);
596
597 elt->data = this;
598 elt->type = QvElement::Rotation;
599 state->addElement(QvState::TransformationIndex, elt);
600
601 OOGLout("{ = INST");
602 OOGLout("transform {");
603 OOGLoutmat(&mat1);
604 OOGLout("} geom");
605 OOGLout("{ = LIST");
606 }
607
608 void
ToWebOOGL(QvState * state)609 QvTranslation::ToWebOOGL(QvState *state)
610 {
611 QvSFMatrix mat1;
612
613 oogldepth++;
614 ANNOUNCE(QvTranslation);
615 QvElement *elt = new QvElement;
616 elt->data = this;
617 elt->type = QvElement::Translation;
618 state->addElement(QvState::TransformationIndex, elt);
619
620 OOGLmat_trans(&mat1, translation.value[0], translation.value[1],
621 translation.value[2]);
622 OOGLout("{ = INST");
623 OOGLout("transform {");
624 OOGLoutmat(&mat1);
625 OOGLout("} geom");
626 OOGLout("{ = LIST");
627 }
628
629 void
ToWebOOGL(QvState * state)630 QvScale::ToWebOOGL(QvState *state)
631 {
632 oogldepth++;
633 ANNOUNCE(QvScale);
634 QvElement *elt = new QvElement;
635 elt->data = this;
636 elt->type = QvElement::Scale;
637 state->addElement(QvState::TransformationIndex, elt);
638 OOGLout("{ = INST");
639 OOGLout("transform {");
640 sprintf(out, "%f 0 0 0", scaleFactor.value[0]);
641 OOGLout(out);
642 sprintf(out, "0 %f 0 0", scaleFactor.value[1]);
643 OOGLout(out);
644 sprintf(out, "0 0 %f 0", scaleFactor.value[2]);
645 OOGLout(out);
646 OOGLout("0 0 0 1");
647 OOGLout("} geom");
648 OOGLout("{ = LIST");
649 }
650
DO_TYPED_PROPERTY(QvDirectionalLight,LightIndex,DirectionalLight)651 DO_TYPED_PROPERTY(QvDirectionalLight, LightIndex, DirectionalLight)
652 DO_TYPED_PROPERTY(QvPointLight, LightIndex, PointLight)
653 DO_TYPED_PROPERTY(QvSpotLight, LightIndex, SpotLight)
654
655 DO_TYPED_PROPERTY(QvOrthographicCamera, CameraIndex, OrthographicCamera)
656 DO_TYPED_PROPERTY(QvPerspectiveCamera, CameraIndex, PerspectiveCamera)
657
658 //////////////////////////////////////////////////////////////////////////////
659 //
660 // Shapes.
661 //
662 //////////////////////////////////////////////////////////////////////////////
663
664 static void
665 OOGLprintProperties(QvState *state)
666 {
667 // printf("--------------------------------------------------------------\n");
668 // state->print();
669 // printf("--------------------------------------------------------------\n");
670 }
671
672 void
ToWebOOGL(QvState * state)673 QvCone::ToWebOOGL(QvState *state)
674 {
675 ANNOUNCE(QvCone);
676 OOGLout("# VRML Cone");
677 OOGLout("{ = BEZ224");
678 if (parts.value == ALL || parts.value == SIDES)
679 {
680 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1", height.value/2.0,
681 height.value/2.0);
682 OOGLout(out);
683 sprintf(out, "%f 0 0 1\t0 0 %f 0\t%f 0 0 1", -bottomRadius.value/2.0,
684 bottomRadius.value/2.0, bottomRadius.value/2.0);
685 OOGLout(out);
686 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1\n", -bottomRadius.value,
687 -height.value/2.0, bottomRadius.value, bottomRadius.value,
688 -height.value/2.0);
689 OOGLout(out);
690
691 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -bottomRadius.value,
692 -height.value/2.0, -bottomRadius.value, bottomRadius.value,
693 -height.value/2.0);
694 OOGLout(out);
695 sprintf(out, "%f 0 0 1\t0 0 %f 0\t%f 0 0 1", -bottomRadius.value/2.0,
696 -bottomRadius.value/2.0, bottomRadius.value/2.0);
697 OOGLout(out);
698 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1\n", height.value/2.0,
699 height.value/2.0);
700 OOGLout(out);
701 }
702 if (parts.value == ALL || parts.value == BOTTOM)
703 {
704 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1", -height.value/2.0,
705 -height.value/2.0);
706 OOGLout(out);
707 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -bottomRadius.value/2.0,
708 -height.value/2.0, bottomRadius.value/2.0,
709 bottomRadius.value/2.0, -height.value/2.0);
710 OOGLout(out);
711 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1\n", -bottomRadius.value,
712 -height.value/2.0, bottomRadius.value, bottomRadius.value,
713 -height.value/2.0);
714 OOGLout(out);
715
716 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -bottomRadius.value,
717 -height.value/2.0, -bottomRadius.value, bottomRadius.value,
718 -height.value/2.0);
719 OOGLout(out);
720 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -bottomRadius.value/2.0,
721 -height.value/2.0, -bottomRadius.value/2.0,
722 bottomRadius.value/2.0, -height.value/2.0);
723 OOGLout(out);
724 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1\n", -height.value/2.0,
725 -height.value/2.0);
726 OOGLout(out);
727 }
728 OOGLout("}");
729 }
730
731 void
ToWebOOGL(QvState * state)732 QvCube::ToWebOOGL(QvState *state)
733 {
734 float x = width.value / 2.0, y = height.value / 2.0, z = depth.value / 2.0;
735 int i;
736
737 ANNOUNCE(QvCube);
738 OOGLout("# VRML Cube");
739 OOGLout("{ = OFF");
740 OOGLout("8 6 12");
741 for(i = 0; i < 8; i++) {
742 sprintf(out, "%g %g %g", i&1 ? -x : x, i&2 ? -y : y, i&4 ? -z : z);
743 OOGLout(out);
744 }
745 OOGLout("4 3 2 1 0");
746 OOGLout("4 4 5 6 7");
747 OOGLout("4 2 3 7 6");
748 OOGLout("4 0 1 5 4");
749 OOGLout("4 0 4 7 3");
750 OOGLout("4 1 2 6 5");
751 OOGLout("}");
752 }
753
754 void
ToWebOOGL(QvState * state)755 QvCylinder::ToWebOOGL(QvState *state)
756 {
757 QvElement *elt = NULL;
758 QvMaterial *qv_material = NULL;
759 QvMaterialBinding *qv_materialb = NULL;
760 Binding mb_val;
761
762 elt = state->getTopElement(QvState::MaterialIndex);
763 if (elt) { qv_material = (QvMaterial *)elt->data;}
764 elt = state->getTopElement(QvState::MaterialBindingIndex);
765 if (elt) { qv_materialb = (QvMaterialBinding *)elt->data; }
766
767 if (qv_materialb) { mb_val = (Binding) qv_materialb->value.value; }
768 else { mb_val = DEFAULT; }
769
770 ANNOUNCE(QvCylinder);
771 OOGLout("# VRML Cylinder");
772 OOGLout("{");
773 if (mb_val != PER_PART && mb_val != PER_PART_INDEXED)
774 {
775 OOGLappearance(qv_material);
776 OOGLout("= BEZ224");
777 } else {
778 OOGLout("= CBEZ224");
779 }
780
781 colstr[0] = '\0';
782 if (parts.value == ALL || parts.value == SIDES)
783 {
784 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value,
785 height.value/2.0, radius.value, radius.value, height.value/2.0);
786 OOGLout(out);
787 sprintf(out, "%f 0 0 1\t0 0 %f 0\t%f 0 0 1", -radius.value,
788 radius.value, radius.value);
789 OOGLout(out);
790 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1\n", -radius.value,
791 -height.value/2.0, radius.value, radius.value, -height.value/2.0);
792 OOGLout(out);
793
794 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value,
795 -height.value/2.0, -radius.value, radius.value, -height.value/2.0);
796 OOGLout(out);
797 sprintf(out, "%f 0 0 1\t0 0 %f 0\t%f 0 0 1", -radius.value,
798 -radius.value, radius.value);
799 OOGLout(out);
800 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value,
801 height.value/2.0, -radius.value, radius.value, height.value/2.0);
802 OOGLout(out);
803
804 if (mb_val == PER_PART || mb_val == PER_PART_INDEXED) {
805 OOGLgetcolor(qv_material, qv_materialb, 0);
806 sprintf(out, "%s %s %s %s\n", colstr, colstr, colstr, colstr);
807 OOGLout(out);
808 }
809
810 }
811 if (parts.value == TOP || parts.value == ALL)
812 {
813 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1", height.value/2.0,
814 height.value/2.0);
815 OOGLout(out);
816 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value/2.0,
817 height.value/2.0, radius.value/2.0,
818 radius.value/2.0, height.value/2.0);
819 OOGLout(out);
820 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1\n", -radius.value,
821 height.value/2.0, radius.value, radius.value, height.value/2.0);
822 OOGLout(out);
823
824 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value,
825 height.value/2.0, -radius.value, radius.value, height.value/2.0);
826 OOGLout(out);
827 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value/2.0,
828 height.value/2.0, -radius.value/2.0,
829 radius.value/2.0, height.value/2.0);
830 OOGLout(out);
831 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1", height.value/2.0,
832 height.value/2.0);
833 OOGLout(out);
834
835 if (mb_val == PER_PART || mb_val == PER_PART_INDEXED) {
836 OOGLgetcolor(qv_material, qv_materialb, 1);
837 sprintf(out, "%s %s %s %s\n", colstr, colstr, colstr, colstr);
838 OOGLout(out);
839 }
840 }
841
842 if (parts.value == BOTTOM || parts.value == ALL)
843 {
844 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1", -height.value/2.0,
845 -height.value/2.0);
846 OOGLout(out);
847 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value/2.0,
848 -height.value/2.0, radius.value/2.0,
849 radius.value/2.0, -height.value/2.0);
850 OOGLout(out);
851 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1\n", -radius.value,
852 -height.value/2.0, radius.value, radius.value, -height.value/2.0);
853 OOGLout(out);
854
855 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value,
856 -height.value/2.0, -radius.value, radius.value, -height.value/2.0);
857 OOGLout(out);
858 sprintf(out, "%f %f 0 1\t0 0 %f 0\t%f %f 0 1", -radius.value/2.0,
859 -height.value/2.0, -radius.value/2.0,
860 radius.value/2.0, -height.value/2.0);
861 OOGLout(out);
862 sprintf(out, "0 %f 0 1\t0 0 0 0\t0 %f 0 1\n", -height.value/2.0,
863 -height.value/2.0);
864 OOGLout(out);
865 if (mb_val == PER_PART || mb_val == PER_PART_INDEXED) {
866 OOGLgetcolor(qv_material, qv_materialb, 2);
867 sprintf(out, "%s %s %s %s\n", colstr, colstr, colstr, colstr);
868 OOGLout(out);
869 }
870
871 }
872
873 OOGLout("}");
874 }
875
876 void
ToWebOOGL(QvState * state)877 QvSphere::ToWebOOGL(QvState *state)
878 {
879 QvElement *elt = NULL;
880 QvMaterial *qv_material = NULL;
881 // QvMaterialBinding *qv_materialb = NULL;
882
883 elt = state->getTopElement(QvState::MaterialIndex);
884 if (elt) { qv_material = (QvMaterial *)elt->data;}
885 elt = state->getTopElement(QvState::MaterialBindingIndex);
886 // if (elt) { qv_materialb = (QvMaterialBinding *)elt->data; }
887
888 ANNOUNCE(QvSphere);
889 OOGLout("# VRML Sphere");
890 OOGLout("{");
891 OOGLappearance(qv_material);
892 OOGLout("= SPHERE");
893 sprintf(out, " %f", radius.value);
894 OOGLout(out);
895 OOGLout(" 0 0 0");
896 OOGLout("}");
897 }
898
899 void
ToWebOOGL(QvState * state)900 QvIndexedFaceSet::ToWebOOGL(QvState *state)
901 {
902 QvElement *elt = NULL;
903 QvCoordinate3 *qv_coord = NULL;
904 QvMaterial *qv_material = NULL;
905 // QvMaterialBinding *qv_materialb = NULL;
906 QvNormal *qv_normal = NULL;
907 QvNormalBinding *qv_normalb = NULL;
908 float *coords;
909 // float *vects;
910 long *firstindex;
911 // Binding mb_val;
912 Binding nb_val;
913 int count, numfaces, bad, numverts, numcoords, numnormals;
914
915 elt = state->getTopElement(QvState::Coordinate3Index);
916 if (elt) { qv_coord = (QvCoordinate3 *)elt->data;}
917 elt = state->getTopElement(QvState::MaterialIndex);
918 if (elt) { qv_material = (QvMaterial *)elt->data;}
919 elt = state->getTopElement(QvState::MaterialBindingIndex);
920 // if (elt) { qv_materialb = (QvMaterialBinding *)elt->data; }
921 elt = state->getTopElement(QvState::NormalIndex);
922 if (elt) { qv_normal = (QvNormal *)elt->data; }
923 elt = state->getTopElement(QvState::NormalBindingIndex);
924 if (elt) { qv_normalb = (QvNormalBinding *)elt->data; }
925
926 // if (qv_materialb) { mb_val = (Binding) qv_materialb->value.value; }
927 // else { mb_val = DEFAULT; }
928 if (qv_normalb) { nb_val = (Binding) qv_normalb->value.value; }
929 else { nb_val = DEFAULT; }
930
931 if (qv_coord) {
932 numcoords = qv_coord->point.num;
933 coords = qv_coord->point.values;
934 } else { numcoords = 0; coords = NULL; }
935 if (qv_normal) {
936 numnormals = qv_normal->vector.num;
937 // vects = qv_normal->vector.values;
938 } else {
939 numnormals = 0;
940 // vects = NULL;
941 }
942 if (qv_material) {
943 }
944
945 firstindex = coordIndex.values;
946 numverts = coordIndex.num,
947
948 ANNOUNCE(QvIndexedFaceSet);
949
950 numfaces = 0; bad = 0;
951 for (count = 0; count < numverts; count++)
952 {
953 if (firstindex[count] < 0 && !bad) { numfaces++; bad = 1; }
954 else bad = 0; /* bad handles case of two consecutive delimeters */
955 if (firstindex[count] > (numcoords - 1)) return;
956 }
957 for (count = 0; count < numnormals; count++) {
958
959 }
960
961 OOGLout("# IndexedFaceSet");
962 if (coords == NULL) { OOGLout("# Bad Values"); return; }
963 if (nb_val) { }
964 OOGLout("{ = OFF");
965 sprintf(out, "%d %d 0\n", numcoords, numfaces);
966 OOGLout(out);
967
968 for (count = 0; count < numcoords; count++)
969 {
970 float x = coords[count*3], y = coords[count*3+1], z = coords[count*3+2];
971 sprintf(out, "%f %f %f", x, y, z);
972 OOGLout(out);
973 }
974 OOGLout("");
975
976 count = 0;
977 while (count < numverts) {
978 int numvts, start;
979 numvts = 0;
980 start = count;
981 while (firstindex[count] > -1 && count < numverts) {
982 count++; numvts++;
983 }
984 if (count > start)
985 {
986 OOGLoutindent();
987 sprintf(out, "%d", numvts);
988 OOGLoutraw(out);
989 for(int i=start;i<count;i++) {
990 sprintf(out, " %ld", firstindex[i]);
991 OOGLoutraw(out);
992 }
993 OOGLoutraw("\n");
994 }
995 count++;
996 }
997 OOGLout("}");
998
999 }
1000
1001 void
ToWebOOGL(QvState * state)1002 QvIndexedLineSet::ToWebOOGL(QvState *state)
1003 {
1004 QvElement *elt = NULL;
1005 QvCoordinate3 *qv_coord = NULL;
1006 QvMaterial *qv_material = NULL;
1007 QvMaterialBinding *qv_materialb = NULL;
1008 float *coords;
1009 long *firstindex, *matindex;
1010 Binding mb_val;
1011 int numvts, points, numsegs;
1012 int count, numlines, numverts, numcoords, nummats;
1013
1014 elt = state->getTopElement(QvState::Coordinate3Index);
1015 if (elt) { qv_coord = (QvCoordinate3 *)elt->data;}
1016 elt = state->getTopElement(QvState::MaterialIndex);
1017 if (elt) { qv_material = (QvMaterial *)elt->data;}
1018 elt = state->getTopElement(QvState::MaterialBindingIndex);
1019 if (elt) { qv_materialb = (QvMaterialBinding *)elt->data; }
1020
1021 if (qv_materialb) { mb_val = (Binding) qv_materialb->value.value; }
1022 else { mb_val = DEFAULT; }
1023
1024 if (qv_coord) {
1025 numcoords = qv_coord->point.num;
1026 coords = qv_coord->point.values;
1027 } else { numcoords = 0; coords = NULL; }
1028
1029 nummats = materialIndex.num;
1030 matindex = materialIndex.values;
1031 firstindex = coordIndex.values;
1032 numverts = coordIndex.num,
1033
1034 ANNOUNCE(QvIndexedLineSet);
1035
1036 count = 0; numlines = 0; numvts = 0; points = 0; numsegs = 0;
1037 while (count < numverts) {
1038 int x;
1039
1040 x = 0;
1041 while (firstindex[count] < 0 && count < numverts) count++;
1042 while (firstindex[count] > -1 && count < numverts) {
1043 count++; x++;
1044 }
1045 if (x == 1) {
1046 numvts++; numlines++; points++;
1047 } else if (x > 1) {
1048 numvts += x; numlines++; numsegs += x - 1;
1049 }
1050 }
1051
1052 OOGLout("# IndexedLineSet");
1053 if (coords == NULL || numvts < 1 || numlines < 1) {
1054 OOGLout("# Bad Values");
1055 return;
1056 }
1057
1058 OOGLout("{ = VECT");
1059 if (mb_val == DEFAULT || mb_val == OVERALL) {
1060 sprintf(out, "%d %d 1\n", numlines, numvts);
1061 } else if (mb_val == PER_FACE || mb_val == PER_FACE_INDEXED) {
1062 sprintf(out, "%d %d %d\n", numlines, numvts, numlines);
1063 } else if (mb_val == PER_PART || mb_val == PER_PART_INDEXED) {
1064 sprintf(out, "%d %d %d\n", numsegs + points, numvts, numsegs + points);
1065 } else if (mb_val == PER_VERTEX || mb_val == PER_VERTEX_INDEXED) {
1066 sprintf(out, "%d %d %d\n", numlines, numvts, numvts);
1067 }
1068 OOGLout(out);
1069
1070 /* number of vertices in each poly line */
1071
1072 OOGLoutindent();
1073 count = 0;
1074 while (count < numverts) {
1075 int x;
1076
1077 x = 0;
1078 while (firstindex[count] < 0 && count < numverts) count++;
1079 while (firstindex[count] > -1 && count < numverts) {
1080 count++; x++;
1081 }
1082 if (mb_val == PER_PART || mb_val == PER_PART_INDEXED) {
1083 /* Here, we divide our poly lines into segments... */
1084 if (x == 1) {
1085 sprintf(out,"1 ");
1086 OOGLoutraw(out);
1087 } else if (x > 1) {
1088 while (x > 1) {
1089 sprintf(out,"2 ");
1090 OOGLoutraw(out);
1091 x--;
1092 }
1093 sprintf(out,"%d ", x - 1);
1094 OOGLoutraw(out);
1095 }
1096 } else if (x > 0) {
1097 sprintf(out,"%d ", x);
1098 OOGLoutraw(out);
1099 }
1100 }
1101 OOGLoutraw("\n");
1102
1103 /* number of colors in each poly line */
1104
1105 OOGLoutindent();
1106 if (mb_val == DEFAULT || mb_val == OVERALL) {
1107 count = 1;
1108 OOGLoutraw("1 ");
1109 while (count < numlines) {
1110 sprintf(out,"0 ");
1111 OOGLoutraw(out);
1112 count++;
1113 }
1114 OOGLoutraw("\n");
1115 } else if (mb_val == PER_FACE || mb_val == PER_FACE_INDEXED) {
1116 count = 0;
1117 while (count < numlines) {
1118 OOGLoutraw("1 "); count++;
1119 }
1120 } else if (mb_val == PER_PART || mb_val == PER_PART_INDEXED) {
1121 count = 0;
1122 while (count < (numsegs + points)) {
1123 OOGLoutraw("1 "); count++;
1124 }
1125 } else if (mb_val == PER_VERTEX || mb_val == PER_VERTEX_INDEXED) {
1126 count = 0;
1127 while (count < numverts) {
1128 int x;
1129
1130 x = 0;
1131 while (firstindex[count] < 0 && count < numverts) count++;
1132 while (firstindex[count] > -1 && count < numverts) {
1133 count++; x++;
1134 }
1135 if (x > 0) {
1136 sprintf(out,"%d ", x);
1137 OOGLoutraw(out);
1138 }
1139 }
1140 }
1141 OOGLout("");
1142
1143 count = 0;
1144 while (count < numverts) {
1145 long num;
1146
1147 while (firstindex[count] < 0 && count < numverts) count++;
1148 while (firstindex[count] > -1 && count < numverts) {
1149 float x, y, z;
1150
1151 num = firstindex[count]; count++;
1152 if (num > -1 && num < numcoords) {
1153 x = coords[num * 3];
1154 y = coords[num * 3 + 1];
1155 z = coords[num * 3 + 2];
1156 sprintf(out,"%f %f %f", x, y, z);
1157 OOGLout(out);
1158 } else sprintf(out,"%f %f %f", x, y, z);
1159 }
1160 }
1161 OOGLout("");
1162
1163 OOGLoutindent();
1164 if (mb_val == DEFAULT || mb_val == OVERALL) {
1165 OOGLgetcolor(qv_material, qv_materialb, 0);
1166 OOGLout(colstr);
1167 } else if (mb_val == PER_FACE || mb_val == PER_PART ||
1168 mb_val == PER_VERTEX) {
1169 int numpieces;
1170
1171 if (mb_val == PER_FACE) numpieces = numlines;
1172 else if (mb_val == PER_PART) numpieces = numsegs + points;
1173 else if (mb_val == PER_VERTEX) numpieces = numvts;
1174
1175 count = 0;
1176 while (count < numpieces) {
1177 OOGLgetcolor(qv_material, qv_materialb, count);
1178 OOGLout(colstr);
1179 count++;
1180 }
1181 } else if (mb_val == PER_FACE_INDEXED || mb_val == PER_PART_INDEXED ||
1182 mb_val == PER_VERTEX_INDEXED) {
1183 int numpieces, x;
1184
1185 if (mb_val == PER_FACE_INDEXED) numpieces = numlines;
1186 else if (mb_val == PER_PART_INDEXED) numpieces = numsegs + points;
1187 else if (mb_val == PER_VERTEX_INDEXED) numpieces = numvts;
1188
1189 count = 0; x = 0;
1190 while (count < numpieces) {
1191 int num;
1192
1193 if (nummats > 0) {
1194 num = (int) matindex[x % nummats];
1195 if (num >= 0) {
1196 OOGLgetcolor(qv_material, qv_materialb, num);
1197 OOGLout(colstr);
1198 count++; x++;
1199 } else x++;
1200 } else {
1201 OOGLgetcolor(qv_material, qv_materialb, 0);
1202 OOGLout(colstr); count++;
1203 }
1204 }
1205 }
1206 OOGLout("}");
1207
1208 }
1209
1210 void
ToWebOOGL(QvState * state)1211 QvPointSet::ToWebOOGL(QvState *state)
1212 {
1213 QvElement *elt = NULL;
1214 QvCoordinate3 *qv_coord = NULL;
1215 QvMaterial *qv_material = NULL;
1216 QvMaterialBinding *qv_materialb = NULL;
1217 float *coords;
1218 // Binding mb_val;
1219 int count, numcoords;
1220 long numverts;
1221
1222 elt = state->getTopElement(QvState::Coordinate3Index);
1223 if (elt) { qv_coord = (QvCoordinate3 *)elt->data;}
1224 elt = state->getTopElement(QvState::MaterialIndex);
1225 if (elt) { qv_material = (QvMaterial *)elt->data;}
1226 elt = state->getTopElement(QvState::MaterialBindingIndex);
1227 if (elt) { qv_materialb = (QvMaterialBinding *)elt->data; }
1228
1229 // if (qv_materialb) { mb_val = (Binding) qv_materialb->value.value; }
1230 // else { mb_val = DEFAULT; }
1231
1232 if (qv_coord) {
1233 numcoords = qv_coord->point.num;
1234 coords = qv_coord->point.values;
1235 } else { numcoords = 0; coords = NULL; }
1236
1237 if (qv_material) {
1238 }
1239
1240 if (startIndex.value > numcoords) {
1241 OOGLout("# Bad Values");
1242 return;
1243 }
1244
1245 if (numPoints.value == (-1)) {
1246 numverts = numcoords - startIndex.value;
1247 } else if ((numPoints.value - startIndex.value) > numcoords) {
1248 OOGLout("# Bad Values");
1249 return;
1250 } else {
1251 numverts = numPoints.value - startIndex.value;
1252 }
1253
1254 ANNOUNCE(QvPointSet);
1255
1256 OOGLout("# PointSet");
1257 if (coords == NULL) {
1258 OOGLout("# Bad Values");
1259 return;
1260 }
1261 OOGLout("{ = VECT");
1262 sprintf(out, "%ld %ld %ld\n", numverts, numverts, numverts);
1263 OOGLout(out);
1264
1265 /* number of vertices in each poly line */
1266
1267 OOGLoutindent();
1268 for (count = 0; count < numverts; count++) {
1269 OOGLoutraw("1 ");
1270 }
1271 OOGLoutraw("\n");
1272
1273 /* number of colors in each poly line */
1274
1275 OOGLoutindent();
1276 for (count = 0; count < numverts; count++) {
1277 OOGLoutraw("1 ");
1278 }
1279 OOGLoutraw("\n");
1280
1281 for (count = 0; count < numverts; count++)
1282 {
1283 float x = coords[(count+startIndex.value)*3],
1284 y = coords[(count+startIndex.value)*3+1],
1285 z = coords[(count+startIndex.value)*3+2];
1286
1287 sprintf(out, "%f %f %f", x, y, z);
1288 OOGLout(out);
1289 }
1290 OOGLout("");
1291
1292 for (count = 0; count < numverts; count++) {
1293 OOGLgetcolor(qv_material, qv_materialb, count);
1294 OOGLout(colstr);
1295 }
1296 OOGLout("}");
1297
1298 }
1299
knowngsfont(char * str)1300 static int knowngsfont(char *str)
1301 {
1302 if(str == NULL)
1303 return 0;
1304 if(access(str, 0) >= 0)
1305 return 1;
1306
1307 char buf[2048];
1308 const char *p, *tail;
1309 const char *gsfontpath = getenv("GS_FONTPATH");
1310
1311 if(gsfontpath == NULL)
1312 gsfontpath = "/usr/local/lib/ghostscript/fonts";
1313 for(p = tail = gsfontpath; tail && *p != '\0'; p = tail+1) {
1314 tail = strchr(p, ':');
1315 int len = tail ? tail - p : strlen(p);
1316 if(len > 1024) len = 1024;
1317 memcpy(buf, p, len);
1318 buf[len] = '/';
1319 strncpy(buf+len+1, str, 2046-len);
1320 if(access(buf, 0) >= 0)
1321 return 1;
1322 }
1323 return 0;
1324 }
1325
ToWebOOGL(QvState * state)1326 void QvAsciiText::ToWebOOGL(QvState *state)
1327 {
1328
1329 float fontsize = 1.0;
1330 // float linespace = 1.0;
1331 char *font = NULL;
1332 // int bold = 0, italic = 0;
1333
1334 QvElement *elt = state->getTopElement(QvState::FontStyleIndex);
1335 if(elt && elt->data) {
1336 QvFontStyle *fs = (QvFontStyle *)elt->data;
1337 fontsize = fs->size.value;
1338 // if(fs->style.value & (1<<QvFontStyle::BOLD))
1339 // bold = 1;
1340 switch(fs->family.value) {
1341 case QvFontStyle::SERIF: font = "hrpl_t.gsf"; break;
1342 case QvFontStyle::TYPEWRITER: /* sorry, can't do that now */ break;
1343 }
1344 }
1345
1346 int i, c;
1347 float y = 0;
1348 char buf[2048], *q;
1349 const char *p;
1350 char *just = "sw";
1351 FILE *f;
1352
1353 switch(justification.value) {
1354 case QvAsciiText::LEFT: just = "sw"; break;
1355 case QvAsciiText::RIGHT: just = "se"; break;
1356 case QvAsciiText::CENTER: just = "s"; break;
1357 }
1358 OOGLout(string.num > 1 ? "{ = LIST # VRML AsciiText" : "# VRML AsciiText");
1359 for(i = 0; i < string.num; i++) {
1360 float wid = width.values[ (i<width.num) ? i : width.num-1 ];
1361 sprintf(buf, "hvectext -s %g -align %s -plane xy -at 0 %g 0 ",
1362 fontsize, just, y);
1363 if(wid > 0)
1364 sprintf(buf + strlen(buf), "-w %g ", wid);
1365 if(font && knowngsfont(font))
1366 sprintf(buf + strlen(buf), "-hershey %s ", font);
1367
1368 q = buf + strlen(buf);
1369 *q++ = '\'';
1370 for(p = string.values[i].getString(); p && *p != '\0' && q < &buf[2048-3]; ) {
1371 if(*p == '\'' || *p == '\\') *q++ = '\\';
1372 *q++ = *p++;
1373 }
1374 *q++ = '\'';
1375 *q = '\0';
1376 f = popen(buf, "r");
1377 for(q = buf; (c = getc(f)) != EOF; ) {
1378 if(c == '\n') {
1379 *q = '\0';
1380 OOGLout(buf);
1381 q = buf;
1382 } else {
1383 *q++ = c;
1384 }
1385 }
1386 pclose(f);
1387 y -= spacing.value * fontsize;
1388 }
1389 if(string.num > 1)
1390 OOGLout("} # End AsciiText");
1391 }
1392
1393 //////////////////////////////////////////////////////////////////////////////
1394 //
1395 // WWW-specific nodes.
1396 //
1397 //////////////////////////////////////////////////////////////////////////////
1398
1399 void
ToWebOOGL(QvState *)1400 QvWWWInline::ToWebOOGL(QvState *)
1401 {
1402 int notuniq = 0;
1403 int i;
1404
1405 ANNOUNCE(QvWWWInline);
1406
1407 if (OOGLhand) {
1408 sprintf(out, "{ : %s }", name.value.getString());
1409 for (i = 0; i < unique && !notuniq; i++) {
1410 if (!strcmp(urls[i], name.value.getString())) notuniq = 1;
1411 }
1412 if (!notuniq) {
1413 urls[unique++] = (char *)name.value.getString();
1414 }
1415 } else {
1416 sprintf(out, "{ COMMENT url.%d WWWInline { \"%s\" }}",
1417 unique++, name.value.getString());
1418 }
1419 OOGLout(out);
1420 }
1421
1422 void
ToWebOOGL(QvState * state)1423 QvWWWAnchor::ToWebOOGL(QvState *state)
1424 {
1425 int savedepth, i;
1426
1427 ANNOUNCE(QvWWWAnchor);
1428
1429 OOGLout("{ = LIST # Anchor");
1430 OOGLoutindent();
1431 OOGLoutraw("{ COMMENT ");
1432 sprintf(out, "wwwanchor.%d HREF { \"%s\" } }\n", mypid,
1433 name.value.getString());
1434 OOGLoutraw(out);
1435
1436 savedepth = oogldepth;
1437
1438 indent++;
1439 for (i = 0; i < getNumChildren(); i++)
1440 getChild(i)->ToWebOOGL(state);
1441 indent--;
1442
1443 savedepth = oogldepth - savedepth; /* How deep did we get ? :-)*/
1444
1445 for (i = 0; i < savedepth; i++) { /* Do the equivalent OOGL pop */
1446 out[i*2] = '}'; /* pop the LIST */
1447 out[i*2+1] = '}'; /* pop the INST */
1448 }
1449
1450 out[savedepth*2] = '\0';
1451 OOGLout(out);
1452 OOGLout("} # End Anchor");
1453 oogldepth = oogldepth - savedepth;
1454
1455 }
1456
1457 //////////////////////////////////////////////////////////////////////////////
1458 //
1459 // Default traversal methods. These nodes have no effects during traversal.
1460 //
1461 //////////////////////////////////////////////////////////////////////////////
1462
1463 DEFAULT_TRAVERSE(QvInfo)
1464 DEFAULT_TRAVERSE(QvUnknownNode)
1465
1466 //////////////////////////////////////////////////////////////////////////////
1467
1468 #undef ANNOUNCE
1469 #undef DEFAULT_TRAVERSE
1470 #undef DO_PROPERTY
1471 #undef DO_SHAPE
1472 #undef DO_TYPED_PROPERTY
1473