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