00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <math.h>
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include "X3DDisplayDevice.h"
00039 #include "Matrix4.h"
00040 #include "utilities.h"
00041 #include "DispCmds.h"
00042 #include "Hershey.h"
00043
00044
00045
00046 #define DEFAULT_RADIUS 0.002f
00047 #define DASH_LENGTH 0.02f
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00060
00062 X3DDisplayDevice::X3DDisplayDevice(
00063 const char *public_name,
00064 const char *public_pretty_name,
00065 const char *default_file_name,
00066 const char *default_command_line) :
00067 FileRenderer(public_name, public_pretty_name,
00068 default_file_name, default_command_line) {
00069 }
00070
00071
00072 X3DDisplayDevice::X3DDisplayDevice(void) :
00073 FileRenderer("X3D", "X3D (XML) full specification", "vmdscene.x3d", "true") {
00074 }
00075
00077 void X3DDisplayDevice::set_color(int mycolorIndex) {
00078 #if 0
00079 write_cindexmaterial(mycolorIndex, materialIndex);
00080 #endif
00081 }
00082
00083
00084 void X3DDisplayDevice::text(float *pos, float size, float thickness,
00085 const char *str) {
00086 float textpos[3];
00087 float textsize;
00088 hersheyhandle hh;
00089
00090
00091 (transMat.top()).multpoint3d(pos, textpos);
00092 textsize = size * 1.5f;
00093
00094 ResizeArray<int> idxs;
00095 ResizeArray<float> pnts;
00096 idxs.clear();
00097 pnts.clear();
00098
00099 int idx=0;
00100 while (*str != '\0') {
00101 float lm, rm, x, y;
00102 int draw;
00103 x=y=0.0f;
00104 draw=0;
00105
00106 hersheyDrawInitLetter(&hh, *str, &lm, &rm);
00107 textpos[0] -= lm * textsize;
00108
00109 while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
00110 float pt[3];
00111
00112 if (draw) {
00113
00114 idxs.append(idx);
00115
00116 pt[0] = textpos[0] + textsize * x;
00117 pt[1] = textpos[1] + textsize * y;
00118 pt[2] = textpos[2];
00119
00120 pnts.append(pt[0]);
00121 pnts.append(pt[1]);
00122 pnts.append(pt[2]);
00123
00124 idx++;
00125 } else {
00126 idxs.append(-1);
00127 }
00128 }
00129 idxs.append(-1);
00130 textpos[0] += rm * textsize;
00131 str++;
00132 }
00133
00134 fprintf(outfile, "<Shape>\n");
00135 fprintf(outfile, " ");
00136
00137
00138
00139
00140 fprintf(outfile, "<Appearance><Material ");
00141 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00142 fprintf(outfile, "diffuseColor='0 0 0' ");
00143
00144 const float *rgb = matData[colorIndex];
00145 fprintf(outfile, "emissiveColor='%g %g %g' ",
00146 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00147 fprintf(outfile, "/>");
00148
00149
00150 if (thickness < 0.99f || thickness > 1.01f) {
00151 fprintf(outfile, " <LineProperties linewidthScaleFactor=\"%g\" "
00152 "containerField=\"lineProperties\"/>\n",
00153 (double) thickness);
00154 }
00155 fprintf(outfile, "</Appearance>\n");
00156
00157
00158
00159
00160 fprintf(outfile, " <IndexedLineSet coordIndex='");
00161 int i, cnt;
00162 cnt = idxs.num();
00163 for (i=0; i<cnt; i++) {
00164 fprintf(outfile, "%d ", idxs[i]);
00165 }
00166 fprintf(outfile, "'>\n");
00167
00168 fprintf(outfile, " <Coordinate point='");
00169 cnt = pnts.num();
00170 for (i=0; i<cnt; i+=3) {
00171 fprintf(outfile, "%c%g %g %g",
00172 (i==0) ? ' ' : ',',
00173 pnts[i], pnts[i+1], pnts[i+2]);
00174 }
00175 fprintf(outfile, "'/>\n");
00176 fprintf(outfile, " </IndexedLineSet>\n");
00177 fprintf(outfile, "</Shape>\n");
00178 }
00179
00180
00181
00182 void X3DDisplayDevice::sphere(float *xyzr) {
00183 float cent[3], radius;
00184
00185
00186 (transMat.top()).multpoint3d(xyzr, cent);
00187 radius = scale_radius(xyzr[3]);
00188
00189 fprintf(outfile, "<Transform translation='%g %g %g'>\n",
00190 cent[0], cent[1], cent[2]);
00191 fprintf(outfile, " <Shape>\n");
00192 fprintf(outfile, " ");
00193 write_cindexmaterial(colorIndex, materialIndex);
00194 fprintf(outfile, " <Sphere radius='%g'/>\n", radius);
00195 fprintf(outfile, " </Shape>\n");
00196 fprintf(outfile, "</Transform>\n");
00197 }
00198
00199
00200
00201 void X3DDisplayDevice::point(float * xyz) {
00202 float txyz[3];
00203
00204
00205 (transMat.top()).multpoint3d(xyz, txyz);
00206
00207
00208 fprintf(outfile, "<Shape>\n");
00209 fprintf(outfile, " ");
00210
00211
00212 fprintf(outfile, "<Appearance><Material ");
00213 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00214 fprintf(outfile, "diffuseColor='0 0 0' ");
00215
00216 const float *rgb = matData[colorIndex];
00217 fprintf(outfile, "emissiveColor='%g %g %g' ",
00218 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00219 fprintf(outfile, "/>");
00220 fprintf(outfile, "</Appearance>\n");
00221
00222 fprintf(outfile, " <PointSet>\n");
00223 fprintf(outfile, " <Coordinate point='%g %g %g'/>\n",
00224 txyz[0], txyz[1], txyz[2]);
00225
00226 float col[3];
00227 vec_copy(col, matData[colorIndex]);
00228 fprintf(outfile, " <Color color='%g %g %g'/>\n",
00229 col[0], col[1], col[2]);
00230 fprintf(outfile, " </PointSet>\n");
00231 fprintf(outfile, "</Shape>\n");
00232 }
00233
00234
00235
00236 void X3DDisplayDevice::point_array(int num, float size,
00237 float *xyz, float *colors) {
00238 float txyz[3];
00239
00240
00241 fprintf(outfile, "<Shape>\n");
00242 fprintf(outfile, " ");
00243
00244
00245 fprintf(outfile, "<Appearance><Material ");
00246 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00247 fprintf(outfile, "diffuseColor='0 0 0' ");
00248 fprintf(outfile, "emissiveColor='1 1 1' ");
00249 fprintf(outfile, "/>");
00250 fprintf(outfile, "</Appearance>\n");
00251
00252 fprintf(outfile, " <PointSet>\n");
00253
00254 int i;
00255 fprintf(outfile, " <Coordinate point='");
00256 for (i=0; i<num; i++) {
00257
00258 (transMat.top()).multpoint3d(&xyz[i*3], txyz);
00259 fprintf(outfile, "%c %g %g %g",
00260 (i==0) ? ' ' : ',',
00261 txyz[0], txyz[1], txyz[2]);
00262 }
00263 fprintf(outfile, "'/>\n");
00264
00265 fprintf(outfile, " <Color color='");
00266 for (i=0; i<num; i++) {
00267 int cind = i*3;
00268 fprintf(outfile, "%c %g %g %g",
00269 (i==0) ? ' ' : ',',
00270 colors[cind], colors[cind+1], colors[cind+2]);
00271 }
00272 fprintf(outfile, "'/>\n");
00273
00274 fprintf(outfile, " </PointSet>\n");
00275 fprintf(outfile, "</Shape>\n");
00276 }
00277
00278
00280 void X3DDisplayDevice::line(float *a, float*b) {
00281 float ta[3], tb[3];
00282
00283 if (lineStyle == ::SOLIDLINE) {
00284
00285 (transMat.top()).multpoint3d(a, ta);
00286 (transMat.top()).multpoint3d(b, tb);
00287
00288
00289 fprintf(outfile, "<Shape>\n");
00290 fprintf(outfile, " ");
00291 write_cindexmaterial(colorIndex, materialIndex);
00292
00293 fprintf(outfile, " <IndexedLineSet coordIndex='0 1 -1'>\n");
00294 fprintf(outfile, " <Coordinate point='%g %g %g, %g %g %g'/>\n",
00295 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2]);
00296
00297 float col[3];
00298 vec_copy(col, matData[colorIndex]);
00299 fprintf(outfile, " <Color color='%g %g %g, %g %g %g'/>\n",
00300 col[0], col[1], col[2], col[0], col[1], col[2]);
00301 fprintf(outfile, " </IndexedLineSet>\n");
00302 fprintf(outfile, "</Shape>\n");
00303 } else if (lineStyle == ::DASHEDLINE) {
00304 float dirvec[3], unitdirvec[3], tmp1[3], tmp2[3];
00305 int i, j, test;
00306
00307
00308 (transMat.top()).multpoint3d(a, tmp1);
00309 (transMat.top()).multpoint3d(b, tmp2);
00310
00311
00312 vec_sub(dirvec, tmp2, tmp1);
00313 vec_copy(unitdirvec, dirvec);
00314 vec_normalize(unitdirvec);
00315 test = 1;
00316 i = 0;
00317 while (test == 1) {
00318 for (j=0; j<3; j++) {
00319 ta[j] = (float) (tmp1[j] + (2*i )*DASH_LENGTH*unitdirvec[j]);
00320 tb[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00321 }
00322 if (fabsf(tmp1[0] - tb[0]) >= fabsf(dirvec[0])) {
00323 vec_copy(tb, tmp2);
00324 test = 0;
00325 }
00326
00327
00328 fprintf(outfile, "<Shape>\n");
00329 fprintf(outfile, " ");
00330 write_cindexmaterial(colorIndex, materialIndex);
00331
00332 fprintf(outfile, " <IndexedLineSet coordIndex='0 1 -1'>\n");
00333 fprintf(outfile, " <Coordinate point='%g %g %g, %g %g %g'/>\n",
00334 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2]);
00335
00336 float col[3];
00337 vec_copy(col, matData[colorIndex]);
00338 fprintf(outfile, " <Color color='%g %g %g, %g %g %g'/>\n",
00339 col[0], col[1], col[2], col[0], col[1], col[2]);
00340 fprintf(outfile, " </IndexedLineSet>\n");
00341 fprintf(outfile, "</Shape>\n");
00342 i++;
00343 }
00344 } else {
00345 msgErr << "X3DDisplayDevice: Unknown line style "
00346 << lineStyle << sendmsg;
00347 }
00348 }
00349
00350
00351 void X3DDisplayDevice::line_array(int num, float thickness, float *points) {
00352 float *v = points;
00353 float txyz[3];
00354 int i;
00355
00356 fprintf(outfile, "<Shape>\n");
00357 fprintf(outfile, " ");
00358
00359
00360 fprintf(outfile, "<Appearance><Material ");
00361 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00362 fprintf(outfile, "diffuseColor='0 0 0' ");
00363
00364 const float *rgb = matData[colorIndex];
00365 fprintf(outfile, "emissiveColor='%g %g %g' ",
00366 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00367 fprintf(outfile, "/>");
00368
00369
00370 if (thickness < 0.99f || thickness > 1.01f) {
00371 fprintf(outfile, " <LineProperties linewidthScaleFactor=\"%g\" "
00372 "containerField=\"lineProperties\"/>\n",
00373 (double) thickness);
00374 }
00375 fprintf(outfile, "</Appearance>\n");
00376
00377
00378 fprintf(outfile, " <IndexedLineSet coordIndex='");
00379 for (i=0; i<num; i++) {
00380 fprintf(outfile, "%d %d -1 ", i*2, i*2+1);
00381 }
00382 fprintf(outfile, "'>\n");
00383
00384 fprintf(outfile, " <Coordinate point='");
00385
00386 for (i=0; i<(num*2); i++) {
00387
00388 (transMat.top()).multpoint3d(v, txyz);
00389 fprintf(outfile, "%c%g %g %g",
00390 (i==0) ? ' ' : ',',
00391 txyz[0], txyz[1], txyz[2]);
00392 v += 3;
00393 }
00394 fprintf(outfile, "'/>\n");
00395
00396 fprintf(outfile, " </IndexedLineSet>\n");
00397 fprintf(outfile, "</Shape>\n");
00398 }
00399
00400
00401 void X3DDisplayDevice::polyline_array(int num, float thickness, float *points) {
00402 float *v = points;
00403 float txyz[3];
00404
00405 fprintf(outfile, "<Shape>\n");
00406 fprintf(outfile, " ");
00407
00408
00409 fprintf(outfile, "<Appearance><Material ");
00410 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00411 fprintf(outfile, "diffuseColor='0 0 0' ");
00412
00413 const float *rgb = matData[colorIndex];
00414 fprintf(outfile, "emissiveColor='%g %g %g' ",
00415 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00416 fprintf(outfile, "/>");
00417
00418
00419 if (thickness < 0.99f || thickness > 1.01f) {
00420 fprintf(outfile, " <LineProperties linewidthScaleFactor=\"%g\" "
00421 "containerField=\"lineProperties\"/>\n",
00422 (double) thickness);
00423 }
00424 fprintf(outfile, "</Appearance>\n");
00425
00426
00427 fprintf(outfile, " <LineSet vertexCount='%d'>", num);
00428
00429 fprintf(outfile, " <Coordinate point='");
00430 for (int i=0; i<num; i++) {
00431
00432 (transMat.top()).multpoint3d(v, txyz);
00433 fprintf(outfile, "%c%g %g %g",
00434 (i==0) ? ' ' : ',',
00435 txyz[0], txyz[1], txyz[2]);
00436 v += 3;
00437 }
00438 fprintf(outfile, "'/>\n");
00439
00440 fprintf(outfile, " </LineSet>\n");
00441 fprintf(outfile, "</Shape>\n");
00442 }
00443
00444
00445
00446 void X3DDisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00447 float ta[3], tb[3], radius;
00448
00449
00450 (transMat.top()).multpoint3d(a, ta);
00451 (transMat.top()).multpoint3d(b, tb);
00452 radius = scale_radius(r);
00453
00454 cylinder_noxfrm(ta, tb, radius, filled);
00455 }
00456
00457
00458
00459 void X3DDisplayDevice::cylinder_noxfrm(float *ta, float *tb, float radius, int filled) {
00460 if (ta[0] == tb[0] && ta[1] == tb[1] && ta[2] == tb[2]) {
00461 return;
00462 }
00463
00464 float height = distance(ta, tb);
00465
00466 fprintf(outfile, "<Transform translation='%g %g %g' ",
00467 ta[0], ta[1] + (height / 2.0), ta[2]);
00468
00469 float rotaxis[3];
00470 float cylaxdir[3];
00471 float yaxis[3] = {0.0, 1.0, 0.0};
00472
00473 vec_sub(cylaxdir, tb, ta);
00474 vec_normalize(cylaxdir);
00475 float dp = dot_prod(yaxis, cylaxdir);
00476
00477 cross_prod(rotaxis, cylaxdir, yaxis);
00478 vec_normalize(rotaxis);
00479
00480
00481 if ((rotaxis[0]*rotaxis[0] +
00482 rotaxis[1]*rotaxis[1] +
00483 rotaxis[2]*rotaxis[2]) > 0.5) {
00484 fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
00485 fprintf(outfile, "rotation='%g %g %g %g'",
00486 rotaxis[0], rotaxis[1], rotaxis[2], -acosf(dp));
00487 } else if (dp < -0.98) {
00488
00489
00490
00491
00492 fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
00493 fprintf(outfile, "rotation='0 0 -1 -3.14159'");
00494 }
00495 fprintf(outfile, ">\n");
00496
00497 fprintf(outfile, " <Shape>\n");
00498 fprintf(outfile, " ");
00499 write_cindexmaterial(colorIndex, materialIndex);
00500
00501
00502 fprintf(outfile, " <Cylinder "
00503 "bottom='%s' height='%g' radius='%g' side='%s' top='%s' />\n",
00504 filled ? "true" : "false",
00505 height,
00506 radius,
00507 "true",
00508 filled ? "true" : "false");
00509
00510 fprintf(outfile, " </Shape>\n");
00511 fprintf(outfile, "</Transform>\n");
00512 }
00513
00514
00515 void X3DDisplayDevice::cone(float *a, float *b, float r) {
00516 float ta[3], tb[3], radius;
00517
00518 if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
00519 return;
00520 }
00521
00522
00523 (transMat.top()).multpoint3d(a, ta);
00524 (transMat.top()).multpoint3d(b, tb);
00525 radius = scale_radius(r);
00526
00527 float height = distance(a, b);
00528
00529 fprintf(outfile, "<Transform translation='%g %g %g' ",
00530 ta[0], ta[1] + (height / 2.0), ta[2]);
00531
00532 float rotaxis[3];
00533 float cylaxdir[3];
00534 float yaxis[3] = {0.0, 1.0, 0.0};
00535
00536 vec_sub(cylaxdir, tb, ta);
00537 vec_normalize(cylaxdir);
00538 float dp = dot_prod(yaxis, cylaxdir);
00539
00540 cross_prod(rotaxis, cylaxdir, yaxis);
00541 vec_normalize(rotaxis);
00542
00543 if ((rotaxis[0]*rotaxis[0] +
00544 rotaxis[1]*rotaxis[1] +
00545 rotaxis[2]*rotaxis[2]) > 0.5) {
00546 fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
00547 fprintf(outfile, "rotation='%g %g %g %g'",
00548 rotaxis[0], rotaxis[1], rotaxis[2], -acosf(dp));
00549 }
00550 fprintf(outfile, ">\n");
00551
00552 fprintf(outfile, " <Shape>\n");
00553 fprintf(outfile, " ");
00554 write_cindexmaterial(colorIndex, materialIndex);
00555
00556
00557 fprintf(outfile, " <Cone bottomRadius='%g' height='%g'/>\n", radius, height);
00558
00559 fprintf(outfile, " </Shape>\n");
00560 fprintf(outfile, "</Transform>\n");
00561 }
00562
00563
00564
00565 void X3DDisplayDevice::triangle(const float *a, const float *b, const float *c,
00566 const float *n1, const float *n2, const float *n3) {
00567 float ta[3], tb[3], tc[3], tn1[3], tn2[3], tn3[3];
00568
00569
00570 (transMat.top()).multpoint3d(a, ta);
00571 (transMat.top()).multpoint3d(b, tb);
00572 (transMat.top()).multpoint3d(c, tc);
00573
00574
00575 (transMat.top()).multnorm3d(n1, tn1);
00576 (transMat.top()).multnorm3d(n2, tn2);
00577 (transMat.top()).multnorm3d(n3, tn3);
00578
00579 fprintf(outfile, "<Shape>\n");
00580 fprintf(outfile, " ");
00581 write_cindexmaterial(colorIndex, materialIndex);
00582 fprintf(outfile, " <IndexedFaceSet solid='false' coordIndex='0 1 2 -1'>\n");
00583 fprintf(outfile, " <Coordinate point='%g %g %g, %g %g %g, %g %g %g'/>\n",
00584 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2], tc[0], tc[1], tc[2]);
00585
00586 fprintf(outfile, " <Normal vector='%g %g %g, %g %g %g, %g %g %g'/>\n",
00587 tn1[0], tn1[1], tn1[2], tn2[0], tn2[1], tn2[2], tn3[0], tn3[1], tn3[2]);
00588 fprintf(outfile, " </IndexedFaceSet>\n");
00589 fprintf(outfile, "</Shape>\n");
00590 }
00591
00592
00593
00594 void X3DDisplayDevice::tricolor(const float * a, const float * b, const float * c,
00595 const float * n1, const float * n2, const float * n3,
00596 const float *c1, const float *c2, const float *c3) {
00597 float ta[3], tb[3], tc[3], tn1[3], tn2[3], tn3[3];
00598
00599
00600 (transMat.top()).multpoint3d(a, ta);
00601 (transMat.top()).multpoint3d(b, tb);
00602 (transMat.top()).multpoint3d(c, tc);
00603
00604
00605 (transMat.top()).multnorm3d(n1, tn1);
00606 (transMat.top()).multnorm3d(n2, tn2);
00607 (transMat.top()).multnorm3d(n3, tn3);
00608
00609
00610 fprintf(outfile, "<Shape>\n");
00611 fprintf(outfile, " ");
00612 write_cindexmaterial(colorIndex, materialIndex);
00613 fprintf(outfile, " <IndexedFaceSet solid='false' coordIndex='0 1 2 -1'>\n");
00614 fprintf(outfile, " <Coordinate point='%g %g %g, %g %g %g, %g %g %g'/>\n",
00615 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2], tc[0], tc[1], tc[2]);
00616
00617 fprintf(outfile, " <Normal vector='%g %g %g, %g %g %g, %g %g %g'/>\n",
00618 tn1[0], tn1[1], tn1[2], tn2[0], tn2[1], tn2[2], tn3[0], tn3[1], tn3[2]);
00619 fprintf(outfile, " <Color color='%g %g %g, %g %g %g, %g %g %g'/>\n",
00620 c1[0], c1[1], c1[2], c2[0], c2[1], c2[2], c3[0], c3[1], c3[2]);
00621 fprintf(outfile, " </IndexedFaceSet>\n");
00622 fprintf(outfile, "</Shape>\n");
00623 }
00624
00625
00626
00627
00628 void X3DDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00629 int numfacets, int * facets) {
00630 int i;
00631
00632 fprintf(outfile, "<Shape>\n");
00633 fprintf(outfile, " ");
00634 write_cindexmaterial(colorIndex, materialIndex);
00635
00636
00637 fprintf(outfile, " <IndexedTriangleSet solid='false' index='");
00638 for (i=0; i<numfacets*3; i+=3) {
00639 fprintf(outfile, "%d %d %d ", facets[i], facets[i+1], facets[i+2]);
00640 }
00641 fprintf(outfile, "'>\n");
00642
00643
00644 fprintf(outfile, " <Coordinate point='");
00645 for (i=0; i<numverts; i++) {
00646 const float *v = cnv + i*10 + 7;
00647 float tv[3];
00648 (transMat.top()).multpoint3d(v, tv);
00649 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
00650 }
00651 fprintf(outfile, "'/>\n");
00652
00653
00654 fprintf(outfile, " <Color color='");
00655 for (i=0; i<numverts; i++) {
00656 const float *c = cnv + i*10;
00657 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
00658 }
00659 fprintf(outfile, "'/>\n");
00660
00661
00662 fprintf(outfile, " <Normal vector='");
00663 for (i=0; i<numverts; i++) {
00664 const float *n = cnv + i*10 + 4;
00665 float tn[3];
00666 (transMat.top()).multnorm3d(n, tn);
00667 #if 1
00668
00669 fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00670 #else
00671
00672 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00673 #endif
00674 }
00675 fprintf(outfile, "'/>\n");
00676
00677 fprintf(outfile, " </IndexedTriangleSet>\n");
00678 fprintf(outfile, "</Shape>\n");
00679 }
00680
00681
00682
00683
00684
00685 void X3DDisplayDevice::tristrip(int numverts, const float * cnv,
00686 int numstrips, const int *vertsperstrip,
00687 const int *facets) {
00688
00689 int i, strip, v = 0;
00690 fprintf(outfile, "<Shape>\n");
00691 fprintf(outfile, " ");
00692 write_cindexmaterial(colorIndex, materialIndex);
00693
00694
00695
00696 fprintf(outfile, " <IndexedTriangleStripSet solid='false' index='");
00697 for (strip=0; strip < numstrips; strip++) {
00698 for (i=0; i<vertsperstrip[strip]; i++) {
00699 fprintf(outfile, "%d ", facets[v]);
00700 v++;
00701 }
00702 fprintf(outfile, "-1 ");
00703 }
00704 fprintf(outfile, "'>\n");
00705
00706
00707 fprintf(outfile, " <Coordinate point='");
00708 for (i=0; i<numverts; i++) {
00709 const float *v = cnv + i*10 + 7;
00710 float tv[3];
00711 (transMat.top()).multpoint3d(v, tv);
00712 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
00713 }
00714 fprintf(outfile, "'/>\n");
00715
00716
00717 fprintf(outfile, " <Color color='");
00718 for (i=0; i<numverts; i++) {
00719 const float *c = cnv + i*10;
00720 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
00721 }
00722 fprintf(outfile, "'/>\n");
00723
00724
00725 fprintf(outfile, " <Normal vector='");
00726 for (i=0; i<numverts; i++) {
00727 const float *n = cnv + i*10 + 4;
00728 float tn[3];
00729 (transMat.top()).multnorm3d(n, tn);
00730 #if 1
00731
00732 fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00733 #else
00734
00735 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00736 #endif
00737 }
00738 fprintf(outfile, "'/>\n");
00739
00740 fprintf(outfile, " </IndexedTriangleStripSet>\n");
00741 fprintf(outfile, "</Shape>\n");
00742 }
00743
00744
00745 void X3DDisplayDevice::multmatrix(const Matrix4 &mat) {
00746 }
00747
00748
00749 void X3DDisplayDevice::load(const Matrix4 &mat) {
00750 }
00751
00752
00753 void X3DDisplayDevice::comment(const char *s) {
00754 fprintf (outfile, "<!-- %s -->\n", s);
00755 }
00756
00758
00759
00760 void X3DDisplayDevice::write_header(void) {
00761 fprintf(outfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00762 fprintf(outfile, "<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\"\n");
00763 fprintf(outfile, " \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n");
00764 fprintf(outfile, "\n");
00765
00766
00767
00768
00769
00770
00771 if (projection() == PERSPECTIVE) {
00772
00773 fprintf(outfile, "<X3D version='3.1' profile='Interchange'>\n");
00774 } else {
00775
00776 fprintf(outfile, "<X3D version='3.2' profile='Interchange'>\n");
00777 }
00778
00779 fprintf(outfile, "<head>\n");
00780 fprintf(outfile, " <meta name='description' content='VMD Molecular Graphics'/>\n");
00781 fprintf(outfile, "</head>\n");
00782 fprintf(outfile, "<Scene>\n");
00783 fprintf(outfile, "<!-- Created with VMD: -->\n");
00784 fprintf(outfile, "<!-- http://www.ks.uiuc.edu/Research/vmd/ -->\n");
00785
00786
00787 if (projection() == PERSPECTIVE) {
00788 float vfov = float(2.0*atan2((double) 0.5*vSize, (double) eyePos[2]-zDist));
00789 if (vfov > VMD_PI)
00790 vfov=float(VMD_PI);
00791
00792 fprintf(outfile, "<Viewpoint description=\"VMD Perspective View\" fieldOfView=\"%g\" orientation=\"0 0 -1 0\" position=\"%g %g %g\" centerOfRotation=\"0 0 0\" />\n",
00793 vfov, eyePos[0], eyePos[1], eyePos[2]);
00794 } else {
00795 fprintf(outfile, "<OrthoViewpoint description=\"VMD Orthographic View\" fieldOfView=\"%g %g %g %g\" orientation=\"0 0 -1 0\" position=\"%g %g %g\" centerOfRotation=\"0 0 0\" />\n",
00796 -Aspect*vSize/4, -vSize/4, Aspect*vSize/4, vSize/4,
00797 eyePos[0], eyePos[1], eyePos[2]);
00798 }
00799
00800 if (backgroundmode == 1) {
00801
00802 fprintf(outfile, "<Background skyColor='%g %g %g, %g %g %g, %g %g %g' ",
00803 backgradienttopcolor[0],
00804 backgradienttopcolor[1],
00805 backgradienttopcolor[2],
00806 (backgradienttopcolor[0]+backgradientbotcolor[0])/2.0f,
00807 (backgradientbotcolor[1]+backgradienttopcolor[1])/2.0f,
00808 (backgradienttopcolor[2]+backgradientbotcolor[2])/2.0f,
00809 backgradientbotcolor[0],
00810 backgradientbotcolor[1],
00811 backgradientbotcolor[2]);
00812 fprintf(outfile, "skyAngle='1.5, 3.0' />");
00813 } else {
00814
00815 fprintf(outfile, "<Background skyColor='%g %g %g'/>",
00816 backColor[0], backColor[1], backColor[2]);
00817 }
00818 fprintf(outfile, "\n");
00819 }
00820
00821 void X3DDisplayDevice::write_trailer(void) {
00822 fprintf(outfile, "</Scene>\n");
00823 fprintf(outfile, "</X3D>\n");
00824 }
00825
00826 void X3DDisplayDevice::write_cindexmaterial(int cindex, int material) {
00827 write_colormaterial((float *) &matData[cindex], material);
00828 }
00829
00830 void X3DDisplayDevice::write_colormaterial(float *rgb, int) {
00831
00832 fprintf(outfile, "<Appearance><Material ");
00833 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00834 fprintf(outfile, "diffuseColor='%g %g %g' ",
00835 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00836 fprintf(outfile, "shininess='%g' ", mat_shininess);
00837 fprintf(outfile, "specularColor='%g %g %g' ",
00838 mat_specular, mat_specular, mat_specular);
00839 fprintf(outfile, "transparency='%g' ", 1.0 - mat_opacity);
00840 fprintf(outfile, "/></Appearance>\n");
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00858
00859
00860 X3DOMDisplayDevice::X3DOMDisplayDevice(void) :
00861 X3DDisplayDevice("X3DOM", "X3D (XML) limited subset for X3DOM v1.1", "vmdscene.x3d", "true") {
00862 }
00863
00864
00865
00866
00867 void X3DOMDisplayDevice::line_array(int num, float thickness, float *points) {
00868 float *v = points;
00869 float txyz[3];
00870 int i;
00871
00872 fprintf(outfile, "<Shape>\n");
00873 fprintf(outfile, " ");
00874
00875
00876 fprintf(outfile, "<Appearance><Material ");
00877 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00878 fprintf(outfile, "diffuseColor='0 0 0' ");
00879
00880 const float *rgb = matData[colorIndex];
00881 fprintf(outfile, "emissiveColor='%g %g %g' ",
00882 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00883 fprintf(outfile, "/>");
00884
00885 #if 0
00886
00887
00888 if (thickness < 0.99f || thickness > 1.01f) {
00889 fprintf(outfile, " <LineProperties linewidthScaleFactor=\"%g\" "
00890 "containerField=\"lineProperties\"/>\n",
00891 (double) thickness);
00892 }
00893 #endif
00894 fprintf(outfile, "</Appearance>\n");
00895
00896
00897 fprintf(outfile, " <IndexedLineSet coordIndex='");
00898 for (i=0; i<num; i++) {
00899 fprintf(outfile, "%d %d -1 ", i*2, i*2+1);
00900 }
00901 fprintf(outfile, "'>\n");
00902
00903 fprintf(outfile, " <Coordinate point='");
00904
00905 for (i=0; i<(num*2); i++) {
00906
00907 (transMat.top()).multpoint3d(v, txyz);
00908 fprintf(outfile, "%c%g %g %g",
00909 (i==0) ? ' ' : ',',
00910 txyz[0], txyz[1], txyz[2]);
00911 v += 3;
00912 }
00913 fprintf(outfile, "'/>\n");
00914
00915 fprintf(outfile, " </IndexedLineSet>\n");
00916 fprintf(outfile, "</Shape>\n");
00917 }
00918
00919
00920
00921
00922 void X3DOMDisplayDevice::polyline_array(int num, float thickness, float *points) {
00923 float *v = points;
00924 float txyz[3];
00925 int i;
00926
00927 fprintf(outfile, "<Shape>\n");
00928 fprintf(outfile, " ");
00929
00930
00931 fprintf(outfile, "<Appearance><Material ");
00932 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
00933 fprintf(outfile, "diffuseColor='0 0 0' ");
00934
00935 const float *rgb = matData[colorIndex];
00936 fprintf(outfile, "emissiveColor='%g %g %g' ",
00937 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
00938 fprintf(outfile, "/>");
00939
00940 #if 0
00941
00942
00943 if (thickness < 0.99f || thickness > 1.01f) {
00944 fprintf(outfile, " <LineProperties linewidthScaleFactor=\"%g\" "
00945 "containerField=\"lineProperties\"/>\n",
00946 (double) thickness);
00947 }
00948 #endif
00949 fprintf(outfile, "</Appearance>\n");
00950
00951
00952
00953
00954 fprintf(outfile, " <IndexedLineSet coordIndex='");
00955 for (i=0; i<num; i++) {
00956 fprintf(outfile, "%d ", i);
00957 }
00958 fprintf(outfile, "'>\n");
00959
00960 fprintf(outfile, " <Coordinate point='");
00961 for (i=0; i<num; i++) {
00962
00963 (transMat.top()).multpoint3d(v, txyz);
00964 fprintf(outfile, "%c%g %g %g",
00965 (i==0) ? ' ' : ',',
00966 txyz[0], txyz[1], txyz[2]);
00967 v += 3;
00968 }
00969 fprintf(outfile, "'/>\n");
00970
00971 fprintf(outfile, " </IndexedLineSet>\n");
00972 fprintf(outfile, "</Shape>\n");
00973 }
00974
00975
00976
00977
00978 void X3DOMDisplayDevice::text(float *pos, float size, float thickness,
00979 const char *str) {
00980 float textpos[3];
00981 float textsize;
00982 hersheyhandle hh;
00983
00984
00985 (transMat.top()).multpoint3d(pos, textpos);
00986 textsize = size * 1.5f;
00987
00988 ResizeArray<int> idxs;
00989 ResizeArray<float> pnts;
00990 idxs.clear();
00991 pnts.clear();
00992
00993 int idx=0;
00994 while (*str != '\0') {
00995 float lm, rm, x, y;
00996 int draw;
00997 x=y=0.0f;
00998 draw=0;
00999
01000 hersheyDrawInitLetter(&hh, *str, &lm, &rm);
01001 textpos[0] -= lm * textsize;
01002
01003 while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
01004 float pt[3];
01005
01006 if (draw) {
01007
01008 idxs.append(idx);
01009
01010 pt[0] = textpos[0] + textsize * x;
01011 pt[1] = textpos[1] + textsize * y;
01012 pt[2] = textpos[2];
01013
01014 pnts.append(pt[0]);
01015 pnts.append(pt[1]);
01016 pnts.append(pt[2]);
01017
01018 idx++;
01019 } else {
01020 idxs.append(-1);
01021 }
01022 }
01023 idxs.append(-1);
01024 textpos[0] += rm * textsize;
01025 str++;
01026 }
01027
01028 fprintf(outfile, "<Shape>\n");
01029 fprintf(outfile, " ");
01030
01031
01032
01033
01034 fprintf(outfile, "<Appearance><Material ");
01035 fprintf(outfile, "ambientIntensity='%g' ", mat_ambient);
01036 fprintf(outfile, "diffuseColor='0 0 0' ");
01037
01038 const float *rgb = matData[colorIndex];
01039 fprintf(outfile, "emissiveColor='%g %g %g' ",
01040 mat_diffuse * rgb[0], mat_diffuse * rgb[1], mat_diffuse * rgb[2]);
01041 fprintf(outfile, "/>");
01042
01043 #if 0
01044
01045
01046 if (thickness < 0.99f || thickness > 1.01f) {
01047 fprintf(outfile, " <LineProperties linewidthScaleFactor=\"%g\" "
01048 "containerField=\"lineProperties\"/>\n",
01049 (double) thickness);
01050 }
01051 #endif
01052 fprintf(outfile, "</Appearance>\n");
01053
01054
01055
01056
01057 fprintf(outfile, " <IndexedLineSet coordIndex='");
01058 int i, cnt;
01059 cnt = idxs.num();
01060 for (i=0; i<cnt; i++) {
01061 fprintf(outfile, "%d ", idxs[i]);
01062 }
01063 fprintf(outfile, "'>\n");
01064
01065 fprintf(outfile, " <Coordinate point='");
01066 cnt = pnts.num();
01067 for (i=0; i<cnt; i+=3) {
01068 fprintf(outfile, "%c%g %g %g",
01069 (i==0) ? ' ' : ',',
01070 pnts[i], pnts[i+1], pnts[i+2]);
01071 }
01072 fprintf(outfile, "'/>\n");
01073 fprintf(outfile, " </IndexedLineSet>\n");
01074 fprintf(outfile, "</Shape>\n");
01075 }
01076
01077
01078
01079
01080 void X3DOMDisplayDevice::tristrip(int numverts, const float * cnv,
01081 int numstrips, const int *vertsperstrip,
01082 const int *facets) {
01083
01084
01085
01086 int i, strip, v = 0;
01087 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
01088
01089 fprintf(outfile, "<Shape>\n");
01090 fprintf(outfile, " ");
01091 write_cindexmaterial(colorIndex, materialIndex);
01092
01093
01094
01095 fprintf(outfile, " <IndexedTriangleSet solid='false' index='");
01096 for (strip=0; strip < numstrips; strip++) {
01097 for (i=0; i<(vertsperstrip[strip] - 2); i++) {
01098
01099 fprintf(outfile, "%d %d %d ",
01100 facets[v + (stripaddr[i & 0x01][0])],
01101 facets[v + (stripaddr[i & 0x01][1])],
01102 facets[v + (stripaddr[i & 0x01][2])]);
01103 v++;
01104 }
01105 v+=2;
01106 }
01107 fprintf(outfile, "'>\n");
01108
01109
01110 fprintf(outfile, " <Coordinate point='");
01111 for (i=0; i<numverts; i++) {
01112 const float *v = cnv + i*10 + 7;
01113 float tv[3];
01114 (transMat.top()).multpoint3d(v, tv);
01115 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
01116 }
01117 fprintf(outfile, "'/>\n");
01118
01119
01120 fprintf(outfile, " <Color color='");
01121 for (i=0; i<numverts; i++) {
01122 const float *c = cnv + i*10;
01123 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
01124 }
01125 fprintf(outfile, "'/>\n");
01126
01127
01128 fprintf(outfile, " <Normal vector='");
01129 for (i=0; i<numverts; i++) {
01130 const float *n = cnv + i*10 + 4;
01131 float tn[3];
01132 (transMat.top()).multnorm3d(n, tn);
01133 #if 1
01134
01135 fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
01136 #else
01137
01138 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
01139 #endif
01140 }
01141 fprintf(outfile, "'/>\n");
01142
01143 fprintf(outfile, " </IndexedTriangleSet>\n");
01144 fprintf(outfile, "</Shape>\n");
01145 }
01146
01148
01149
01150